eclipse-lsp4e / eclipse-lsp4e/lsp4e
LSPDiagnosticsToMarkers causes invalid thread access exception on non-resource
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 85
- Forks
- 69
- Avg merge
- 8h 33m
- Merged PRs (30d)
- 6
Description
I'm in the process of rewriting our LSP4e-based eclipse integration and have run into an odd SWT threading violation from diagnostics publishing.
SWT.error(int, Throwable, String) line: 4920
SWT.error(int, Throwable) line: 4833
SWT.error(int) line: 4804
CTabFolder(Widget).error(int) line: 811
CTabFolder(Widget).checkWidget() line: 598
ContributedPartRenderer$1(Widget).checkParent(Widget) line: 536
ContributedPartRenderer$1(Widget).<init>(Widget, int) line: 142
ContributedPartRenderer$1(Control).<init>(Composite, int) line: 124
ContributedPartRenderer$1(Scrollable).<init>(Composite, int) line: 76
ContributedPartRenderer$1(Composite).<init>(Composite, int) line: 96
ContributedPartRenderer$1.<init>(ContributedPartRenderer, Composite, int, MPart) line: 86
ContributedPartRenderer.createWidget(MUIElement, Object) line: 86
PartRenderingEngine.createWidget(MUIElement, Object) line: 995
PartRenderingEngine.safeCreateGui(MUIElement, Object, IEclipseContext) line: 659
PartRenderingEngine.safeCreateGui(MUIElement) line: 763
PartRenderingEngine$2.run() line: 728
SafeRunner.run(ISafeRunnable) line: 45
PartRenderingEngine.createGui(MUIElement) line: 712
PartServiceImpl.createElement(MUIElement) line: 1313
PartServiceImpl.showPart(MPart, EPartService$PartState) line: 1274
EditorReference(WorkbenchPartReference).getPart(boolean) line: 397
EditorReference.getEditor(boolean) line: 283
LSPDiagnosticsToMarkers.lambda$0(IEditorReference) line: 95
0x00000008008cc6d8.apply(Object) line: not available
ReferencePipeline$3$1.accept(P_OUT) line: 197
HashMap$KeySpliterator<K,V>.forEachRemaining(Consumer<? super K>) line: 1707
ReferencePipeline$3(AbstractPipeline<E_IN,E_OUT,S>).copyInto(Sink<P_IN>, Spliterator<P_IN>) line: 509
ReferencePipeline$3(AbstractPipeline<E_IN,E_OUT,S>).wrapAndCopyInto(S, Spliterator<P_IN>) line: 499
ForEachOps$ForEachOp$OfRef<T>(ForEachOps$ForEachOp<T>).evaluateSequential(PipelineHelper<T>, Spliterator<S>) line: 150
ForEachOps$ForEachOp$OfRef<T>.evaluateSequential(PipelineHelper, Spliterator) line: 173
ReferencePipeline$3(AbstractPipeline<E_IN,E_OUT,S>).evaluate(TerminalOp<E_OUT,R>) line: 234
ReferencePipeline$3(ReferencePipeline<P_IN,P_OUT>).forEach(Consumer<? super P_OUT>) line: 596
LSPDiagnosticsToMarkers.accept(PublishDiagnosticsParams) line: 101
LSPDiagnosticsToMarkers.accept(Object) line: 1
CocoLanguageClient(LanguageClientImpl).publishDiagnostics(PublishDiagnosticsParams) line: 101
GeneratedMethodAccessor32.invoke(Object, Object[]) line: not available
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43
Method.invoke(Object, Object...) line: 568
GenericEndpoint.lambda$recursiveFindRpcMethods$0(AnnotationUtil$MethodInfo, Object, Object) line: 65
0x0000000800844a38.apply(Object) line: not available
GenericEndpoint.notify(String, Object) line: 160
RemoteEndpoint.handleNotification(NotificationMessage) line: 231
RemoteEndpoint.consume(Message) line: 198
LanguageServerWrapper.lambda$3(MessageConsumer, URI, Message) line: 313
0x0000000800813af0.consume(Message) line: not available
StreamMessageProducer.handleMessage(InputStream, StreamMessageProducer$Headers) line: 185
StreamMessageProducer.listen(MessageConsumer) line: 97
ConcurrentMessageProcessor.run() line: 114
Executors$RunnableAdapter<T>.call() line: 539
FutureTask<V>.run() line: 264
ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1136
ThreadPoolExecutor$Worker.run() line: 635
Thread.run() line: 840
I get the problem when relaunching Eclipse on a workspace in a persisted state, with an editor for a file outside of a project.
The issue seems to be in the second branch of LSPDiagnosticsToMarkers.accept. I'm using an older version of LSP4e (0.18.11), but this code seems to be substantially unchanged other than a bit of non-semantic tidying up. The code has two branches, depending on whether the file targeted by a diagnostic is an IResource or not. It's the second branch that is causing the problem.
The scenario seems to be:
- A file that the language server recognises, but which isn't part of a workspace project, is open as an editor in the workbench.
- The file has a problem that the LS generates a marker for.
- The workbench is restarted with the open editor as part of the persisted state.
There might be something racy about the issue as well - I know the normal branch will temporarily open editors if they're not already open to install markers. The editor in this case is clearly open in the workbench, but it might be that the diagnostics publishing sometimes runs before the editor has been materialised by the workbench restore.
Happy to contribute a fix but I'm not totally sure what the right fix might be. I have a workaround to override the LanguageClientImpl and make sure the diagnostics consumer runs via Display.getDefault().asyncExec(), but I'm not sure how robust that is.
Any Eclipse gurus able to help with the diagnosis?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in LSPDiagnosticsToMarkers.accept, especially the second branch for diagnostics targeting a non-resource file, and reproduce the persisted-workspace scenario with an editor outside a project. Compare the timing of diagnostics publication with workbench editor restoration and inspect the existing Display.getDefault().asyncExec() workaround. Done means diagnostics no longer trigger invalid SWT thread or widget-access exceptions in that scenario.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- desktop, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100