Bug 573758 - [GTK3] Tree.setSelection() leaks native memory
Summary: [GTK3] Tree.setSelection() leaks native memory
Status: CLOSED NOT_ECLIPSE
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.15   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Platform-SWT-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-05-25 09:40 EDT by Simeon Andreev CLA
Modified: 2021-06-16 07:26 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Simeon Andreev CLA 2021-05-25 09:40:34 EDT
To reproduce, run the following snippet:

  public static void main(String[] args) {
    Display display = new Display();
    final Image image = display.getSystemImage(SWT.ICON_INFORMATION);
    Shell shell = new Shell(display);
    shell.setText("Test Tree leak based on SWT example: Images on the right side of the TreeItem");
    shell.setLayout(new FillLayout());
    
    shell.setSize(500, 200);
    shell.open();
    
    AtomicBoolean c = new AtomicBoolean(true);
    Thread t = new Thread(new Runnable() {
    	AtomicInteger i = new AtomicInteger(0);
    	Tree tree;
    	List<TreeItem> items;
    	@Override
    	public void run() {
    		while (c.get() && !display.isDisposed()) {
    			display.asyncExec(new Runnable() {
    				@Override
    				public void run() {
    					tree = new Tree(shell, SWT.MULTI | SWT.FULL_SELECTION);
    				    tree.setHeaderVisible(true);
    				    tree.setLinesVisible(true);
    				    int columnCount = 4;
    				    for (int i = 0; i < columnCount; i++) {
    				      TreeColumn column = new TreeColumn(tree, SWT.NONE);
    				      column.setText("Column " + i);
    				    }
    				    items = new ArrayList<>();
    				    int itemCount = 3;
    				    for (int i = 0; i < itemCount; i++) {
    				      TreeItem item1 = new TreeItem(tree, SWT.NONE);
    				      item1.setText("item " + i);
    				      for (int c = 1; c < columnCount; c++) {
    				        item1.setText(c, "item [" + i + "-" + c + "]");
    				        item1.setImage(c, image);
    				      }
    				      items.add(item1);
    				    }

    				    for (int i = 0; i < columnCount; i++) {
    				      tree.getColumn(i).pack();
    				    }
    				}
    			});
    			try {
    				Thread.sleep(1000);
    			} catch (InterruptedException e) {
    			}
    			display.asyncExec(new Runnable() {
    				@Override
    				public void run() {
    					int index = i.getAndIncrement() % items.size();
    					tree.setSelection(items.get(index));
    				}
    			});
    			try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
				}
    			display.asyncExec(new Runnable() {
    				@Override
    				public void run() {
    					tree.dispose();
    					tree = null;
    					items = null;
    				}
    			});
    			try {
    				Thread.sleep(1000);
    			} catch (InterruptedException e) {
    			}
    		}
    	}
    });
    t.start();
  
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }
    c.set(false);
    if (image != null)
      image.dispose();
    display.dispose();
  }

jemalloc reports the memory leak as:

[2688 bytes leaked]
je_prof_backtrace (/home/sandreev/git/misc/jemalloc/src/prof.c:636 (discriminator 2))
je_malloc_default (/home/sandreev/git/misc/jemalloc/src/jemalloc.c:2289)
g_malloc (??:?)
g_slice_alloc (??:?)
g_slice_alloc0 (??:?)
g_type_create_instance (??:?)
g_object_unref (??:?)
g_object_new_valist (??:?)
g_object_new (??:?)
gtk_renderer_cell_accessible_new (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtkrenderercellaccessible.c:116)
create_cell (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:424)
_gtk_tree_view_accessible_add_state (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:1984)
gtk_tree_view_real_set_cursor (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13313)
gtk_tree_view_set_cursor_on_cell (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13440)
Java_org_eclipse_swt_internal_gtk_GTK_gtk_1tree_1view_1set_1cursor (??:?)
?? (??:0)

If the snippet runs for a longer time:

[27264 bytes leaked]
je_prof_backtrace (/home/sandreev/git/misc/jemalloc/src/prof.c:636 (discriminator 2))
je_malloc_default (/home/sandreev/git/misc/jemalloc/src/jemalloc.c:2289)
g_malloc (??:?)
g_slice_alloc (??:?)
g_slice_alloc0 (??:?)
g_type_create_instance (??:?)
g_object_unref (??:?)
g_object_new_valist (??:?)
g_object_new (??:?)
gtk_renderer_cell_accessible_new (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtkrenderercellaccessible.c:116)
create_cell (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:424)
_gtk_tree_view_accessible_add_state (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:1984)
gtk_tree_view_real_set_cursor (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13313)
gtk_tree_view_set_cursor_on_cell (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13440)
Java_org_eclipse_swt_internal_gtk_GTK_gtk_1tree_1view_1set_1cursor (??:?)
?? (??:0)
Comment 1 Simeon Andreev CLA 2021-05-25 09:50:06 EDT
I cannot reproduce the leak without creating and disposing trees, so I guess the leak is per-tree and not per select call.
Comment 2 Simeon Andreev CLA 2021-05-26 07:40:38 EDT
Reproducible also with a more trivial snippet:

	public static void main(String[] args) {
		int n = 1;
		
		Display display = new Display();
		final Image image = display.getSystemImage(SWT.ICON_INFORMATION);
		Shell shell = new Shell(display);
		shell.setText("Test Tree leak based on SWT example: Images on the right side of the TreeItem");
		shell.setLayout(new FillLayout(SWT.VERTICAL));

		for (int j = 0; j < n; ++j) {
			Tree tree = new Tree(shell, SWT.MULTI | SWT.FULL_SELECTION);
			tree.setHeaderVisible(true);
			tree.setLinesVisible(true);
			int columnCount = 4;
			for (int i = 0; i < columnCount; i++) {
				TreeColumn column = new TreeColumn(tree, SWT.NONE);
				column.setText("Column " + i);
			}
			List<TreeItem> items = new ArrayList<>();
			int itemCount = 3;
			for (int i = 0; i < itemCount; i++) {
				TreeItem item1 = new TreeItem(tree, SWT.NONE);
				item1.setText("item " + i);
				for (int c = 1; c < columnCount; c++) {
					item1.setText(c, "item [" + i + "-" + c + "]");
					item1.setImage(c, image);
				}
				items.add(item1);
			}

			for (int i = 0; i < columnCount; i++) {
				tree.getColumn(i).pack();
			}
			tree.setSelection(items.get(j % items.size()));
		}

		shell.setSize(500, 1000);
		shell.open();

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

For n = 1:

[384 bytes leaked]
je_prof_backtrace (/home/sandreev/git/misc/jemalloc/src/prof.c:636 (discriminator 2))
je_malloc_default (/home/sandreev/git/misc/jemalloc/src/jemalloc.c:2289)
g_malloc (??:?)
g_slice_alloc (??:?)
g_slice_alloc0 (??:?)
g_type_create_instance (??:?)
g_object_unref (??:?)
g_object_new_valist (??:?)
g_object_new (??:?)
gtk_renderer_cell_accessible_new (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtkrenderercellaccessible.c:116)
create_cell (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:424)
_gtk_tree_view_accessible_add_state (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:1984)
gtk_tree_view_real_set_cursor (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13313)
gtk_tree_view_set_cursor_on_cell (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13440)
Java_org_eclipse_swt_internal_gtk_GTK_gtk_1tree_1view_1set_1cursor (??:?)
?? (??:0)

For n = 5:

[1920 bytes leaked]
je_prof_backtrace (/home/sandreev/git/misc/jemalloc/src/prof.c:636 (discriminator 2))
je_malloc_default (/home/sandreev/git/misc/jemalloc/src/jemalloc.c:2289)
g_malloc (??:?)
g_slice_alloc (??:?)
g_slice_alloc0 (??:?)
g_type_create_instance (??:?)
g_object_unref (??:?)
g_object_new_valist (??:?)
g_object_new (??:?)
gtk_renderer_cell_accessible_new (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtkrenderercellaccessible.c:116)
create_cell (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:424)
_gtk_tree_view_accessible_add_state (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:1984)
gtk_tree_view_real_set_cursor (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13313)
gtk_tree_view_set_cursor_on_cell (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13440)
Java_org_eclipse_swt_internal_gtk_GTK_gtk_1tree_1view_1set_1cursor (??:?)
?? (??:0)

Something used by GTK+ is not being freed correctly.

When I try similar code with a GTK+ snippet, I don't see a leak (but maybe I'm missing something that SWT does):

#include <gtk/gtk.h>

enum
{
  COL_URI = 0,
  NUM_COLS
} ;

// gcc -g table.c  `pkg-config --cflags --libs gtk+-3.0`  -o table

int main (int argc, char **argv)
{
  GtkWidget *window, *scrolled_window, *box, *tree;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
  gtk_window_set_default_size(GTK_WINDOW(window), 200, 200);

  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  gtk_container_add (GTK_CONTAINER (window), scrolled_window);

  box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
  gtk_container_add(GTK_CONTAINER(scrolled_window), box);

  int n = 1;
  int i;
  for (i = 0; i < n; ++i)
  {
    GtkTreeViewColumn   *col1;
    GtkCellRenderer     *renderer;
    GtkListStore        *liststore;

    liststore = gtk_list_store_new(NUM_COLS, G_TYPE_STRING);

    tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));

    g_object_unref(liststore); /* destroy model with view */

    col1 = gtk_tree_view_column_new();;

    renderer = gtk_cell_renderer_text_new();

    gtk_tree_view_column_set_title(col1, "column");
    gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col1);
    gtk_tree_view_column_pack_start(col1, renderer, TRUE);
    gtk_tree_view_column_add_attribute(col1, renderer, "text", COL_URI);
    gtk_tree_view_column_set_fixed_width(col1, 150);
    gtk_tree_view_column_set_resizable(col1, TRUE);

    GtkTreeStore *treestore;
    treestore = gtk_tree_store_new(NUM_COLS, G_TYPE_STRING);

    gtk_tree_view_set_model(GTK_TREE_VIEW(tree), NULL);
    gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(treestore));

    GtkTreeIter iter;
    int j;
    for (j = 0; j < 3; ++j)
    {
      gtk_tree_store_append(treestore, &iter, NULL);
      gtk_tree_store_set(treestore, &iter, COL_URI, "item", -1);
    }

    GtkTreePath *path;
    path = gtk_tree_model_get_path (GTK_TREE_MODEL(treestore), &iter);
    gtk_tree_view_set_cursor (GTK_TREE_VIEW(tree), path, col1, FALSE);
    gtk_tree_path_free (path);

    gtk_box_pack_start(GTK_BOX(box), tree, TRUE, TRUE, 0);
  }

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}

If I simplify the SWT snippet more, to be like the GTK+ snippet above, I still see the same leak (though somewhat less memory is leaked):

	public static void main(String[] args) {
		int n = 1;
		
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setText("tree");
		shell.setLayout(new FillLayout(SWT.VERTICAL));

		for (int j = 0; j < n; ++j) {
			Tree tree = new Tree(shell, SWT.MULTI | SWT.FULL_SELECTION);
			tree.setHeaderVisible(true);
			tree.setLinesVisible(true);
			TreeColumn column = new TreeColumn(tree, SWT.NONE);
			column.setText("column");
			List<TreeItem> items = new ArrayList<>();
			int itemCount = 3;
			for (int i = 0; i < itemCount; i++) {
				TreeItem item1 = new TreeItem(tree, SWT.NONE);
				item1.setText(new String[] { "text" });
				items.add(item1);
			}
			column.pack();
			tree.setSelection(items.get(/* j % items.size() */2));
		}

		shell.setSize(500, 1000);
		shell.open();

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

n = 1:

[160 bytes leaked]
je_prof_backtrace (/home/sandreev/git/misc/jemalloc/src/prof.c:636 (discriminator 2))
je_malloc_default (/home/sandreev/git/misc/jemalloc/src/jemalloc.c:2289)
g_malloc (??:?)
g_slice_alloc (??:?)
g_slice_alloc0 (??:?)
g_type_create_instance (??:?)
g_object_unref (??:?)
g_object_new_with_properties (??:?)
g_object_new (??:?)
gtk_container_cell_accessible_new (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtkcontainercellaccessible.c:131)
create_cell (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:424)
_gtk_tree_view_accessible_add_state (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:1984)
gtk_tree_view_real_set_cursor (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13313)
gtk_tree_view_set_cursor_on_cell (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13440)
Java_org_eclipse_swt_internal_gtk_GTK_gtk_1tree_1view_1set_1cursor (??:?)
?? (??:0)

n = 5:

[800 bytes leaked]
je_prof_backtrace (/home/sandreev/git/misc/jemalloc/src/prof.c:636 (discriminator 2))
je_malloc_default (/home/sandreev/git/misc/jemalloc/src/jemalloc.c:2289)
g_malloc (??:?)
g_slice_alloc (??:?)
g_slice_alloc0 (??:?)
g_type_create_instance (??:?)
g_object_unref (??:?)
g_object_new_with_properties (??:?)
g_object_new (??:?)
gtk_container_cell_accessible_new (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtkcontainercellaccessible.c:131)
create_cell (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:424)
_gtk_tree_view_accessible_add_state (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:1984)
gtk_tree_view_real_set_cursor (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13313)
gtk_tree_view_set_cursor_on_cell (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13440)
Java_org_eclipse_swt_internal_gtk_GTK_gtk_1tree_1view_1set_1cursor (??:?)
?? (??:0)
Comment 3 Simeon Andreev CLA 2021-05-26 11:30:44 EDT
Looks like the leaking code runs only if there is more than 1 renderer for a column. So I've updated my GTK+ snippet:

#include <gtk/gtk.h>

enum
{
  COL_URI = 0,
  NUM_COLS
} ;

// gcc -g table.c  `pkg-config --cflags --libs gtk+-3.0`  -o table

int main (int argc, char **argv)
{
  GtkWidget *window, *scrolled_window, *box, *tree;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
  gtk_window_set_default_size(GTK_WINDOW(window), 500, 1000);

  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  gtk_container_add (GTK_CONTAINER (window), scrolled_window);

  box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
  gtk_container_add(GTK_CONTAINER(scrolled_window), box);

  int n = 1;
  int i;
  for (i = 0; i < n; ++i)
  {
    GtkTreeViewColumn   *col1;
    GtkCellRenderer     *renderer;
    GtkListStore        *liststore;

    liststore = gtk_list_store_new(NUM_COLS, G_TYPE_STRING);

    tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));

    g_object_unref(liststore); /* destroy model with view */

    col1 = gtk_tree_view_column_new();

    gtk_tree_view_column_set_title(col1, "column");
    gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col1);
    
    renderer = gtk_cell_renderer_text_new();
    gtk_tree_view_column_pack_start(col1, renderer, TRUE);
    gtk_tree_view_column_add_attribute(col1, renderer, "text", COL_URI + 0);
    
    renderer = gtk_cell_renderer_pixbuf_new();
    gtk_tree_view_column_pack_start(col1, renderer, TRUE);
    //gtk_tree_view_column_add_attribute(col1, renderer, "pixbuf", COL_URI + 0);

    gtk_tree_view_column_set_fixed_width(col1, 150);
    gtk_tree_view_column_set_resizable(col1, TRUE);

    gtk_box_pack_start(GTK_BOX(box), tree, TRUE, TRUE, 0);
   
    GtkTreeStore *treestore;
    treestore = gtk_tree_store_new(NUM_COLS, G_TYPE_STRING);

    gtk_tree_view_set_model(GTK_TREE_VIEW(tree), NULL);
    gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(treestore));

    GtkTreeIter iter;
    int j;
    for (j = 0; j < 3; ++j)
    {
      gtk_tree_store_append(treestore, &iter, NULL);
      gtk_tree_store_set(treestore, &iter, COL_URI, "item", -1);
    }

    GtkTreePath *path;
    path = gtk_tree_model_get_path (GTK_TREE_MODEL(treestore), &iter);
    gtk_tree_view_set_cursor (GTK_TREE_VIEW(tree), path, col1, FALSE);
    gtk_tree_path_free (path);
  }

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}
 
jemalloc now shows the same leak:

n = 1:

[160 bytes leaked]
je_prof_backtrace (/home/sandreev/git/misc/jemalloc/src/prof.c:636 (discriminator 2))
je_malloc_default (/home/sandreev/git/misc/jemalloc/src/jemalloc.c:2289)
g_malloc (??:?)
g_slice_alloc (??:?)
g_slice_alloc0 (??:?)
g_type_create_instance (??:?)
g_object_unref (??:?)
g_object_new_with_properties (??:?)
g_object_new (??:?)
gtk_container_cell_accessible_new (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtkcontainercellaccessible.c:131)
create_cell (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:424)
_gtk_tree_view_accessible_add_state (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:1984)
gtk_tree_view_real_set_cursor (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13313)
gtk_tree_view_set_cursor_on_cell (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13440)
?? (??:0)
__libc_start_main (/usr/src/debug/glibc-2.17-c758a686/csu/../csu/libc-start.c:274)
?? (??:0)

n = 5:

[800 bytes leaked]
je_prof_backtrace (/home/sandreev/git/misc/jemalloc/src/prof.c:636 (discriminator 2))
je_malloc_default (/home/sandreev/git/misc/jemalloc/src/jemalloc.c:2289)
g_malloc (??:?)
g_slice_alloc (??:?)
g_slice_alloc0 (??:?)
g_type_create_instance (??:?)
g_object_unref (??:?)
g_object_new_with_properties (??:?)
g_object_new (??:?)
gtk_container_cell_accessible_new (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtkcontainercellaccessible.c:131)
create_cell (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:424)
_gtk_tree_view_accessible_add_state (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:1984)
gtk_tree_view_real_set_cursor (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13313)
gtk_tree_view_set_cursor_on_cell (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13440)
?? (??:0)
__libc_start_main (/usr/src/debug/glibc-2.17-c758a686/csu/../csu/libc-start.c:274)
?? (??:0)

n = 12:

[1920 bytes leaked]
je_prof_backtrace (/home/sandreev/git/misc/jemalloc/src/prof.c:636 (discriminator 2))
je_malloc_default (/home/sandreev/git/misc/jemalloc/src/jemalloc.c:2289)
g_malloc (??:?)
g_slice_alloc (??:?)
g_slice_alloc0 (??:?)
g_type_create_instance (??:?)
g_object_unref (??:?)
g_object_new_with_properties (??:?)
g_object_new (??:?)
gtk_container_cell_accessible_new (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtkcontainercellaccessible.c:131)
create_cell (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:424)
_gtk_tree_view_accessible_add_state (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:1984)
gtk_tree_view_real_set_cursor (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13313)
gtk_tree_view_set_cursor_on_cell (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13440)
?? (??:0)
__libc_start_main (/usr/src/debug/glibc-2.17-c758a686/csu/../csu/libc-start.c:274)
?? (??:0)

n = 21:

[3360 bytes leaked]
je_prof_backtrace (/home/sandreev/git/misc/jemalloc/src/prof.c:636 (discriminator 2))
je_malloc_default (/home/sandreev/git/misc/jemalloc/src/jemalloc.c:2289)
g_malloc (??:?)
g_slice_alloc (??:?)
g_slice_alloc0 (??:?)
g_type_create_instance (??:?)
g_object_unref (??:?)
g_object_new_with_properties (??:?)
g_object_new (??:?)
gtk_container_cell_accessible_new (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtkcontainercellaccessible.c:131)
create_cell (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:424)
_gtk_tree_view_accessible_add_state (/usr/src/debug/gtk+-3.22.30/gtk/a11y/gtktreeviewaccessible.c:1984)
gtk_tree_view_real_set_cursor (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13313)
gtk_tree_view_set_cursor_on_cell (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:13440)
?? (??:0)
__libc_start_main (/usr/src/debug/glibc-2.17-c758a686/csu/../csu/libc-start.c:274)
?? (??:0)

Alexander, do you have time to double check this? It would be quite unfortunate if the leak is in GTK+, since getting a fix might takes months, years, or we might not get a fix at all...
Comment 4 Alexandr Miloslavskiy CLA 2021-05-26 20:46:06 EDT
Seems to be a GTK bug indeed:
https://gitlab.gnome.org/GNOME/gtk/-/issues/3981
Comment 5 Alexandr Miloslavskiy CLA 2021-06-11 15:39:37 EDT
GTK received a fix for this bug.
Comment 6 Simeon Andreev CLA 2021-06-11 17:04:27 EDT
(In reply to Alexandr Miloslavskiy from comment #5)
> GTK received a fix for this bug.

Alexander, did you test the fix? I tried cherry-picking and compiling (as well as adding prints to ensure I use the compiled code). I still see the same memory leak (both with the GTK+ snippet and with SWT) reported by jemalloc.
Comment 7 Alexandr Miloslavskiy CLA 2021-06-11 17:13:59 EDT
No, I didn't test it. Do you also see the leak with the GTK snippet I posted in the bug?
Comment 8 Simeon Andreev CLA 2021-06-11 17:24:01 EDT
(In reply to Alexandr Miloslavskiy from comment #7)
> No, I didn't test it. Do you also see the leak with the GTK snippet I posted
> in the bug?

I'll try next week, checked only with the snippets from this ticket (the GTK+ one is listed on the RHEL bugzilla ticket).
Comment 9 Alexandr Miloslavskiy CLA 2021-06-11 17:36:43 EDT
Is it possible that you're confusing two bugs? You only mentioned RHEL ticket on the other one.

Sure, I'll wait for your results. I also have a lot to do :)
Comment 10 Simeon Andreev CLA 2021-06-15 02:52:25 EDT
(In reply to Alexandr Miloslavskiy from comment #9)
> Is it possible that you're confusing two bugs? You only mentioned RHEL
> ticket on the other one.
> 
> Sure, I'll wait for your results. I also have a lot to do :)

Yes, I still see the leaks reported by jemalloc with the proposed fix, when I use the snippet from: https://gitlab.gnome.org/GNOME/gtk/-/issues/3981

I have opened tickets at RHEL for the problem:

RHEL bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1965195
RHEL support case: https://access.redhat.com/support/cases/#/case/02950850

Sorry for not mentioning this earlier.
Comment 11 Alexandr Miloslavskiy CLA 2021-06-15 05:32:44 EDT
I have tested it myself and the fix seems to work.

Simeon, I think that you only cherry-picked one commit, but two commits are necessary to fix the leak.

I suggest that you build GTK from 'gtk-3-24' branch, where the fix is already merged via 90e8d7ff.
Comment 12 Simeon Andreev CLA 2021-06-15 05:52:59 EDT
I've cherry-picked 2 commits:

commit 27b3a31dcf66ef7e810945d9aba9dfd8cca017dc (HEAD -> gtk-3-22-jep2587)
Author: Matthias Clasen <mclasen@redhat.com>
Date:   Fri Jun 11 08:53:46 2021 -0400

    a11y: Fix ref counting in tree views
    
    GtkContainerCellAccessible wasn't unsetting accessible
    parents. Fix that.
    
    By itself, this doesn't help for freeing a memory leak,
    since AtkObject keeps a ref on its parent, so we never
    free the GtkContainerCellAccessible as long as it has children.

commit d023ec31aa3e2b01f12ad1b30c27694619884053
Author: Matthias Clasen <mclasen@redhat.com>
Date:   Fri Jun 11 08:55:48 2021 -0400

    a11y: Plug a memory leak with treeviews                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                               
    We need to explicitly remove the children from                                                                                                                                                                                                                             
    a GtkContainerCellAccessible, since they otherwise                                                                                                                                                                                                                         
    keep the parent alive.                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                               
    Fixes: #3981                                                                                                                                                                                                                                                               

RHEL 7 is on GTK 3.22.30. I doubt we will update our R&D workstations to GTK 3.24.x, as long as our RHEL version doesn't use that GTK version.
Comment 13 Alexandr Miloslavskiy CLA 2021-06-15 05:59:43 EDT
I imagine that even if we managed to backport the GTK patches, this still won't help you, because you won't be installing patched GTK to all workstations?
Comment 14 Simeon Andreev CLA 2021-06-15 06:12:15 EDT
(In reply to Alexandr Miloslavskiy from comment #13)
> I imagine that even if we managed to backport the GTK patches, this still
> won't help you, because you won't be installing patched GTK to all
> workstations?

We (me & Andrey) expect RHEL support to backport (working) fixes to GTK 3.22.x. After that GTK version is available from RHEL, we'll update to it.
Comment 15 Alexandr Miloslavskiy CLA 2021-06-15 06:15:24 EDT
I see.
		
The patch seems to solve the problem in 3.24.

Backporting it to 3.22 is something my boss won't approve, so unfortunately I can't help with that.
Comment 16 Simeon Andreev CLA 2021-06-16 04:21:59 EDT
OK, I was prompted on the RHEL bugzilla ticket to double check. Likely I missed a "make clean" when checking the fix, as I don't see the leaks any more. So the fix should be working also for GTK 3.22.x.
Comment 17 Alexandr Miloslavskiy CLA 2021-06-16 04:39:53 EDT
Perfect!

Then I think this issue can be considered as RESOLVED NOT_ECLIPSE?

I don't think that SWT can reasonably work around this GTK problem, because the memory to be freed is buried in internals.
Comment 18 Simeon Andreev CLA 2021-06-16 07:25:50 EDT
The memory leak is in GTK3, see: https://gitlab.gnome.org/GNOME/gtk/-/issues/3981
Comment 19 Simeon Andreev CLA 2021-06-16 07:26:37 EDT
Thanks for the help Alexander!