Crash in getenv in gdbus thread during startup due to setenv on main thread
Affected version
I'm using gnome-shell 45-beta1 on Arch Linux from fcgu. Also, I'm running on X11 using the nvidia drivers (nvidia package on arch) and have 2 monitors.
Bug summary
I started gnome-shell and it crashed. Looking at the core dump, this seems very similar to this bug on launchpad.
Steps to reproduce
- Start gnome shell
- The bug will probably not happen
- Repeat until you get (un)lucky
I'm pretty sure this is a heisenbug, because I can't reproduce it for the life of me.
What happened
gnome-shell crashed.
What did you expect to happen
I expected gnome-shell not to crash.
Relevant logs, screenshots, screencasts etc.
(gdb) info threads
Id Target Id Frame
* 1 Thread 0x7f8cc77fe6c0 (LWP 1504) __GI_getenv (name=name@entry=0x7f8cd3d9fc97 "LANGUAGE") at getenv.c:31
2 Thread 0x7f8cc7fff6c0 (LWP 1503) 0x00007f8cd3d0359f in __GI___poll (fds=0x55b861d17690, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
3 Thread 0x7f8ccf7a2d80 (LWP 1500) futex_wait (private=0, expected=2, futex_word=0x55b861cfc150) at ../sysdeps/nptl/futex-internal.h:146
4 Thread 0x7f8ccd3ff6c0 (LWP 1502) syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
Thread 1 backtrace (the offending thread)
#0 __GI_getenv (name=name@entry=0x7f8cd3d9fc97 "LANGUAGE") at getenv.c:31
#1 0x00007f8cd3c386e2 in guess_category_value (categoryname=0x7f8cd3d85493 <_nl_category_names+51> "LC_MESSAGES", category=5) at dcigettext.c:1569
#2 __dcigettext (domainname=domainname@entry=0x7f8cd47f61be "glib20", msgid1=msgid1@entry=0x7f8cd498dbff "UNIX socket path", msgid2=msgid2@entry=0x0, plural=plural@entry=0, n=n@entry=0, category=category@entry=5) at dcigettext.c:647
#3 0x00007f8cd3c37793 in __GI___dcgettext (domainname=domainname@entry=0x7f8cd47f61be "glib20", msgid=msgid@entry=0x7f8cd498dbff "UNIX socket path", category=category@entry=5) at dcgettext.c:47
#4 0x00007f8cd471bb95 in g_dgettext (domain=domain@entry=0x7f8cd47f61be "glib20", msgid=msgid@entry=0x7f8cd498dbff "UNIX socket path") at ../glib/glib/ggettext.c:404
#5 0x00007f8cd471bbce in glib_gettext (str=str@entry=0x7f8cd498dbff "UNIX socket path") at ../glib/glib/ggettext.c:133
#6 0x00007f8cd48e63fd in g_unix_socket_address_class_init (klass=0x7f8cb8001000) at ../glib/gio/gunixsocketaddress.c:278
#7 g_unix_socket_address_class_intern_init (klass=0x7f8cb8001000) at ../glib/gio/gunixsocketaddress.c:94
#8 0x00007f8cd4d7ecef in type_class_init_Wm (pclass=<optimized out>, node=0x7f8cb8000ec0) at ../glib/gobject/gtype.c:2365
#9 g_type_class_ref (type=<optimized out>) at ../glib/gobject/gtype.c:3080
#10 0x00007f8cd4d6716c in g_object_new_valist (object_type=Python Exception <class 'TypeError'>: can only concatenate str (not "NoneType") to str
, first_property_name=0x7f8cd498fd80 "path", var_args=var_args@entry=0x7f8cc77fc500) at ../glib/gobject/gobject.c:2516
#11 0x00007f8cd4d6729e in g_object_new (object_type=<optimized out>, first_property_name=<optimized out>) at ../glib/gobject/gobject.c:2057
#12 0x00007f8cd49223a1 in g_dbus_address_connect
(error=0x7f8cc77fc690, cancellable=0x55b861d15fb0, key_value_pairs=0x7f8cb8000bd0 = {...}, transport_name=0x55b861d223c0 "unix", address_entry=0x7f8cb8000ba0 "unix:path=/run/user/1000/bus") at ../glib/gio/gdbusaddress.c:596
#13 g_dbus_address_try_connect_one (address_entry=0x7f8cb8000ba0 "unix:path=/run/user/1000/bus", out_guid=out_guid@entry=0x0, cancellable=cancellable@entry=0x55b861d15fb0, error=error@entry=0x7f8cc77fc690)
at ../glib/gio/gdbusaddress.c:807
#14 0x00007f8cd492297d in g_dbus_address_get_stream_sync (address=<optimized out>, out_guid=0x0, cancellable=0x55b861d15fb0, error=0x55b861d22528) at ../glib/gio/gdbusaddress.c:998
#15 0x00007f8cd492cef7 in initable_init (initable=0x55b861d224c0, cancellable=0x55b861d15fb0, error=0x7f8cc77fc7e0) at ../glib/gio/gdbusconnection.c:2542
#16 0x00007f8cd4869703 in async_init_thread (task=0x55b861d22d50, source_object=<optimized out>, task_data=<optimized out>, cancellable=<optimized out>) at ../glib/gio/gasyncinitable.c:263
#17 0x00007f8cd48d4d68 in g_task_thread_pool_thread (thread_data=0x55b861d22d50, pool_data=<optimized out>) at ../glib/gio/gtask.c:1593
#18 0x00007f8cd4769453 in g_thread_pool_thread_proxy (data=<optimized out>) at ../glib/glib/gthreadpool.c:350
#19 0x00007f8cd4766965 in g_thread_proxy (data=0x7f8cc8000b90) at ../glib/glib/gthread.c:831
#20 0x00007f8cd3c8c9eb in start_thread (arg=<optimized out>) at pthread_create.c:444
#21 0x00007f8cd3d10dfc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Thread 2 backtrace
#0 0x00007f8cd3d0359f in __GI___poll (fds=0x55b861d17690, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
#1 0x00007f8cd47931d6 in g_main_context_poll_unlocked (priority=2147483647, n_fds=1, fds=0x55b861d17690, timeout=<optimized out>, context=0x55b861d17400) at ../glib/glib/gmain.c:4653
#2 g_main_context_iterate_unlocked.isra.0 (context=context@entry=0x55b861d17400, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/glib/gmain.c:4344
#3 0x00007f8cd47330d2 in g_main_context_iteration (context=0x55b861d17400, may_block=may_block@entry=1) at ../glib/glib/gmain.c:4414
#4 0x00007f8cd4733122 in glib_worker_main (data=<optimized out>) at ../glib/glib/gmain.c:6574
#5 0x00007f8cd4766965 in g_thread_proxy (data=0x55b861d17630) at ../glib/glib/gthread.c:831
#6 0x00007f8cd3c8c9eb in start_thread (arg=<optimized out>) at pthread_create.c:444
#7 0x00007f8cd3d10dfc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Thread 3 backtrace
#0 futex_wait (private=0, expected=2, futex_word=0x55b861cfc150) at ../sysdeps/nptl/futex-internal.h:146
#1 __GI___lll_lock_wait (futex=futex@entry=0x55b861cfc150, private=0) at lowlevellock.c:49
#2 0x00007f8cd3c8ff1a in lll_mutex_lock_optimized (mutex=0x55b861cfc150) at pthread_mutex_lock.c:48
#3 ___pthread_mutex_lock (mutex=0x55b861cfc150) at pthread_mutex_lock.c:128
#4 0x00007f8cd478e539 in g_rec_mutex_lock (mutex=mutex@entry=0x7f8cd4da1bf0 <class_init_rec_mutex>) at ../glib/glib/gthread-posix.c:397
#5 0x00007f8cd4d7e8c5 in g_type_class_ref (type=<optimized out>) at ../glib/gobject/gtype.c:3068
#6 0x00007f8cd4d6716c in g_object_new_valist (object_type=0x55b861d23720 [None], first_property_name=first_property_name@entry=0x55b8619cb162 "session-mode", var_args=var_args@entry=0x7ffd16a296c0) at ../glib/gobject/gobject.c:2516
#7 0x00007f8cd4a28ecd in _shell_global_init (first_property_name=first_property_name@entry=0x55b8619cb162 "session-mode") at ../gnome-shell/src/shell-global.c:733
#8 0x000055b8619c92ae in main (argc=<optimized out>, argv=<optimized out>) at ../gnome-shell/src/main.c:668
Thread 4 backtrace
#0 syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1 0x00007f8cd478e217 in g_cond_wait (cond=0x55b861d0eb28, mutex=0x55b861d0eb20) at ../glib/glib/gthread-posix.c:1552
#2 0x00007f8cd47001b4 in g_async_queue_pop_intern_unlocked (queue=0x55b861d0eb20, wait=1, end_time=-1) at ../glib/glib/gasyncqueue.c:425
#3 0x00007f8cd47689fe in g_thread_pool_spawn_thread (data=<optimized out>) at ../glib/glib/gthreadpool.c:311
#4 0x00007f8cd4766965 in g_thread_proxy (data=0x55b861d172b0) at ../glib/glib/gthread.c:831
#5 0x00007f8cd3c8c9eb in start_thread (arg=<optimized out>) at pthread_create.c:444
#6 0x00007f8cd3d10dfc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Inspecting getenv()
on thread 1, I can see that:
(gdb) thread 1
[Switching to thread 1 (Thread 0x7f8cc77fe6c0 (LWP 1504))]
#0 __GI_getenv (name=name@entry=0x7f8cd3d9fc97 "LANGUAGE") at getenv.c:31
31 if (name[0] == (*ep)[0]
(gdb) l
26 return NULL;
27
28 size_t len = strlen (name);
29 for (char **ep = __environ; *ep != NULL; ++ep)
30 {
31 if (name[0] == (*ep)[0]
32 && strncmp (name, *ep, len) == 0 && (*ep)[len] == '=')
33 return *ep + len + 1;
34 }
35
(gdb) p __environ
$8 = (char **) 0x55b861d23490
(gdb) p ep
$9 = (char **) 0x55b861d23218
So ep
is before __environ
? I can only interpret that as a race condition with some call to setenv()
or a similar function somewhere, somehow. A quick search reveals some calls to g_setenv, but I'll leave it at this for now, I've already spent too long on this.