Describe the bug
Jvm process crashes with SIGSEGV if there is a Tree with expanded+selected item and Tree.removeAll() is called.
To Reproduce
Here is a snippet for manual reproduction: TreeCrashBug.java.
[a version where clicks emulated in code: TreeCrashBugAuto.java]
Steps to reproduce:
- launch the app (preferably with env variables described below)
- click and expand node v1_1
- click and expand node v1_1_0 (the node becomes selected)
- press GO button => the program crashes and prints something like this into console:
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f2d8349392a, pid=47299, tid=47305
#
# JRE version: OpenJDK Runtime Environment (25.0.2+10) (build 25.0.2+10-Ubuntu-124.04)
# Java VM: OpenJDK 64-Bit Server VM (25.0.2+10-Ubuntu-124.04, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# C [libgtk-3.so.0+0x49392a] gtk_tree_store_get_path+0xc9
...
The generated error report file has this stacktrace:
--------------- T H R E A D ---------------
Current thread (0x00007f2de801b2d0): JavaThread "main" [_thread_in_native, id=47305, stack(0x00007f2dee700000,0x00007f2dee800000) (1024K)]
Stack: [0x00007f2dee700000,0x00007f2dee800000], sp=0x00007f2dee7fc010, free space=1008k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libgtk-3.so.0+0x49392a] gtk_tree_store_get_path+0xc9
C [libgtk-3.so.0+0x493a0c] gtk_tree_store_get_path+0x1ab
C [libgtk-3.so.0+0x47c542] gtk_tree_model_get_path+0x142
C [libswt-pi3-gtk-4973r12.so+0x48655] Java_org_eclipse_swt_internal_gtk_GTK_gtk_1tree_1model_1get_1path+0xf
j org.eclipse.swt.widgets.TreeItem.getParentItem()Lorg/eclipse/swt/widgets/TreeItem;+15
J 1275 c1 org.eclipse.jface.viewers.AbstractTreeViewer.getTreePathFromItem(Lorg/eclipse/swt/widgets/Item;)Lorg/eclipse/jface/viewers/TreePath; (47 bytes) @ 0x00007f2dd07a7f7c [0x00007f2dd07a7800+0x000000000000077c]
j org.eclipse.jface.viewers.AbstractTreeViewer.internalFindItem(Lorg/eclipse/jface/viewers/TreePath;)Lorg/eclipse/swt/widgets/Widget;+44
j org.eclipse.jface.viewers.AbstractTreeViewer.internalFindItems(Ljava/lang/Object;)[Lorg/eclipse/swt/widgets/Widget;+14
j org.eclipse.jface.viewers.TreeViewer.replace(Ljava/lang/Object;ILjava/lang/Object;)V+69
j treebug.TreeCrashBugAuto$TestContentProvider.updateElement(Lorg/eclipse/jface/viewers/TreePath;I)V+17
j org.eclipse.jface.viewers.TreeViewer.virtualLazyUpdateWidget(Lorg/eclipse/swt/widgets/Widget;I)V+65
j org.eclipse.jface.viewers.TreeViewer.lambda$1(Lorg/eclipse/swt/widgets/Event;)V+41
j org.eclipse.jface.viewers.TreeViewer$$Lambda+0x0000000078097ab0.handleEvent(Lorg/eclipse/swt/widgets/Event;)V+5
j org.eclipse.swt.widgets.EventTable.sendEvent(Lorg/eclipse/swt/widgets/Event;)V+243
j org.eclipse.swt.widgets.Display.sendEvent(Lorg/eclipse/swt/widgets/EventTable;Lorg/eclipse/swt/widgets/Event;)V+12
j org.eclipse.swt.widgets.Widget.sendEvent(Lorg/eclipse/swt/widgets/Event;)V+26
j org.eclipse.swt.widgets.Widget.sendEvent(ILorg/eclipse/swt/widgets/Event;Z)V+73
j org.eclipse.swt.widgets.Widget.sendEvent(ILorg/eclipse/swt/widgets/Event;)V+4
j org.eclipse.swt.widgets.Tree.checkData(Lorg/eclipse/swt/widgets/TreeItem;)Z+112
j org.eclipse.swt.widgets.Tree.cellDataProc(JJJJJ)J+180
j org.eclipse.swt.widgets.Display.cellDataProc(JJJJJ)J+25
v ~StubRoutines::call_stub 0x00007f2dd7b37fa6
V [libjvm.so+0x9e4d50] JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x2b0
V [libjvm.so+0xaa1b9b] jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, JavaThread*) [clone .constprop.1]+0x1db
V [libjvm.so+0xaaca78] jni_CallLongMethodV+0x1c8
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.eclipse.swt.internal.gtk.GTK.gtk_tree_model_get_path(JJ)J+0
j org.eclipse.swt.widgets.TreeItem.getParentItem()Lorg/eclipse/swt/widgets/TreeItem;+15
J 1275 c1 org.eclipse.jface.viewers.AbstractTreeViewer.getTreePathFromItem(Lorg/eclipse/swt/widgets/Item;)Lorg/eclipse/jface/viewers/TreePath; (47 bytes) @ 0x00007f2dd07a7f7c [0x00007f2dd07a7800+0x000000000000077c]
j org.eclipse.jface.viewers.AbstractTreeViewer.internalFindItem(Lorg/eclipse/jface/viewers/TreePath;)Lorg/eclipse/swt/widgets/Widget;+44
j org.eclipse.jface.viewers.AbstractTreeViewer.internalFindItems(Ljava/lang/Object;)[Lorg/eclipse/swt/widgets/Widget;+14
j org.eclipse.jface.viewers.TreeViewer.replace(Ljava/lang/Object;ILjava/lang/Object;)V+69
j treebug.TreeCrashBugAuto$TestContentProvider.updateElement(Lorg/eclipse/jface/viewers/TreePath;I)V+17
j org.eclipse.jface.viewers.TreeViewer.virtualLazyUpdateWidget(Lorg/eclipse/swt/widgets/Widget;I)V+65
j org.eclipse.jface.viewers.TreeViewer.lambda$1(Lorg/eclipse/swt/widgets/Event;)V+41
j org.eclipse.jface.viewers.TreeViewer$$Lambda+0x0000000078097ab0.handleEvent(Lorg/eclipse/swt/widgets/Event;)V+5
j org.eclipse.swt.widgets.EventTable.sendEvent(Lorg/eclipse/swt/widgets/Event;)V+243
j org.eclipse.swt.widgets.Display.sendEvent(Lorg/eclipse/swt/widgets/EventTable;Lorg/eclipse/swt/widgets/Event;)V+12
j org.eclipse.swt.widgets.Widget.sendEvent(Lorg/eclipse/swt/widgets/Event;)V+26
j org.eclipse.swt.widgets.Widget.sendEvent(ILorg/eclipse/swt/widgets/Event;Z)V+73
j org.eclipse.swt.widgets.Widget.sendEvent(ILorg/eclipse/swt/widgets/Event;)V+4
j org.eclipse.swt.widgets.Tree.checkData(Lorg/eclipse/swt/widgets/TreeItem;)Z+112
j org.eclipse.swt.widgets.Tree.cellDataProc(JJJJJ)J+180
j org.eclipse.swt.widgets.Display.cellDataProc(JJJJJ)J+25
v ~StubRoutines::call_stub 0x00007f2dd7b37fa6
j org.eclipse.swt.internal.gtk.GTK.gtk_tree_store_clear(J)V+0
j org.eclipse.swt.widgets.Tree.removeAll()V+34
j org.eclipse.jface.viewers.TreeViewer.removeAll(Lorg/eclipse/swt/widgets/Control;)V+4
j org.eclipse.jface.viewers.AbstractTreeViewer.lambda$2()V+12
j org.eclipse.jface.viewers.AbstractTreeViewer$$Lambda+0x0000000078098ea8.run()V+4
j org.eclipse.jface.viewers.StructuredViewer.preservingSelection(Ljava/lang/Runnable;Z)V+26
j org.eclipse.jface.viewers.TreeViewer.preservingSelection(Ljava/lang/Runnable;Z)V+29
j org.eclipse.jface.viewers.StructuredViewer.preservingSelection(Ljava/lang/Runnable;)V+3
j org.eclipse.jface.viewers.AbstractTreeViewer.inputChanged(Ljava/lang/Object;Ljava/lang/Object;)V+7
j org.eclipse.jface.viewers.ContentViewer.setInput(Ljava/lang/Object;)V+72
j org.eclipse.jface.viewers.StructuredViewer.setInput(Ljava/lang/Object;)V+33
j treebug.TreeCrashBugAuto.main([Ljava/lang/String;)V+151
v ~StubRoutines::call_stub 0x00007f2dd7b37fa6
It's a little strange actually: it contains nested calls to Tree.cellDataProc(...).
I was able to get a stacktrace differently: I attached to the process with java and c/c++ debuggers simultaneously.
Here is the java stacktrace (from java debugger) with insertions of native stacktraces (from c/c++ debugger) (it's right before the process crash):
=== Native stack in c/c++ debugger ===
__pthread_kill_implementation() at ./nptl/./nptl/pthread_kill.c:44 0x7f2df009eb2c
__pthread_kill_internal() at ./nptl/./nptl/pthread_kill.c:78 0x7f2df009eb2c
__GI___pthread_kill() at ./nptl/./nptl/pthread_kill.c:89 0x7f2df009eb2c
__GI_raise() at ./signal/../sysdeps/posix/raise.c:26 0x7f2df004527e
__GI_abort() at ./stdlib/./stdlib/abort.c:79 0x7f2df00288ff
os::abort(bool, void const*, void const*) [clone .cold] at 0x7f2deeadc1b9
VMError::report_and_die() at 0x7f2defa1a3e6
VMError::report_and_die() at 0x7f2defa1abcf
VMError::report_and_die() at 0x7f2defa1ac1f
JVM_handle_linux_signal() at 0x7f2def86f630
<signal handler called>() at 0x7f2df0045330
gtk_tree_store_get_path() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtktreestore.c:594 0x7f2d8349392a
gtk_tree_store_get_path() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtktreestore.c:610 0x7f2d83493a0c
gtk_tree_model_get_path() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtktreemodel.c:1 405 0x7f2d8347c542
Java_org_eclipse_swt_internal_gtk_GTK_gtk_1tree_1model_1get_1path() at 0x7f2dc41d4655
0x7f2dd7b47112
0x7f2dee7fc1c8
0x7f2dd7b46d39
0x7f2dee7fc1e8
0x7f2dd7b46d04
0xfffffffffffffff7
0x7f2d9c52f298
0x7
0x7f2d9c536b90
0x0
TreeItem.getParentItem() line: 848
TreeViewer.getParentItem(Item) line: 229
TreeViewer(AbstractTreeViewer).getTreePathFromItem(Item) line: 3199
TreeViewer(AbstractTreeViewer).internalFindItem(TreePath) line: 237
TreeViewer(AbstractTreeViewer).internalFindItems(Object) line: 214
TreeViewer.replace(Object, int, Object) line: 438
TreeCrashBugAuto$TestContentProvider.updateElement(TreePath, int) line: 96
TreeViewer.virtualLazyUpdateWidget(Widget, int) line: 1003
TreeViewer.lambda$1(Event) line: 261
Lambda.handleEvent(Event) line: not available
EventTable.sendEvent(Event) line: 91
Display.sendEvent(EventTable, Event) line: 5865
Tree(Widget).sendEvent(Event) line: 1656
Tree(Widget).sendEvent(int, Event, boolean) line: 1682
Tree(Widget).sendEvent(int, Event) line: 1665
Tree.checkData(TreeItem) line: 375
Tree.cellDataProc(long, long, long, long, long) line: 307
Display.cellDataProc(long, long, long, long, long) line: 997
=== Native stack in c/c++ debugger ===
apply_cell_attributes() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtkcellarea.c:1 257 0x7f2d8311da3b
g_hash_table_foreach() at /opt/gtk/glib2.0-2.80.0/glib/ghash.c:2 117 0x7f2d82d8ef80
gtk_cell_area_real_apply_attributes() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtkcellarea.c:1 286 0x7f2d8311db55
gtk_cell_area_box_apply_attributes() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtkcellareabox.c:1 310 0x7f2d83127dc5
_gtk_marshal_VOID__OBJECT_BOXED_BOOLEAN_BOOLEANv() at /opt/gtk/gtk+3.0-3.24.41/builddir/gtk/gtkmarshalers.c:5 447 0x7f2d830a82e2
g_type_class_meta_marshalv() at /opt/gtk/glib2.0-2.80.0/gobject/gclosure.c:1 062 0x7f2d82cd7f7e
_g_closure_invoke_va() at /opt/gtk/glib2.0-2.80.0/gobject/gclosure.c:897 0x7f2d82cd7a82
signal_emit_valist_unlocked() at /opt/gtk/glib2.0-2.80.0/gobject/gsignal.c:3 424 0x7f2d82cfa81f
g_signal_emit_valist() at /opt/gtk/glib2.0-2.80.0/gobject/gsignal.c:3 263 0x7f2d82cfa16e
g_signal_emit() at /opt/gtk/glib2.0-2.80.0/gobject/gsignal.c:3 583 0x7f2d82cfbb43
gtk_cell_area_apply_attributes() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtkcellarea.c:2 373 0x7f2d83120b52
gtk_tree_view_column_cell_set_cell_data() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtktreeviewcolumn.c:2 821 0x7f2d834c9cfc
set_cell_data() at /opt/gtk/gtk+3.0-3.24.41/gtk/a11y/gtktreeviewaccessible.c:347 0x7f2d835f85d6
create_cell() at /opt/gtk/gtk+3.0-3.24.41/gtk/a11y/gtktreeviewaccessible.c:439 0x7f2d835f890d
_gtk_tree_view_accessible_add_state() at /opt/gtk/gtk+3.0-3.24.41/gtk/a11y/gtktreeviewaccessible.c:2 053 0x7f2d835fc039
gtk_tree_view_real_set_cursor() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtktreeview.c:13 377 0x7f2d834bc13b
gtk_tree_view_row_deleted() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtktreeview.c:9 430 0x7f2d834b1916
g_cclosure_marshal_VOID__BOXED() at /opt/gtk/glib2.0-2.80.0/gobject/gmarshal.c:1 628 0x7f2d82cdd612
g_closure_invoke() at /opt/gtk/glib2.0-2.80.0/gobject/gclosure.c:834 0x7f2d82cd7763
signal_emit_unlocked_R() at /opt/gtk/glib2.0-2.80.0/gobject/gsignal.c:3 888 0x7f2d82cfc894
signal_emit_valist_unlocked() at /opt/gtk/glib2.0-2.80.0/gobject/gsignal.c:3 520 0x7f2d82cfb587
g_signal_emit_valist() at /opt/gtk/glib2.0-2.80.0/gobject/gsignal.c:3 263 0x7f2d82cfa16e
g_signal_emit() at /opt/gtk/glib2.0-2.80.0/gobject/gsignal.c:3 583 0x7f2d82cfbb43
gtk_tree_model_row_deleted() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtktreemodel.c:1 914 0x7f2d8347df98
gtk_tree_store_remove() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtktreestore.c:1 231 0x7f2d834957a6
gtk_tree_store_clear_traverse() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtktreestore.c:1 848 0x7f2d834971d2
gtk_tree_store_clear_traverse() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtktreestore.c:1 839 0x7f2d8349718b
gtk_tree_store_clear() at /opt/gtk/gtk+3.0-3.24.41/gtk/gtktreestore.c:1 884 0x7f2d83497310
Java_org_eclipse_swt_internal_gtk_GTK_gtk_1tree_1store_1clear() at 0x7f2dc41d494d
0x7f2dd7b47112
0x7f2de801d7b8
0x7f2de801d890
0xd8
0xfffffffffffffff7
0x0
GTK.gtk_tree_store_clear(long) line: not available [native method]
Tree.removeAll() line: 2960
TreeViewer.removeAll(Control) line: 290
TreeViewer(AbstractTreeViewer).lambda$2() line: 1629
Lambda.run() line: not available
TreeViewer(StructuredViewer).preservingSelection(Runnable, boolean) line: 1395
TreeViewer.preservingSelection(Runnable, boolean) line: 368
TreeViewer(StructuredViewer).preservingSelection(Runnable) line: 1356
TreeViewer(AbstractTreeViewer).inputChanged(Object, Object) line: 1625
TreeViewer(ContentViewer).setInput(Object) line: 279
TreeViewer(StructuredViewer).setInput(Object) line: 1639
TreeCrashBugAuto.main(String[]) line: 49
Note that the tree has a scrollbar: on my machine the bug doesn't happen if the window is large enough for the tree to have no scrollbar.
Environment variables to start the snippet
The bug seems to be use-after-free error: SWT uses some pointer that has already been freed in the native gtk code.
Such bugs can be difficult to reproduce: the only happens if the freed memory is overritten with some "bad" values by the time the dangling pointer is accessed again.
In order to increase the probability of the bug showing use this environment variables:
export G_DEBUG=gc-friendly # glib: fill freed memory with 0s
export G_SLICE=always-malloc # disable glib's internal memory allocator
export MALLOC_PERTURB_=255 # glibc: fill freed memory with 1s, and fill allocated memory with 0s
This bug is similar to:
Expected behavior
Tree items should be deleted without errors.
Screenshots
See above.
Environment:
- Select the platform(s) on which the behavior is seen:
-
Additional OS info (e.g. OS version, Linux Desktop, etc)
Ubuntu 24.04.4 LTS
X.Org 21.1.11
GTK 3.24.41
SWT 4.39 (the bug also happens in 4.40RC1) from https://download.eclipse.org/eclipse/downloads/
JFace 3.39.0 from maven central repo
-
JRE/JDK version
OpenJDK 64-Bit Server VM (build 25.0.2+10-Ubuntu-124.04, mixed mode, sharing)
Version since
At least since SWT 4.39.
Workaround (or) Additional context
The workaround described here works for this bug.
Describe the bug
Jvm process crashes with
SIGSEGVif there is aTreewith expanded+selected item andTree.removeAll()is called.To Reproduce
Here is a snippet for manual reproduction: TreeCrashBug.java.
[a version where clicks emulated in code: TreeCrashBugAuto.java]
Steps to reproduce:
The generated error report file has this stacktrace:
It's a little strange actually: it contains nested calls to
Tree.cellDataProc(...).I was able to get a stacktrace differently: I attached to the process with java and c/c++ debuggers simultaneously.
Here is the java stacktrace (from java debugger) with insertions of native stacktraces (from c/c++ debugger) (it's right before the process crash):
Note that the tree has a scrollbar: on my machine the bug doesn't happen if the window is large enough for the tree to have no scrollbar.
Environment variables to start the snippet
The bug seems to be use-after-free error: SWT uses some pointer that has already been freed in the native gtk code.
Such bugs can be difficult to reproduce: the only happens if the freed memory is overritten with some "bad" values by the time the dangling pointer is accessed again.
In order to increase the probability of the bug showing use this environment variables:
This bug is similar to:
Tree.cellDataProcwhen callingTreeItem.setImage#678 - use-after-free error that causesSIGSEGVExpected behavior
Tree items should be deleted without errors.
Screenshots
See above.
Environment:
Additional OS info (e.g. OS version, Linux Desktop, etc)
Ubuntu 24.04.4 LTS
X.Org 21.1.11
GTK 3.24.41
SWT 4.39 (the bug also happens in 4.40RC1) from https://download.eclipse.org/eclipse/downloads/
JFace 3.39.0 from maven central repo
JRE/JDK version
OpenJDK 64-Bit Server VM (build 25.0.2+10-Ubuntu-124.04, mixed mode, sharing)
Version since
At least since SWT 4.39.
Workaround (or) Additional context
The workaround described here works for this bug.