Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deadlock between DocumentUndoManager and Building #2429

Open
laeubi opened this issue Oct 20, 2024 · 4 comments
Open

Deadlock between DocumentUndoManager and Building #2429

laeubi opened this issue Oct 20, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@laeubi
Copy link
Contributor

laeubi commented Oct 20, 2024

Today I encountered a deadlock DocumentUndoManager tries to SynchronizableDocument.getModificationStamp

"main" #1 [7493] prio=6 os_prio=0 cpu=454823,61ms elapsed=2588,33s tid=0x00007faedc032b10 nid=7493 waiting for monitor entry  [0x00007faee2dfd000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at org.eclipse.core.internal.filebuffers.SynchronizableDocument.getModificationStamp(SynchronizableDocument.java:151)
	- waiting to lock <0x00000000ab1220d8> (a java.lang.Object)
	at org.eclipse.text.undo.DocumentUndoManager$UndoableTextChange.canUndo(DocumentUndoManager.java:163)
	at org.eclipse.core.commands.operations.DefaultOperationHistory.canUndo(DefaultOperationHistory.java:267)
	at org.eclipse.text.undo.DocumentUndoManager.undoable(DocumentUndoManager.java:836)
	at org.eclipse.jface.text.TextViewerUndoManager.undoable(TextViewerUndoManager.java:348)
	at org.eclipse.jface.text.TextViewer.canDoOperation(TextViewer.java:3892)
	at org.eclipse.jface.text.source.SourceViewer.canDoOperation(SourceViewer.java:836)
	at org.eclipse.compare.internal.MergeSourceViewer$TextOperationAction.isEnabled(MergeSourceViewer.java:139)
	at org.eclipse.compare.internal.MergeSourceViewer$TextOperationAction.update(MergeSourceViewer.java:144)
	at org.eclipse.compare.internal.MergeSourceViewer.updateContentDependantActions(MergeSourceViewer.java:818)
	at org.eclipse.compare.internal.MergeSourceViewer$$Lambda/0x00000001014aa3d0.run(Unknown Source)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:132)
	- locked <0x00000000ded89aa0> (a org.eclipse.swt.widgets.RunnableLock)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:5040)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4520)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1151)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1042)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
	at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:639)
	at org.eclipse.ui.internal.Workbench$$Lambda/0x00000001003c4708.run(Unknown Source)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:546)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:173)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:208)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:143)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:109)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:439)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:271)
	at java.lang.invoke.DirectMethodHandle$Holder.invokeStatic([email protected]/DirectMethodHandle$Holder)
	at java.lang.invoke.LambdaForm$MH/0x00000001000c6800.invoke([email protected]/LambdaForm$MH)
	at java.lang.invoke.LambdaForm$MH/0x00000001000c6c00.invokeExact_MT([email protected]/LambdaForm$MH)
	at jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl([email protected]/DirectMethodHandleAccessor.java:155)
	at jdk.internal.reflect.DirectMethodHandleAccessor.invoke([email protected]/DirectMethodHandleAccessor.java:103)
	at java.lang.reflect.Method.invoke([email protected]/Method.java:580)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:668)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:605)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1481)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1454)

while this is locked by Building thread:

"Worker-51: Building" #1206 [22699] prio=5 os_prio=0 cpu=444,47ms elapsed=619,37s tid=0x00007fad4c029750 nid=22699 waiting on condition  [0x00007fadd68ec000]
   java.lang.Thread.State: TIMED_WAITING (parking)
	at jdk.internal.misc.Unsafe.park([email protected]/Native Method)
	- parking to wait for  <0x00000000deda0d80> (a java.util.concurrent.Semaphore$NonfairSync)
	at java.util.concurrent.locks.LockSupport.parkNanos([email protected]/LockSupport.java:269)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire([email protected]/AbstractQueuedSynchronizer.java:756)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos([email protected]/AbstractQueuedSynchronizer.java:1126)
	at java.util.concurrent.Semaphore.tryAcquire([email protected]/Semaphore.java:415)
	at org.eclipse.ui.internal.PendingSyncExec.acquire(PendingSyncExec.java:39)
	at org.eclipse.ui.internal.PendingSyncExec.waitUntilExecuted(PendingSyncExec.java:88)
	at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:142)
	at org.eclipse.swt.widgets.Display.syncExec(Display.java:5960)
	at org.eclipse.compare.internal.Utilities.firePropertyChange(Utilities.java:179)
	at org.eclipse.compare.internal.Utilities.firePropertyChange(Utilities.java:166)
	at org.eclipse.compare.contentmergeviewer.ContentMergeViewer.fireDirtyState(ContentMergeViewer.java:1185)
	at org.eclipse.compare.contentmergeviewer.ContentMergeViewer.setLeftDirty(ContentMergeViewer.java:1201)
	at org.eclipse.compare.contentmergeviewer.TextMergeViewer.updateDirtyState(TextMergeViewer.java:3279)
	at org.eclipse.compare.contentmergeviewer.TextMergeViewer$ContributorInfo.elementDirtyStateChanged(TextMergeViewer.java:1058)
	at org.eclipse.ui.editors.text.TextFileDocumentProvider$FileBufferListener.dirtyStateChanged(TextFileDocumentProvider.java:305)
	at org.eclipse.core.internal.filebuffers.TextFileBufferManager$3.run(TextFileBufferManager.java:671)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47)
	at org.eclipse.core.internal.filebuffers.TextFileBufferManager.fireDirtyStateChanged(TextFileBufferManager.java:668)
	at org.eclipse.core.internal.filebuffers.ResourceTextFileBuffer$DocumentListener.documentChanged(ResourceTextFileBuffer.java:76)
	at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged2(AbstractDocument.java:739)
	at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged(AbstractDocument.java:708)
	at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged(AbstractDocument.java:692)
	at org.eclipse.jface.text.AbstractDocument.fireDocumentChanged(AbstractDocument.java:766)
	at org.eclipse.jface.text.AbstractDocument.replace(AbstractDocument.java:1091)
	at org.eclipse.core.internal.filebuffers.SynchronizableDocument.replace(SynchronizableDocument.java:176)
	- locked <0x00000000ab1220d8> (a java.lang.Object)
	at org.eclipse.jface.text.AbstractDocument.replace(AbstractDocument.java:1109)
	at org.eclipse.core.internal.filebuffers.SynchronizableDocument.replace(SynchronizableDocument.java:164)
	- locked <0x00000000ab1220d8> (a java.lang.Object)
	at org.eclipse.text.edits.InsertEdit.performDocumentUpdating(InsertEdit.java:78)
	at org.eclipse.text.edits.TextEdit.traverseDocumentUpdating(TextEdit.java:920)
	at org.eclipse.text.edits.TextEdit.traverseDocumentUpdating(TextEdit.java:913)
	at org.eclipse.text.edits.TextEditProcessor.executeDo(TextEditProcessor.java:196)
	at org.eclipse.text.edits.TextEdit.dispatchPerformEdits(TextEdit.java:742)
	at org.eclipse.text.edits.TextEditProcessor.performEdits(TextEditProcessor.java:158)
	at org.eclipse.text.edits.TextEdit.apply(TextEdit.java:714)
	at org.eclipse.text.edits.TextEdit.apply(TextEdit.java:738)
	at org.eclipse.pde.internal.ui.util.PDEModelUtility.generateModelEdits(PDEModelUtility.java:354)
	at org.eclipse.pde.internal.ui.util.PDEModelUtility.modifyModel(PDEModelUtility.java:291)
	at org.eclipse.pde.ds.internal.annotations.DSAnnotationCompilationParticipant.updateProject(DSAnnotationCompilationParticipant.java:447)
	at org.eclipse.pde.ds.internal.annotations.DSAnnotationCompilationParticipant.buildFinished(DSAnnotationCompilationParticipant.java:401)
	at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:262)
	at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:1077)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:296)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:352)
	at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:441)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:444)
	at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:555)
	at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:503)
	at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:585)
	at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:207)
	at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:300)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)

This results in build thread blocked forever and UI freeze. This seems to happen because I have a compare view open, while PDE is modifying the manifest.

@laeubi laeubi added the bug Something isn't working label Oct 20, 2024
@laeubi laeubi changed the title Deock between DocumentUndoManager and Building Deadlock between DocumentUndoManager and Building Oct 20, 2024
@laeubi
Copy link
Contributor Author

laeubi commented Oct 20, 2024

I also encountered similar deadlocks recently but was not able to capture a stack, also in this case it seems that the CompareView was involved. I'm not sure if that is to blame or if the SynchronizableDocument is acquiring locks in wrong order or maybe the document should not be called from different threads (but why the have it synchronized?)

@iloveeclipse
Copy link
Member

This part of the stack is guilty, classic mistake: using syncExec() from a job.
That should be done via asyncExec(), because you never know which locks / rules job acquired, you can't try ro acquire also UI lock:

	at org.eclipse.swt.widgets.Display.syncExec(Display.java:5960)
	at org.eclipse.compare.internal.Utilities.firePropertyChange(Utilities.java:179)
	at org.eclipse.compare.internal.Utilities.firePropertyChange(Utilities.java:166)
	at org.eclipse.compare.contentmergeviewer.ContentMergeViewer.fireDirtyState(ContentMergeViewer.java:1185)
	at org.eclipse.compare.contentmergeviewer.ContentMergeViewer.setLeftDirty(ContentMergeViewer.java:1201)
	at org.eclipse.compare.contentmergeviewer.TextMergeViewer.updateDirtyState(TextMergeViewer.java:3279)
	at org.eclipse.compare.contentmergeviewer.TextMergeViewer$ContributorInfo.elementDirtyStateChanged(TextMergeViewer.java:1058)
	at org.eclipse.ui.editors.text.TextFileDocumentProvider$FileBufferListener.dirtyStateChanged(TextFileDocumentProvider.java:305)

@merks
Copy link
Contributor

merks commented Oct 20, 2024

The last change around this logic used:

		Display.getDefault().execute(runnable);

but that was reverted back to the current state and that state did an asyncExec:

public void execute(Runnable runnable) {
	Objects.requireNonNull(runnable);
	if (isDisposed()) {
		throw new RejectedExecutionException(new SWTException (SWT.ERROR_WIDGET_DISPOSED, null));
	}
	if (thread == Thread.currentThread()) {
		syncExec(runnable);
	} else {
		asyncExec(runnable);
	}
}

And that change too related to deadlock I guess:

eclipse-platform/eclipse.platform@8f7f25e

@laeubi
Copy link
Contributor Author

laeubi commented Oct 20, 2024

This was seen with

Version: 2024-12 M1 (4.34.0 M1)
Build id: 20241003-0706

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants