qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] linux-user,bsd-user: re-exec with G_SLICE=always-malloc


From: Daniel P . Berrangé
Subject: Re: [PATCH] linux-user,bsd-user: re-exec with G_SLICE=always-malloc
Date: Thu, 6 Oct 2022 19:12:56 +0100
User-agent: Mutt/2.2.7 (2022-08-07)

On Tue, Oct 04, 2022 at 07:59:18AM -0700, Richard Henderson wrote:
> On 10/4/22 05:00, Daniel P. Berrangé wrote:
> > g_slice uses a one-time initializer to check the G_SLICE env variable
> > making it hard for QEMU to set the env before any GLib API call has
> > triggered the initializer. Even attribute((constructor)) is not
> > sufficient as QEMU has many constructors and there is no ordering
> > guarantee between them.
> 
> There are orderings for constructors, see 
> __attribute__((constructor(priority))).

Oh, thanks for pointing that out. I tried it, but glib threw 
a bag of rocks at me ;-P

The priority works for ordering within the scope of the binary
containing the constructor.

libglib.so itself has a constructor function registered, and that
calls APIs that trigger GSlice initialization:

#0  g_slice_init_nomessage () at ../glib/gslice.c:443
#1  0x00007ffff7ecbd6e in thread_memory_from_self () at ../glib/gslice.c:560
#2  thread_memory_from_self () at ../glib/gslice.c:550
#3  g_slice_alloc (mem_size=96) at ../glib/gslice.c:1050
#4  0x00007ffff7e9ca02 in g_hash_table_new_full (hash_func=0x7ffff7e91a00 
<g_str_hash>, 
    key_equal_func=0x7ffff7e91a70 <g_str_equal>, key_destroy_func=0x0, 
value_destroy_func=0x0)
    at ../glib/ghash.c:1071
#5  0x00007ffff7ebf313 in g_quark_init () at ../glib/gquark.c:61
#6  0x00007ffff7e77d79 in glib_init () at ../glib/glib-init.c:339
#7  glib_init () at ../glib/glib-init.c:328
#8  glib_init_ctor () at ../glib/glib-init.c:453
#9  0x00007ffff7fcbf7e in call_init (env=0x7fffffffdb80, argv=0x7fffffffdb68, 
argc=2, l=<optimized out>)
    at dl-init.c:70
#10 call_init (l=<optimized out>, argc=2, argv=0x7fffffffdb68, 
env=0x7fffffffdb80) at dl-init.c:26
#11 0x00007ffff7fcc06c in _dl_init (main_map=0x7ffff7ffe2a0, argc=2, 
argv=0x7fffffffdb68, env=0x7fffffffdb80)
    at dl-init.c:117
#12 0x00007ffff7fe3d4a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2


This all takes place when libglib.so is loaded, which happens prior
to any code in QEMU being loaded / executed. So no constructor in
QEMU code can ever pre-empt this in dynamic builds.


The only possible silver linining is that in static linked builds,
it appears that a QEMU constructor with priority 101, will pre-empt
the constructor from any library. This is kind of crazy, as it means
if any library or app code uses priorities, it'll get totally different
execution ordering depending on whether it is dynamic or statically
built. 

I guess we could rely on this hack if we declare that everyone using
binfmt is probably relying on static linked QEMU, and in non-binfmt
cases people can set the env var themselves.  It still feels pretty
dirty.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




reply via email to

[Prev in Thread] Current Thread [Next in Thread]