eclipse.platform.swt icon indicating copy to clipboard operation
eclipse.platform.swt copied to clipboard

Gtk:ERROR assertion failed -> eclipse closes

Open laeubi opened this issue 2 years ago • 26 comments

Today I encountered a crash of Eclipse (2023-03) under linux where the last entry in the log was:

Gtk:ERROR:../../../../gtk/gtktreestore.c:596:gtk_tree_store_get_path: assertion failed: (G_NODE (iter->user_data)->parent != NULL)

I didn't see any crash or similar, the application just exited suddenly, after a restart I can continue working, but maybe the message helps someone more familiar with GTK to guess what might be the cause, from the message itself it looks like there is a null pointer accessed.

laeubi avatar May 10 '23 15:05 laeubi

Which GTK version / OS? Wayland or X11?

where the last entry in the log was

Can you attach complete log / error you have?

Reminds me on https://bugs.eclipse.org/bugs/show_bug.cgi?id=182598, which should have been fixed long time ago.

iloveeclipse avatar May 10 '23 15:05 iloveeclipse

libgtk-3-0:amd64 3.24.5-1 Debian 4.19.194-3 X11

laeubi avatar May 10 '23 16:05 laeubi

Is there a hs_err_pid*.log file somewhere near eclipse, or in your HOME?

SyntevoAlex avatar May 10 '23 21:05 SyntevoAlex

There are some files in the home folder, is there anything particular interesting I should look for?

EDIT: at laest from the file time stamps they seem to not relate here as they are older than the crash...

laeubi avatar May 11 '23 03:05 laeubi

Look for such file inside Eclipse install folder too. The one from this crash should contain the native backtrace for the crash.

akurtakov avatar May 11 '23 04:05 akurtakov

I scanned my whole homefolder recursively and all eclipse install locations but no luck :-\

Also in the past the log contained a short crashlog but not in this case.

laeubi avatar May 11 '23 05:05 laeubi

The crash log will be in the working directory, if JVM will be able to write one. Crash dump (for gdb) should be enabled in the system, otherwise it will be not created. Ideally you would start Eclipse from the shell / console or redirect all the output to a file, so at least full GTK error log will be available. Also ideally you could remember which action caused the crash and try to reproduce it.

iloveeclipse avatar May 11 '23 05:05 iloveeclipse

As I see older crashlogs, at least it seems it was sometimes possible to write logs, but I'll try to look for that data if it occurs next time, I wondering if the place is known to cause errors in the past, maybe the c-code can have a null pointer check and maybe print some additional (eclipse/swt related) info that is helpful in debugging?

laeubi avatar May 11 '23 05:05 laeubi

How can I enable the crash dumps? I currently have encountered the problem again but still no crash files, the RCP application simply exit with

Gtk:ERROR:../../../../gtk/gtktreestore.c:596:gtk_tree_store_get_path: assertion failed: (G_NODE (iter->user_data)->parent != NULL)

laeubi avatar Sep 08 '23 16:09 laeubi

@laeubi if you look for hs_err_pid*.log they are generated in start directory. If you look for core files this differs between distributions.

akurtakov avatar Sep 08 '23 17:09 akurtakov

As said I can't find any hs_err_pid*.log files also I do not see the usual crash report, the JVM simply exits as if one has called System.exit(...) :-\

laeubi avatar Sep 08 '23 17:09 laeubi

Ideally you would start Eclipse from the shell / console or redirect all the output to a file, so at least full GTK error log will be available. Also ideally you could remember which action caused the crash and try to reproduce it.

If GTK native code crashes JVM process, there will be no JVM crash dump but should be some output on the console. Also check recent kernel errors via dmesg, usually you will see there which process crashed and with which error.

iloveeclipse avatar Sep 08 '23 17:09 iloveeclipse

but should be some output on the console

This is the last output from the console (I'm running the application from withing eclipse)

Gtk:ERROR:../../../../gtk/gtktreestore.c:596:gtk_tree_store_get_path: assertion failed: (G_NODE (iter->user_data)->parent != NULL)

check recent kernel errors via dmesg, usually you will see there which process crashed and with which error.

Anything specific to look / grep for? I don't see anything suspicious here, at least nothing with GTK or eclipse or java in the name...

laeubi avatar Sep 08 '23 18:09 laeubi

I have now enabled G_MESSAGES_DEBUG=all that are the messages I see right before the application closes:

<application name>: GdkPixbuf-DEBUG: 05:39:12.063: gdk_pixbuf_from_pixdata() called on:
<application name>: GdkPixbuf-DEBUG: 05:39:12.063: 	Encoding raw
<application name>: GdkPixbuf-DEBUG: 05:39:12.063: 	Dimensions: 14 x 14
<application name>: GdkPixbuf-DEBUG: 05:39:12.063: 	Rowstride: 56, Length: 808
<application name>: GdkPixbuf-DEBUG: 05:39:12.063: 	Copy pixels == false
<application name>: GdkPixbuf-DEBUG: 05:39:12.620: gdk_pixbuf_from_pixdata() called on:
<application name>: GdkPixbuf-DEBUG: 05:39:12.620: 	Encoding raw
<application name>: GdkPixbuf-DEBUG: 05:39:12.620: 	Dimensions: 14 x 14
<application name>: GdkPixbuf-DEBUG: 05:39:12.620: 	Rowstride: 56, Length: 808
<application name>: GdkPixbuf-DEBUG: 05:39:12.620: 	Copy pixels == false
<application name>: GdkPixbuf-DEBUG: 05:39:14.581: gdk_pixbuf_from_pixdata() called on:
<application name>: GdkPixbuf-DEBUG: 05:39:14.581: 	Encoding raw
<application name>: GdkPixbuf-DEBUG: 05:39:14.581: 	Dimensions: 14 x 14
<application name>: GdkPixbuf-DEBUG: 05:39:14.581: 	Rowstride: 56, Length: 808
<application name>: GdkPixbuf-DEBUG: 05:39:14.581: 	Copy pixels == false
**
Gtk:ERROR:../../../../gtk/gtktreestore.c:596:gtk_tree_store_get_path: assertion failed: (G_NODE (iter->user_data)->parent != NULL)

this all seem to happen while updating a tree control so maybe some kind of synchronization issue

laeubi avatar Sep 10 '23 03:09 laeubi

I have now narrowed it down to the following lets say we have a (virtual) tree, with an item selected, it seems I can trigger this by inserting an item in the tree that is inserted before the selected one where the selected is a child in the hierarchy.

laeubi avatar Sep 10 '23 03:09 laeubi

I tried to gather a stacktrace where the user code currently operates before the crash this is the closes user call I can track before application exit:

java.lang.Exception: Stack trace
	at java.base/java.lang.Thread.dumpStack(Thread.java:1380)
	at <usercode>
	at org.eclipse.jface.viewers.TreeViewer.virtualLazyUpdateWidget(TreeViewer.java:998)
	at org.eclipse.jface.viewers.TreeViewer.lambda$1(TreeViewer.java:258)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5855)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1529)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1555)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1538)
	at org.eclipse.swt.widgets.Tree.checkData(Tree.java:373)
	at org.eclipse.swt.widgets.Tree.cellDataProc(Tree.java:305)
	at org.eclipse.swt.widgets.Display.cellDataProc(Display.java:994)
	at org.eclipse.swt.internal.gtk.GTK.gtk_tree_store_remove(Native Method)
	at org.eclipse.swt.widgets.Tree.destroyItem(Tree.java:1292)
	at org.eclipse.swt.widgets.TreeItem.destroyWidget(TreeItem.java:351)
	at org.eclipse.swt.widgets.Widget.release(Widget.java:1354)
	at org.eclipse.swt.widgets.Widget.dispose(Widget.java:543)
	at org.eclipse.swt.widgets.TreeItem.dispose(TreeItem.java:1088)
	at org.eclipse.jface.viewers.TreeViewer.lambda$4(TreeViewer.java:846)
	at org.eclipse.jface.viewers.TreeViewer.preservingSelection(TreeViewer.java:358)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1359)
	at org.eclipse.jface.viewers.TreeViewer.remove(TreeViewer.java:818)
	at <usercode>
	at org.eclipse.jface.viewers.TreeViewer.virtualLazyUpdateWidget(TreeViewer.java:998)
	at org.eclipse.jface.viewers.TreeViewer.lambda$1(TreeViewer.java:258)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5855)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1529)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1555)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1538)
	at org.eclipse.swt.widgets.Tree.checkData(Tree.java:373)
	at org.eclipse.swt.widgets.Tree.cellDataProc(Tree.java:305)
	at org.eclipse.swt.widgets.Display.cellDataProc(Display.java:994)
	at org.eclipse.swt.internal.gtk.GTK.gtk_tree_store_remove(Native Method)
	at org.eclipse.swt.widgets.Tree.destroyItem(Tree.java:1292)
	at org.eclipse.swt.widgets.TreeItem.destroyWidget(TreeItem.java:351)
	at org.eclipse.swt.widgets.Widget.release(Widget.java:1354)
	at org.eclipse.swt.widgets.Widget.dispose(Widget.java:543)
	at org.eclipse.swt.widgets.TreeItem.dispose(TreeItem.java:1088)
	at org.eclipse.jface.viewers.TreeViewer.lambda$4(TreeViewer.java:846)
	at org.eclipse.jface.viewers.TreeViewer.preservingSelection(TreeViewer.java:358)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1359)
	at org.eclipse.jface.viewers.TreeViewer.remove(TreeViewer.java:818)
	at <usercode>
	at org.eclipse.jface.viewers.TreeViewer.virtualLazyUpdateWidget(TreeViewer.java:998)
	at org.eclipse.jface.viewers.TreeViewer.lambda$1(TreeViewer.java:258)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5855)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1529)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1555)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1538)
	at org.eclipse.swt.widgets.Tree.checkData(Tree.java:373)
	at org.eclipse.swt.widgets.Tree.cellDataProc(Tree.java:305)
	at org.eclipse.swt.widgets.Display.cellDataProc(Display.java:994)
	at org.eclipse.swt.internal.gtk.GTK.gtk_tree_store_remove(Native Method)
	at org.eclipse.swt.widgets.Tree.destroyItem(Tree.java:1292)
	at org.eclipse.swt.widgets.TreeItem.destroyWidget(TreeItem.java:351)
	at org.eclipse.swt.widgets.Widget.release(Widget.java:1354)
	at org.eclipse.swt.widgets.Widget.dispose(Widget.java:543)
	at org.eclipse.swt.widgets.TreeItem.dispose(TreeItem.java:1088)
	at org.eclipse.jface.viewers.TreeViewer.lambda$4(TreeViewer.java:846)
	at org.eclipse.jface.viewers.TreeViewer.preservingSelection(TreeViewer.java:358)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1359)
	at org.eclipse.jface.viewers.TreeViewer.remove(TreeViewer.java:818)
	at <usercode>
	at org.eclipse.jface.viewers.TreeViewer.virtualLazyUpdateWidget(TreeViewer.java:998)
	at org.eclipse.jface.viewers.TreeViewer.lambda$1(TreeViewer.java:258)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5855)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1529)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1555)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1538)
	at org.eclipse.swt.widgets.Tree.checkData(Tree.java:373)
	at org.eclipse.swt.widgets.Tree.cellDataProc(Tree.java:305)
	at org.eclipse.swt.widgets.Display.cellDataProc(Display.java:994)
	at org.eclipse.swt.internal.gtk.GTK.gtk_tree_store_remove(Native Method)
	at org.eclipse.swt.widgets.Tree.destroyItem(Tree.java:1292)
	at org.eclipse.swt.widgets.TreeItem.destroyWidget(TreeItem.java:351)
	at org.eclipse.swt.widgets.Widget.release(Widget.java:1354)
	at org.eclipse.swt.widgets.Widget.dispose(Widget.java:543)
	at org.eclipse.swt.widgets.TreeItem.dispose(TreeItem.java:1088)
	at org.eclipse.jface.viewers.TreeViewer.lambda$4(TreeViewer.java:846)
	at org.eclipse.jface.viewers.TreeViewer.preservingSelection(TreeViewer.java:358)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1359)
	at org.eclipse.jface.viewers.TreeViewer.remove(TreeViewer.java:818)
	at <usercode>
	at org.eclipse.jface.viewers.TreeViewer.virtualLazyUpdateWidget(TreeViewer.java:998)
	at org.eclipse.jface.viewers.TreeViewer.lambda$1(TreeViewer.java:258)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5855)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1529)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1555)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1538)
	at org.eclipse.swt.widgets.Tree.checkData(Tree.java:373)
	at org.eclipse.swt.widgets.Tree.cellDataProc(Tree.java:305)
	at org.eclipse.swt.widgets.Display.cellDataProc(Display.java:994)
	at org.eclipse.swt.internal.gtk.GTK.gtk_tree_store_remove(Native Method)
	at org.eclipse.swt.widgets.Tree.destroyItem(Tree.java:1292)
	at org.eclipse.swt.widgets.TreeItem.destroyWidget(TreeItem.java:351)
	at org.eclipse.swt.widgets.Widget.release(Widget.java:1354)
	at org.eclipse.swt.widgets.Widget.dispose(Widget.java:543)
	at org.eclipse.swt.widgets.TreeItem.dispose(TreeItem.java:1088)
	at org.eclipse.swt.widgets.Tree.remove(Tree.java:2975)
	at org.eclipse.swt.widgets.Tree.setItemCount(Tree.java:3512)
	at org.eclipse.swt.widgets.TreeItem.setItemCount(TreeItem.java:1638)
	at org.eclipse.jface.viewers.TreeViewer.lambda$5(TreeViewer.java:955)
	at org.eclipse.jface.viewers.TreeViewer.preservingSelection(TreeViewer.java:358)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1359)
	at org.eclipse.jface.viewers.TreeViewer.setHasChildren(TreeViewer.java:941)
	at <usercode>
	at org.eclipse.jface.viewers.TreeViewer.virtualLazyUpdateWidget(TreeViewer.java:998)
	at org.eclipse.jface.viewers.TreeViewer.virtualRefreshExpandedItems(TreeViewer.java:706)
	at org.eclipse.jface.viewers.TreeViewer.virtualRefreshExpandedItems(TreeViewer.java:714)
	at org.eclipse.jface.viewers.TreeViewer.internalRefreshStruct(TreeViewer.java:681)
	at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh(AbstractTreeViewer.java:1947)
	at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh(AbstractTreeViewer.java:1904)
	at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh(AbstractTreeViewer.java:1890)
	at org.eclipse.jface.viewers.StructuredViewer.lambda$2(StructuredViewer.java:1459)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1398)
	at org.eclipse.jface.viewers.TreeViewer.preservingSelection(TreeViewer.java:365)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1359)
	at org.eclipse.jface.viewers.StructuredViewer.refresh(StructuredViewer.java:1459)
	at org.eclipse.jface.viewers.ColumnViewer.refresh(ColumnViewer.java:526)
	at <usercode>
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:132)
	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:1155)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1046)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155)
	at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:168)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:136)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:402)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:659)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:596)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1467)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1440)

laeubi avatar Sep 10 '23 04:09 laeubi

I was now able to trace this down to the following SWT call(s)

Thread [main] (Suspended (breakpoint at line 547 in TreeItem))	
	owns: RunnableLock  (id=140)	
	TreeItem.getExpanded() line: 547	
	TreeViewer.lambda$5(Object, boolean) line: 956	
	0x00000008012d9fc8.run() line: not available	
	TreeViewer.preservingSelection(Runnable, boolean) line: 358	
	TreeViewer(StructuredViewer).preservingSelection(Runnable) line: 1359	
	TreeViewer.setHasChildren(Object, boolean) line: 941	
	<UserCode>TreeContentProvider.updateElement(Object, int) line: 85	
	TreeViewer.virtualLazyUpdateWidget(Widget, int) line: 998	
	TreeViewer.lambda$1(Event) line: 258	
	0x00000008012b77a8.handleEvent(Event) line: not available	
	EventTable.sendEvent(Event) line: 89	
	Display.sendEvent(EventTable, Event) line: 5855	
	Tree(Widget).sendEvent(Event) line: 1529	
	Tree(Widget).sendEvent(int, Event, boolean) line: 1555	
	Tree(Widget).sendEvent(int, Event) line: 1538	
	Tree.checkData(TreeItem) line: 373	
	Tree.cellDataProc(long, long, long, long, long) line: 305	
	Display.cellDataProc(long, long, long, long, long) line: 994	
	GTK.gtk_tree_store_remove(long, long) line: not available [native method]	
	Tree.destroyItem(TreeItem) line: 1292	
	TreeItem.destroyWidget() line: 351	
	TreeItem(Widget).release(boolean) line: 1354	
	TreeItem(Widget).dispose() line: 543	
	TreeItem.dispose() line: 1088	
	TreeViewer.lambda$4(Object, int, List) line: 846	
	0x00000008013e4688.run() line: not available	
	TreeViewer.preservingSelection(Runnable, boolean) line: 358	
	TreeViewer(StructuredViewer).preservingSelection(Runnable) line: 1359	
	TreeViewer.remove(Object, int) line: 818	
	<UserCode>TreeContentProvider.updateElement(Object, int) line: 89	
	TreeViewer.virtualLazyUpdateWidget(Widget, int) line: 998	
	TreeViewer.lambda$1(Event) line: 258	
	0x00000008012b77a8.handleEvent(Event) line: not available	
	EventTable.sendEvent(Event) line: 89	
	Display.sendEvent(EventTable, Event) line: 5855	
	Tree(Widget).sendEvent(Event) line: 1529	
	Tree(Widget).sendEvent(int, Event, boolean) line: 1555	
	Tree(Widget).sendEvent(int, Event) line: 1538	
	Tree.checkData(TreeItem) line: 373	
	Tree.cellDataProc(long, long, long, long, long) line: 305	
	Display.cellDataProc(long, long, long, long, long) line: 994	
	GTK.gtk_tree_store_remove(long, long) line: not available [native method]	
	Tree.destroyItem(TreeItem) line: 1292	
	TreeItem.destroyWidget() line: 351	
	TreeItem(Widget).release(boolean) line: 1354	
	TreeItem(Widget).dispose() line: 543	
	TreeItem.dispose() line: 1088	
	TreeViewer.lambda$4(Object, int, List) line: 846	
	0x00000008013e4688.run() line: not available	
	TreeViewer.preservingSelection(Runnable, boolean) line: 358	
	TreeViewer(StructuredViewer).preservingSelection(Runnable) line: 1359	
	TreeViewer.remove(Object, int) line: 818	
	<UserCode>TreeContentProvider.updateElement(Object, int) line: 89	
	TreeViewer.virtualLazyUpdateWidget(Widget, int) line: 998	
	TreeViewer.lambda$1(Event) line: 258	
	0x00000008012b77a8.handleEvent(Event) line: not available	
	EventTable.sendEvent(Event) line: 89	
	Display.sendEvent(EventTable, Event) line: 5855	
	Tree(Widget).sendEvent(Event) line: 1529	
	Tree(Widget).sendEvent(int, Event, boolean) line: 1555	
	Tree(Widget).sendEvent(int, Event) line: 1538	
	Tree.checkData(TreeItem) line: 373	
	Tree.cellDataProc(long, long, long, long, long) line: 305	
	Display.cellDataProc(long, long, long, long, long) line: 994	
	GTK.gtk_tree_store_remove(long, long) line: not available [native method]	
	Tree.destroyItem(TreeItem) line: 1292	
	TreeItem.destroyWidget() line: 351	
	TreeItem(Widget).release(boolean) line: 1354	
	TreeItem(Widget).dispose() line: 543	
	TreeItem.dispose() line: 1088	
	TreeViewer.lambda$4(Object, int, List) line: 846	
	0x00000008013e4688.run() line: not available	
	TreeViewer.preservingSelection(Runnable, boolean) line: 358	
	TreeViewer(StructuredViewer).preservingSelection(Runnable) line: 1359	
	TreeViewer.remove(Object, int) line: 818	
	<UserCode>TreeContentProvider.updateElement(Object, int) line: 89	
	TreeViewer.virtualLazyUpdateWidget(Widget, int) line: 998	
	TreeViewer.lambda$1(Event) line: 258	
	0x00000008012b77a8.handleEvent(Event) line: not available	
	EventTable.sendEvent(Event) line: 89	
	Display.sendEvent(EventTable, Event) line: 5855	
	Tree(Widget).sendEvent(Event) line: 1529	
	Tree(Widget).sendEvent(int, Event, boolean) line: 1555	
	Tree(Widget).sendEvent(int, Event) line: 1538	
	Tree.checkData(TreeItem) line: 373	
	Tree.cellDataProc(long, long, long, long, long) line: 305	
	Display.cellDataProc(long, long, long, long, long) line: 994	
	GTK.gtk_tree_store_remove(long, long) line: not available [native method]	
	Tree.destroyItem(TreeItem) line: 1292	
	TreeItem.destroyWidget() line: 351	
	TreeItem(Widget).release(boolean) line: 1354	
	TreeItem(Widget).dispose() line: 543	
	TreeItem.dispose() line: 1088	
	TreeViewer.lambda$4(Object, int, List) line: 846	
	0x00000008013e4688.run() line: not available	
	TreeViewer.preservingSelection(Runnable, boolean) line: 358	
	TreeViewer(StructuredViewer).preservingSelection(Runnable) line: 1359	
	TreeViewer.remove(Object, int) line: 818	
	<UserCode>TreeContentProvider.updateElement(Object, int) line: 89	
	TreeViewer.virtualLazyUpdateWidget(Widget, int) line: 998	
	TreeViewer.lambda$1(Event) line: 258	
	0x00000008012b77a8.handleEvent(Event) line: not available	
	EventTable.sendEvent(Event) line: 89	
	Display.sendEvent(EventTable, Event) line: 5855	
	Tree(Widget).sendEvent(Event) line: 1529	
	Tree(Widget).sendEvent(int, Event, boolean) line: 1555	
	Tree(Widget).sendEvent(int, Event) line: 1538	
	Tree.checkData(TreeItem) line: 373	
	Tree.cellDataProc(long, long, long, long, long) line: 305	
	Display.cellDataProc(long, long, long, long, long) line: 994	
	GTK.gtk_tree_store_remove(long, long) line: not available [native method]	
	Tree.destroyItem(TreeItem) line: 1292	
	TreeItem.destroyWidget() line: 351	
	TreeItem(Widget).release(boolean) line: 1354	
	TreeItem(Widget).dispose() line: 543	
	TreeItem.dispose() line: 1088	
	TreeViewer.lambda$4(Object, int, List) line: 846	
	0x00000008013e4688.run() line: not available	
	TreeViewer.preservingSelection(Runnable, boolean) line: 358	
	TreeViewer(StructuredViewer).preservingSelection(Runnable) line: 1359	
	TreeViewer.remove(Object, int) line: 818	
	<UserCode>TreeContentProvider.updateElement(Object, int) line: 89	
	TreeViewer.virtualLazyUpdateWidget(Widget, int) line: 998	
	TreeViewer.lambda$1(Event) line: 258	
	0x00000008012b77a8.handleEvent(Event) line: not available	
	EventTable.sendEvent(Event) line: 89	
	Display.sendEvent(EventTable, Event) line: 5855	
	Tree(Widget).sendEvent(Event) line: 1529	
	Tree(Widget).sendEvent(int, Event, boolean) line: 1555	
	Tree(Widget).sendEvent(int, Event) line: 1538	
	Tree.checkData(TreeItem) line: 373	
	Tree.cellDataProc(long, long, long, long, long) line: 305	
	Display.cellDataProc(long, long, long, long, long) line: 994	
	GTK.gtk_tree_store_remove(long, long) line: not available [native method]	
	Tree.destroyItem(TreeItem) line: 1292	
	TreeItem.destroyWidget() line: 351	
	TreeItem(Widget).release(boolean) line: 1354	
	TreeItem(Widget).dispose() line: 543	
	TreeItem.dispose() line: 1088	
	Tree.remove(long, int, int) line: 2975	
	Tree.setItemCount(long, int) line: 3512	
	TreeItem.setItemCount(int) line: 1638	
	TreeViewer.lambda$5(Object, boolean) line: 955	
	0x00000008012d9fc8.run() line: not available	
	TreeViewer.preservingSelection(Runnable, boolean) line: 358	
	TreeViewer(StructuredViewer).preservingSelection(Runnable) line: 1359	
	TreeViewer.setHasChildren(Object, boolean) line: 941	
	<UserCode>TreeContentProvider.updateElement(Object, int) line: 85	
	TreeViewer.virtualLazyUpdateWidget(Widget, int) line: 998	
	TreeViewer.virtualRefreshExpandedItems(Widget, Widget, Object, int) line: 706	
	TreeViewer.virtualRefreshExpandedItems(Widget, Widget, Object, int) line: 714	
	TreeViewer.internalRefreshStruct(Widget, Object, boolean) line: 681	
	TreeViewer(AbstractTreeViewer).internalRefresh(Widget, Object, boolean, boolean) line: 1947	
	TreeViewer(AbstractTreeViewer).internalRefresh(Object, boolean) line: 1904	
	TreeViewer(AbstractTreeViewer).internalRefresh(Object) line: 1890	
	TreeViewer(StructuredViewer).lambda$2(Object) line: 1459	
	0x00000008012b8408.run() line: not available	
	TreeViewer(StructuredViewer).preservingSelection(Runnable, boolean) line: 1398	
	TreeViewer.preservingSelection(Runnable, boolean) line: 365	
	TreeViewer(StructuredViewer).preservingSelection(Runnable) line: 1359	
	TreeViewer(StructuredViewer).refresh(Object) line: 1459	
	TreeViewer(ColumnViewer).refresh(Object) line: 526	
	<UserCode>TreeContentProvider$ChildNode.lambda$4() line: 327	
	0x00000008013e26a0.run() line: not available	
	RunnableLock.run(Display) line: 40	
	Synchronizer.runAsyncMessages(boolean) line: 132	
	Display.runAsyncMessages(boolean) line: 5040	
	Display.readAndDispatch() line: 4520	
	PartRenderingEngine$5.run() line: 1155	
	Realm.runWithDefault(Realm, Runnable) line: 338	
	PartRenderingEngine.run(MApplicationElement, IEclipseContext) line: 1046	
	E4Workbench.createAndRunUI(MApplicationElement) line: 155	
	E4Application.start(IApplicationContext) line: 168	
	EclipseAppHandle.run(Object) line: 203	
	EclipseAppLauncher.runApplication(Object) line: 136	
	EclipseAppLauncher.start(Object) line: 104	
	EclipseStarter.run(Object) line: 402	
	EclipseStarter.run(String[], Runnable) line: 255	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 77	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
	Method.invoke(Object, Object...) line: 568	
	Main.invokeFramework(String[], URL[]) line: 659	
	Main.basicRun(String[]) line: 596	
	Main.run(String[]) line: 1467	
	Main.main(String[]) line: 1440	

I think the problem is with org.eclipse.swt.widgets.TreeItem.destroyWidget() that already has freed some data but not yet marked the item as disposed, then an event happens (maybe even a dispose event ...) and JFace acceses the data from partly disposed widget -> GTK crash!

laeubi avatar Sep 10 '23 05:09 laeubi

Actually it seems the SWT.SetData event in org.eclipse.jface.viewers.TreeViewer.hookControl(Control) that causing the crash.

laeubi avatar Sep 10 '23 05:09 laeubi

I now have also checked the JFace code it seems at even time the widgets are not marked as disposed so not much JFace can do here :-\

laeubi avatar Sep 10 '23 05:09 laeubi

Current hack in my org.eclipse.jface.viewers.ILazyTreeContentProvider.updateElement(Object, int) method;

@Override
public void updateElement(Object parent, int index) {
	if(isSwtIssue667()) {
		System.err.println("Break out because of https://github.com/eclipse-platform/eclipse.platform.swt/issues/667");
		return;
	}
        ....
}

private Boolean isSwtIssue667() {
	if(Platform.OS_LINUX.equals(Platform.getOS())) {
		return StackWalker.getInstance().walk(stream -> stream.map(StackFrame::getMethodName).anyMatch("gtk_tree_store_remove"::equals));
	}
	return false;
}

laeubi avatar Sep 10 '23 05:09 laeubi

If you happen to make an SWT snippet reproducing the problem, I might find time to fix it,

SyntevoAlex avatar Nov 28 '23 14:11 SyntevoAlex

@laeubi - I am running into the same crash in Eclipse 4.29 when selecting the elements from the TreeViewer with ILazyTreeContentProvider. And your workaround in updateElement() does not work for me. Any other suggestions? Thanks.

kudbudeen1 avatar Dec 08 '23 03:12 kudbudeen1

Any other suggestions?

as @SyntevoAlex mentioned if you have some snippet or application one can download to see the problem it would be great, I was not able to reproduce it in a smaller snippet.

laeubi avatar Dec 08 '23 05:12 laeubi

You can also try to run Eclipse with

export G_SLICE=always-malloc
export MALLOC_PERTURB_=204

Maybe it will help it crash and produce a crash log.

SyntevoAlex avatar Dec 09 '23 20:12 SyntevoAlex

FYI @akurtakov I finally got a reproducer now, it is not purse SWT an requires JFace and looks a bit clumsy but reproduce the problem reliable for me:

package test;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ILazyTreeContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class SnippetVirtualLazyTreeViewerCrash {


	private class MyContentProvider implements ILazyTreeContentProvider {
		private TreeViewer treeViewer;

		@Override
		public Object getParent(Object element) {
			return ((Node) element).getParent();
		}

		@Override
		public void updateChildCount(Object element, int currentChildCount) {
			treeViewer.setChildCount(element, ((Node) element).childs.size());
		}

		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			this.treeViewer = (TreeViewer) viewer;
		}

		@Override
		public void updateElement(Object parent, int index) {
			System.out.println("Snippet047VirtualLazyTreeViewerCrash.MyContentProvider.updateElement()");
			Thread.dumpStack();
			Node element = ((Node) parent).childs.get(index);
			if (element.childs.isEmpty()) {
				System.out.println("Node '" + element.text + " is empty and will no be removed");
				treeViewer.remove(parent);
			} else {
				System.out.println("Node '" + element.text + " will be made permanent");
				treeViewer.replace(parent, index, element);
				updateChildCount(element, -1);
			}
		}
	}

	public class Node {

		private final List<Node> childs = new ArrayList<>();
		private final Node parent;
		private final String text;

		public Node(String text, Node parent) {
			this.text = text;
			this.parent = parent;
		}

		public Node getParent() {
			return parent;
		}

		@Override
		public String toString() {
			return text;
		}

	}

	public Snippet047VirtualLazyTreeViewerCrash(Shell shell) {

		TreeViewer treeViewer = new TreeViewer(shell, SWT.VIRTUAL | SWT.BORDER);
		treeViewer.setLabelProvider(new LabelProvider());
		treeViewer.setContentProvider(new MyContentProvider());
		treeViewer.setUseHashlookup(true);
		Node root = new Node("root", null);
		for (int i = 0; i < 10; i++) {
			Node child = new Node("Child " + i, root);
			root.childs.add(child);
			for (int j = 0; j < 5; j++) {
				Node subchild = new Node("Child " + ((char) ('A' + j)), child);
				child.childs.add(subchild);
			}
		}
		treeViewer.setInput(root);
		treeViewer.getTree().setLayoutData(GridDataFactory.fillDefaults().create());
		treeViewer.setChildCount(root, root.childs.size());
		treeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {

			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				ITreeSelection selection = treeViewer.getStructuredSelection();
				Object firstElement = selection.getFirstElement();
				if (firstElement instanceof Node node) {
					Node parent = node.parent;
					parent.childs.remove(node);
					shell.getDisplay().timerExec(1000, () -> {
						treeViewer.refresh(parent);
					});
				}

			}
		});
	}

	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new GridLayout());
		new SnippetVirtualLazyTreeViewerCrash(shell);
		shell.setSize(800, 600);
		shell.open();

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		display.dispose();
	}

}

It shows you a tree and if you select on an item, it got removed after a 1 second delay. Now try to expand an item --> JVM crash with message

Node 'Child A is empty and will no be removed
Bail out! Gtk:ERROR:../../../gtk/gtktreestore.c:597:gtk_tree_store_get_path: assertion failed: (G_NODE (iter->user_data)->parent != NULL)
**
Gtk:ERROR:../../../gtk/gtktreestore.c:597:gtk_tree_store_get_path: assertion failed: (G_NODE (iter->user_data)->parent != NULL)

https://github.com/user-attachments/assets/c2820a06-6cb5-477f-aaa4-3c6e402c62bb

laeubi avatar Jul 18 '25 16:07 laeubi

Observations

  1. Initial Tree Population:

    • cellDataProc() gets called for rendering cells
    • gtk_tree_model_get_path() is called to get paths for items
    • checkData() triggers SWT.SetData events for virtual items
  2. Item Removal During Expand:

    [USER CODE] DirectCrashTest.MyContentProvider.updateElement() - parent=Child 0, index=0
    [USER CODE] Node 'SubChild 0.0' is empty and will be removed
    [JAVA] TreeItem.destroyWidget() - ENTER
    [JAVA] Tree.destroyItem() - ENTER - handle=139735893161088
    [JAVA] Tree.destroyItem() - About to call gtk_tree_store_remove
    [NATIVE C] gtk_tree_store_remove() - ENTER - store=0x7f16cc5c7bb0, iter=0x7f16cc463480
    [JAVA] Tree.cellDataProc() - ENTER - cell=139735893748432, iter=139735895274640
    
  3. Key Finding:

    • cellDataProc() is being called during gtk_tree_store_remove()
    • This happens before gtk_tree_store_remove() completes (before EXIT)
    • This is a re-entrant callback situation
  4. The Crash Path: When gtk_tree_store_remove() is called, GTK internally triggers callbacks that lead back to cellDataProc(), which then tries to access the TreeItem being removed. This can lead to:

    • Accessing partially destroyed GTK tree model nodes
    • The assertion (G_NODE (iter->user_data)->parent != NULL) failing when getExpanded() calls gtk_tree_model_get_path() on a node being removed

laeubi avatar Nov 02 '25 11:11 laeubi