Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-85308

Eclipse SWT Tree leaks native memory via gtk_tree_view_expand_row()

Linking RHIVOS CVEs to...Migration: Automation ...Sync from "Extern...XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Normal Normal
    • None
    • rhel-9.4
    • gtk3
    • None
    • Moderate
    • rhel-display-desktop-foundation
    • ssg_display
    • 5
    • False
    • False
    • Hide

      None

      Show
      None
    • Yes
    • None
    • None
    • None
    • If docs needed, set a value
    • None
    • 57,005

      Description of problem:

      Eclipse SWT Tree leaks native memory via gtk_tree_view_expand_row()

      Version-Release number of selected component (if applicable):

      We observe the leak with Eclipse 4.15, Eclipse 4.20 and Eclipse 4.21, as well as latest master from SWT. We assume the leak is seen with all Eclipse versions inbetween.

      How reproducible:

      To reproduce the leak, run the following SWT snippet:

      public static void main(String[] args) {
      Display display = new Display();
      Shell shell = new Shell(display);
      shell.setText("Tree Example");
      shell.setLayout(new FillLayout());
      Tree tree = new Tree(shell, SWT.NONE);
      tree.setItemCount(2);
      TreeItem item0 = tree.getItem(0);
      item0.setText("item0");
      TreeItem item1 = tree.getItem(1);
      item1.setText("item1");
      item1.setItemCount(6);
      TreeItem[] children = item1.getItems();
      for (int k = 0; k < children.length; ++k)

      { children[k].setText("child" + k); }

      item1.setExpanded(true);
      tree.setItemCount(1);
      shell.open();
      while (!shell.isDisposed())

      { if (!display.readAndDispatch()) display.sleep(); }

      display.dispose();
      }

      jemalloc reports a memory leak as follows:

      [240 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 (??:?)
      _gtk_rbnode_new.isra.2 (/usr/src/debug/gtk+-3.22.30/gtk/gtkrbtree.c:61)
      _gtk_rbtree_insert_after (/usr/src/debug/gtk+-3.22.30/gtk/gtkrbtree.c:456)
      gtk_tree_view_build_tree (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:9570)
      gtk_tree_view_real_expand_row (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:12865)
      gtk_tree_view_expand_row (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:12920)
      Java_org_eclipse_swt_internal_gtk_GTK_gtk_1tree_1view_1expand_1row (??:?)
      ?? (??:0)

      The same leak can be reproduced with the following GTK+ snippet:

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

      #include <gtk/gtk.h>

      enum

      { COL1 = 0, NUM_COLS }

      ;

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

      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);

      GtkCellRenderer *renderer;

      view = gtk_tree_view_new ();

      renderer = gtk_cell_renderer_text_new ();
      gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "column 1", renderer, "text", COL1, NULL);

      GtkTreeStore *treestore;
      GtkTreeIter iter, child;

      treestore = gtk_tree_store_new(NUM_COLS, G_TYPE_STRING);

      gtk_tree_store_append(treestore, &iter, NULL);
      gtk_tree_store_set(treestore, &iter, COL1, "item", -1);
      gtk_tree_store_append(treestore, &iter, NULL);
      gtk_tree_store_set(treestore, &iter, COL1, "item", -1);
      GtkTreePath *path = NULL;
      path = gtk_tree_model_get_path (GTK_TREE_MODEL(treestore), &iter);

      int j;
      for (j = 0; j < 6; ++j)

      { gtk_tree_store_append(treestore, &child, &iter); gtk_tree_store_set(treestore, &child, COL1, "child", -1); }

      gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (treestore));

      if (path)

      { gtk_tree_view_expand_row(GTK_TREE_VIEW(view), path, FALSE); gtk_tree_path_free(path); }

      gtk_container_add (GTK_CONTAINER (window), scrolled_window);
      gtk_container_add (GTK_CONTAINER (scrolled_window), view);

      gtk_widget_show_all (window);

      GtkTreeIter iter1, child1;
      if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(treestore), &iter1, NULL, 1))

      { gtk_tree_store_remove(treestore, &iter1); }

      g_object_unref(treestore);

      gtk_main ();

      return 0;
      }

      jemalloc reports a memory leak as follows:

      [240 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 (??:?)
      _gtk_rbnode_new.isra.2 (/usr/src/debug/gtk+-3.22.30/gtk/gtkrbtree.c:61)
      _gtk_rbtree_insert_after (/usr/src/debug/gtk+-3.22.30/gtk/gtkrbtree.c:456)
      gtk_tree_view_build_tree (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:9570)
      gtk_tree_view_real_expand_row (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:12865)
      gtk_tree_view_expand_row (/usr/src/debug/gtk+-3.22.30/gtk/gtktreeview.c:12920)
      ?? (??:0)
      __libc_start_main (/usr/src/debug/glibc-2.17-c758a686/csu/../csu/libc-start.c:274)
      ?? (??:0)

      Actual results:

      Memory is leaked.

      Expected results:

      Memory is not leaked.

      Additional info:

      For more context (e.g. actual Eclipse user operations to run into the leak) see Eclipse bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=574065

       

      Customer comment:

      The customer is able to successfully reproduce the issue  on RHEL 9.4 which was reported on RHEL 7.9 and got closed as WONT DO:

      LINK: https://issues.redhat.com/browse/RHEL-4087
      I can reproduce the leak with the steps from the description on RHEL 9.4 (latest Advantest sysadmins can provide):

      [240 bytes leaked]
      prof_backtrace_impl (/data/jemalloc/src/prof_sys.c:106)
      je_prof_backtrace (/data/jemalloc/src/prof_sys.c:527)
      je_prof_tctx_create (/data/jemalloc/src/prof.c:231)
      je_malloc_default (/data/jemalloc/src/jemalloc.c:2800)
      g_malloc (??:?)
      g_slice_alloc (??:?)
      gtk_socket_add_id (??:?)
      gtk_socket_add_id (??:?)
      gtk_tree_view_insert_column_with_data_func (??:?)
      gtk_tree_view_expand_row (??:?)
      0x0000000000401552 (??:0)
      __libc_start_call_main (??:?)
      __libc_start_main_alias_2 (:?)
      0x0000000000401204 (??:0)

      (I didn't install debug symbols so line numbers are not available)

      To configure jemalloc:

      cd /data/
      git clone https://github.com/jemalloc/jemalloccd jemalloc
      ./autogen.sh
      ./configure --prefix=/data/jemalloc/ --enable-prof
      make

      Then compile the reproduction snippet with:

      gcc -g tree.c pkg-config --cflags --libs gtk+-3.0 -o tree

      And run it with:

      LD_PRELOAD=/data/jemalloc/lib/libjemalloc.so.2 G_SLICE=always-malloc MALLOC_CONF=prof:true,prof_leak:true,prof_final:true,lg_prof_sample:0,lg_prof_interval:-1 treeleak

      Parse the resulting jeprof heap file with this script:

      https://github.com/SyntevoAlex/JavaJemallocScripts/blob/main/ParseHeapFile.sh

       

      Please let me know in case you need any further information/data.

              mclasen@redhat.com Matthias Clasen
              jira-bugzilla-migration RH Bugzilla Integration
              Matthias Clasen Matthias Clasen
              Radek Duda Radek Duda
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved: