After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 701694 - mem profiler is unusable after g_type_init deprecation
mem profiler is unusable after g_type_init deprecation
Status: RESOLVED WONTFIX
Product: glib
Classification: Platform
Component: gobject
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
: 705303 712295 752320 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2013-06-06 06:04 UTC by Daiki Ueno
Modified: 2015-08-02 01:43 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
valgrind log (4.10 KB, text/plain)
2013-06-06 06:05 UTC, Daiki Ueno
  Details
Sets glib_mem_profiler_table in gobject_init_ctor() (2.78 KB, patch)
2014-04-14 08:16 UTC, Dmitry Balakshin
reviewed Details | Review

Description Daiki Ueno 2013-06-06 06:04:41 UTC
I noticed that a few of IBus test cases, which has "g_mem_set_vtable (glib_mem_profiler_table)", started failing after the g_type_init deprecation.

It can be reproduced with the following simple test case:

$ cat > test.c <<EOF
#include <glib-object.h>

static void
test_alloc (void)
{
  g_object_new (G_TYPE_OBJECT, NULL);
}

gint
main (gint    argc,
      gchar **argv)
{
    g_mem_set_vtable (glib_mem_profiler_table);
    g_test_init (&argc, &argv, NULL);
    g_test_add_func ("/alloc", test_alloc);
    return g_test_run ();
}
^D

$ ./test
/alloc: *** Error in `./test': realloc(): invalid pointer: 0x000000000084ce80 ***

Looking at the valgrind output (attached), Glib seems to call profiler_try_realloc on a memory block allocated by non-profiling malloc (called from gobject_init_ctor).
Comment 1 Daiki Ueno 2013-06-06 06:05:54 UTC
Created attachment 246127 [details]
valgrind log
Comment 2 Matthias Clasen 2013-11-15 11:26:40 UTC
*** Bug 712295 has been marked as a duplicate of this bug. ***
Comment 3 Matthias Clasen 2013-11-15 11:27:27 UTC
*** Bug 705303 has been marked as a duplicate of this bug. ***
Comment 4 Reuben Thomas 2014-03-23 22:54:22 UTC
I ran into this when trying to use libgc with glib (in other words, a non-profiling use of g_mem_set_vtable).

The only idea I see for a fix so far, comment #3 of bug 705303, only works for profiling (it suggests reading GOBJECT_DEBUG in gobject_init_ctor.

It looks as though it might be possible to work around this by rewiring libc's allocator, where possible: glibc allows this via variables, so presumably the rewiring can be done statically, before gobject_init_ctor is run; however, this solution isn't portable.

(libgc has an option to override malloc, but that doesn't work on all platforms (e.g. amd64 Ubuntu!), and it doesn't help other allocators.)

While we're waiting for a fix (a way to disable gobject_init_ctor at runtime?), any other suggestions?
Comment 5 Reuben Thomas 2014-03-23 23:11:34 UTC
I guess one fix would be to use the same mechanism in glib as in glibc, i.e. the ability statically to override the allocator. However, it would also need, at least for libgc, an "init" hook, as libgc needs to be initialised before it can be called.
Comment 6 Reuben Thomas 2014-03-23 23:13:45 UTC
Or just a hook variable that disables the gobject_init_ctor magic.
Comment 7 Dmitry Balakshin 2014-04-14 08:16:18 UTC
Created attachment 274238 [details] [review]
Sets glib_mem_profiler_table in gobject_init_ctor()

There is a GOBJECT_DEBUG env variable, that is used to debug GType/GObject. I've added one more value to it - "memory", that forces to set glib_mem_profiler_table earily in gobject_init_ctor().
This solution does not allow you to set your own GMemVTable. But you'll be able to call g_mem_profile() and get memory usage summary.
Comment 8 Philip Withnall 2014-04-20 20:47:52 UTC
Review of attachment 274238 [details] [review]:

I'm not a GLib developer, but I don't think this is correct. Firstly, memory management is handled in libglib, not libgobject, so the g_mem_set_vtable() call should happen in the libglib initialiser function (g_debug_init() in glib-init.c). Secondly, this doesn't restore the original behaviour of supporting custom memory vtables.
Comment 9 Philip Withnall 2014-04-20 20:51:44 UTC
The problem is that gobject_init_ctor() is making a memory allocation somewhere, so the options are to:
 • Change it so it doesn't.
 • Force the vtable to be set up in glib_init(), as above, which only allows a fixed set of vtables to be used.
 • Require the user to call g_mem_set_vtable() from their own constructor function which is ordered to be called before glib_init().

The first option is not possible: gobject_init_ctor() is essentially g_type_init(), and we can't change the GLib type system to not perform allocations.

The second option is the approach almost taken by this patch.

The third option might work, but would require existing calls to g_mem_set_vtable() to be moved to a constructor, and would require G_DEFINE_CONSTRUCTOR() to grow support for ordering invocations of the constructor functions. From some quick research, this looks like it should be possible for all the supported platforms except perhaps SunPro C, which seems to require linker intervention to guarantee constructor/destructor ordering. This option seems fragile to me, but might be workable.

Ryan, what do you think about the possibility of enforcing constructor ordering?
Comment 10 Olivier Crête 2014-10-31 15:59:23 UTC
Another option is to just deprecate the whole g_mem_set_vtable() thing. We have valgrind now.
Comment 11 Reuben Thomas 2014-10-31 16:06:17 UTC
Valgrind is fine for debugging, but this API was also used to replace the allocator for other reasons, e.g. to use a garbage collector or use a different allocator for a specific application.
Comment 12 Alexander Larsson 2015-06-27 16:47:22 UTC
I don't think it is reasonable to make this work. We could possibly make the gobject constructor do some magic, but any other constructor which we don't control could call g_malloc too. And anyway, a full solution would need to handle other libraries calling malloc() directly. Any robust special handling of malloc must happen at the libc level.

Thus i think we should just drop the overhead of constatly going through a vtable. Patches for this are in bug 751592.
Comment 13 Ray Strode [halfline] 2015-07-04 03:03:55 UTC
fwiw, glibc even provides facilities for doing this at the libc level.

$ man 3 malloc_hook

for more details
Comment 14 Emmanuele Bassi (:ebassi) 2015-07-13 11:39:22 UTC
*** Bug 752320 has been marked as a duplicate of this bug. ***
Comment 15 Michael Catanzaro 2015-08-02 01:43:11 UTC
Since the patch in bug #751592 landed, this bug is surely WONTFIX...?