Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash: g_variant_serialised_n_children: code should not be reached #894

Closed
autarkper opened this issue Jul 10, 2012 · 19 comments
Closed

Crash: g_variant_serialised_n_children: code should not be reached #894

autarkper opened this issue Jul 10, 2012 · 19 comments

Comments

@autarkper
Copy link
Contributor

I'm suffering quite badly from Cinnamon (current master) crashing a lot. One of the surest ways to produce a crash is to open and close Expo a few times, but sometimes just moving the mouse pointer down to the panel can trigger a crash. Whenever this happens, the following is printed to the console:

GLib:ERROR:/build/buildd/glib2.0-2.32.3/./glib/gvariant-serialiser.c:1320:g_variant_serialised_n_children: code should not be reached

One strange thing is that just before the crash, the following is output to the looking-glass log:

debug t=[current time] loading default theme

Now, why would opening or closing Expo trigger a theme change?

See also: #785, which I opened when I thought the problem was related to Expo.

@pmarcelll
Copy link

Hi, I have another way to trigger this bug: change the name of "Menu" in Cinnamon Settings by holding down any character button, you can see the letters slowly appearing (it does it on my system). While the Menu word is still "growing", click it. I saw this bug on github and checked the log with cinnamon --replace, same "serialised_n_children" bug.

@autarkper
Copy link
Contributor Author

@pmarcelll: Great catch!

Now that we have a sure way to trigger the crash, it should be easy to get a stack dump. Could somebody please instruct me on how to build a debug-enabled Cinnamon?

@glebihan
Copy link
Member

@autarkper : To get a stack trace for cinnamon, you can use gdb by following the instructions given there : https://live.gnome.org/GettingTraces/Details

Basically, what you need to do is switch to tty (or at least a different display) and run :

DISPLAY=:0 gdb --args cinnamon --replace

(adapt the value of DISPLAY to the correct one if needed)
then when the gdb prompt comes up, type :

run

Once the crash has occured, typing :

thread apply all bt

will show you the stack trace.

I managed to trigger the crash and get a stack trace here, using the method suggested by @pmarcelll (Thanks !). I haven't had time to look closely into it, but it seems to be related to gsettings. So here is it :

[New Thread 0x7fffc1328700 (LWP 15166)]
[Thread 0x7fffc1328700 (LWP 15166) exited]
**
GLib:ERROR:/build/buildd/glib2.0-2.33.3/./glib/gvariant-serialiser.c:1320:g_variant_serialised_n_children: code should not be reached

Program received signal SIGABRT, Aborted.
0x00007ffff61e2445 in raise () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) thread apply all bt

Thread 8 (Thread 0x7fffd5a98700 (LWP 15153)):
#0 0x00007ffff65750fe in pthread_cond_timedwait@@GLIBC_2.3.2 ()
from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x00007ffff6809fe5 in g_cond_wait_until ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2 0x00007ffff67a4391 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3 0x00007ffff67a49da in g_async_queue_timeout_pop ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4 0x00007ffff67f1022 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5 0x00007ffff67f0865 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#6 0x00007ffff6570e9a in start_thread ()
from /lib/x86_64-linux-gnu/libpthread.so.0
#7 0x00007ffff629e4bd in clone () from /lib/x86_64-linux-gnu/libc.so.6
#8 0x0000000000000000 in ?? ()

Thread 7 (Thread 0x7fffe1070700 (LWP 15150)):
#0 0x00007ffff6574d84 in pthread_cond_wait@@GLIBC_2.3.2 ()
from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x00007fffee209940 in PR_WaitCondVar ()
from /usr/lib/x86_64-linux-gnu/libnspr4.so
#2 0x00007ffff56153f7 in ?? () from /usr/lib/libmozjs185.so.1.0
#3 0x00007fffee20f103 in ?? () from /usr/lib/x86_64-linux-gnu/libnspr4.so
---Type to continue, or q to quit---
#4 0x00007ffff6570e9a in start_thread ()
from /lib/x86_64-linux-gnu/libpthread.so.0
#5 0x00007ffff629e4bd in clone () from /lib/x86_64-linux-gnu/libc.so.6
#6 0x0000000000000000 in ?? ()

Thread 6 (Thread 0x7fffe1871700 (LWP 15149)):
#0 0x00007ffff6292b03 in poll () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff0569b9f in ?? () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#2 0x00007ffff055b0f5 in pa_mainloop_poll ()
from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#3 0x00007ffff055b759 in pa_mainloop_iterate ()
from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#4 0x00007ffff055b810 in pa_mainloop_run ()
from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#5 0x00007ffff0569b4f in ?? () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#6 0x00007fffe9707663 in ?? ()
from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-2.0.so
#7 0x00007ffff6570e9a in start_thread ()
from /lib/x86_64-linux-gnu/libpthread.so.0
#8 0x00007ffff629e4bd in clone () from /lib/x86_64-linux-gnu/libc.so.6
#9 0x0000000000000000 in ?? ()

Thread 5 (Thread 0x7fffe2072700 (LWP 15146)):
---Type to continue, or q to quit---
#0 0x00007ffff6292b03 in poll () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff67cdb84 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2 0x00007ffff67cdfe2 in g_main_loop_run ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3 0x00007ffff13c8886 in ?? () from /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#4 0x00007ffff67f0865 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5 0x00007ffff6570e9a in start_thread ()
from /lib/x86_64-linux-gnu/libpthread.so.0
#6 0x00007ffff629e4bd in clone () from /lib/x86_64-linux-gnu/libc.so.6
#7 0x0000000000000000 in ?? ()

Thread 4 (Thread 0x7fffe2a7a700 (LWP 15143)):
#0 0x00007ffff6292b03 in poll () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff67cdb84 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2 0x00007ffff67cdfe2 in g_main_loop_run ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3 0x00007fffe2a7fb7b in ?? ()
from /usr/lib/x86_64-linux-gnu/gio/modules/libdconfsettings.so
#4 0x00007ffff67f0865 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5 0x00007ffff6570e9a in start_thread ()
from /lib/x86_64-linux-gnu/libpthread.so.0
#6 0x00007ffff629e4bd in clone () from /lib/x86_64-linux-gnu/libc.so.6
#7 0x0000000000000000 in ?? ()
---Type to continue, or q to quit---

Thread 3 (Thread 0x7fffe3583700 (LWP 15141)):
#0 0x00007ffff6574d84 in pthread_cond_wait@@GLIBC_2.3.2 ()
from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x00007fffe5aa1363 in ?? () from /usr/lib/x86_64-linux-gnu/dri/r600_dri.so
#2 0x00007ffff6570e9a in start_thread ()
from /lib/x86_64-linux-gnu/libpthread.so.0
#3 0x00007ffff629e4bd in clone () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x0000000000000000 in ?? ()

Thread 1 (Thread 0x7ffff7f979c0 (LWP 15133)):
#0 0x00007ffff61e2445 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff61e5bab in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff67eed97 in g_assertion_message ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3 0x00007ffff680542d in g_variant_serialised_n_children ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4 0x00007ffff68018ce in g_variant_n_children ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5 0x00007ffff67fde48 in g_variant_iter_init ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#6 0x00007ffff67fde9d in g_variant_iter_new ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
---Type to continue, or q to quit---
#7 0x00007ffff13a40d2 in ?? () from /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#8 0x00007ffff13a42fc in ?? () from /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#9 0x00007ffff13a7832 in g_settings_get_value ()
from /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#10 0x00007ffff78cb5c3 in ?? () from /usr/lib/libmuffin.so.0
#11 0x00007ffff6a8df57 in g_cclosure_marshal_VOID__STRINGv ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#12 0x00007ffff6a8b317 in ?? ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#13 0x00007ffff6aa4ac8 in g_signal_emit_valist ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#14 0x00007ffff6aa5202 in g_signal_emit ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#15 0x00007ffff13a6401 in ?? () from /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#16 0x00007ffff58161e4 in ffi_call_unix64 () from /usr/lib/libmozjs185.so.1.0
#17 0x00007ffff5815c21 in ffi_call () from /usr/lib/libmozjs185.so.1.0
#18 0x00007ffff6a8c04b in g_cclosure_marshal_generic_va ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#19 0x00007ffff6a8b317 in ?? ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#20 0x00007ffff6aa4ac8 in g_signal_emit_valist ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#21 0x00007ffff6aa5202 in g_signal_emit ()
---Type to continue, or q to quit---
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#22 0x00007ffff13a6c57 in ?? () from /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#23 0x00007ffff13a2aea in ?? () from /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#24 0x00007ffff67cd8b5 in g_main_context_dispatch ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#25 0x00007ffff67cdbe8 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#26 0x00007ffff67cdfe2 in g_main_loop_run ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#27 0x00007ffff78c9807 in meta_run () from /usr/lib/libmuffin.so.0
#28 0x0000000000401a6b in main (argc=1, argv=0x7fffffffead8) at main.c:342

@glebihan
Copy link
Member

@autarkper : BTW, we already had such an issue with gsettings, which apparently doesn't like us to get or set the value of settings too often. There was another crash that was fixed a few weeks ago that caused by the fact that we did write the value of a setting every time we opened/closed the expo.
It's possible we missed something and there's another similar issue.

The issue with changing the menu label seems to also very likely be the same issue (as we do change the value of an entry in gsettings for each letter).

@mtwebster
Copy link
Member

Maybe we should add an 'apply' button for the settings app?

@glebihan
Copy link
Member

@mtwebster : that would be on way of handling it. Another one would be to change the event on which we submit the change from "changed" to "focus-out-event"

@autarkper
Copy link
Contributor Author

@glebihan, @mtwebster : Thanks for your input!

Re the stack trace, the interesting thread is the last one, unless there is a thread collision somewhere (which seems unlikely, since the other threads are all in a wait state). It would be interesting to know what is happening at frame #10; what value is muffin trying to get?

#9 0x00007ffff13a7832 in g_settings_get_value () from /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#10 0x00007ffff78cb5c3 in ?? () from /usr/lib/libmuffin.so.0
#11 0x00007ffff6a8df57 in g_cclosure_marshal_VOID_STRINGv ()

@autarkper
Copy link
Contributor Author

I have built a debug version of muffin and tried running cinnamon in a debugger (in tty1), as suggested by @glebihan. However, after a few seconds it crashes:

$ DISPLAY=:0 gdb --args cinnamon --replace
...
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff2d79b05 in cogl_texture_set_region_from_bitmap_EXP () from /usr/lib/x86_64-linux-gnu/libcogl.so.9

As a matter of fact I can't run "DISPLAY=:0 cinnamon --replace" from tty1 either!

Update: I have worked around the debugging problem by running a batched debugging session from within a terminal window. But I'm still not getting a function name for stack frame #10.

@mtwebster
Copy link
Member

I was thinking more on the settings issue - would it be totally redundant to have a global settings 'cache' exist in cinnamon?

Sort of a high level layer that the rest of Cinnamon accesses to read and write settings, then this layer, in a more orderly fashion, writes changes to gsettings directly.

i.e.

XX Applet wants the setting 'menu-activate-on-hover', it calls:

CinnamonSettings,get_boolean('menu-activate-on-hover')

CinnamonSettings checks its cache (an array of key: value properties) - if it's in the cache, it returns the value immediately. If no, it goes to gsettings and gets the value, stores it in its cache, and returns the value.

XX Applet then wants to change that value:

CinnamonSettings.set_boolean('menu-activate-on-hover', true)

CinnamonSettings immediately changes its cached value, then queues up the change for gsettings. On its next 'write pulse,' it writes the new value to gsettings.

It could also handle signaling for setting changes, so all connections to settings goes through CinnamonSettings, which chains on down to gsettings.

This would require code changes wherever settings are currently accessed and written, but would keep gsettings from getting over-used and possibly causing this crashy behavior? The additional advantage would be speed - any subsequent access of a particular setting after the first time would be quick.

Just an idea that popped in my head, like I said, may be redundant and unnecessarily complicate things.

@autarkper
Copy link
Contributor Author

Oh, I see that the sole instance of muffin calling g_settings_get_value directly is in prefs.c.

@autarkper
Copy link
Contributor Author

I feel I'm getting closer.

I put a log statement inside muffin's settings_changed function. Here is the output from when I use the menu-settings trick to trigger a crash:

68  Window manager warning: key: attach-modal-dialogs
69  Window manager warning: key: button-layout
70  Window manager warning: key: edge-tiling
71  Window manager warning: key: workspaces-only-on-primary
72  Window manager warning: key: attach-modal-dialogs
73  Window manager warning: key: draggable-border-width
74  Window manager warning: key: dynamic-workspaces
75  Window manager warning: key: edge-tiling
76  Window manager warning: key: keybindings/
77  **
78  GLib:ERROR:/build/buildd/glib2.0-2.32.3/./glib/gvariant-serialiser.c:1320:g_variant_serialised_n_children: code should not be reached

So, the key that triggers the crash appears to be "keybindings/".

@autarkper
Copy link
Contributor Author

By returning immediately when the key is "keybinding/" I can get a little further before crashing:

236 Window manager warning: key: attach-modal-dialogs
237 Window manager warning: key: button-layout
238 Window manager warning: key: edge-tiling
239 Window manager warning: key: workspaces-only-on-primary
240 Window manager warning: key: attach-modal-dialogs
241 Window manager warning: key: draggable-border-width
242 Window manager warning: key: dynamic-workspaces
243 Window manager warning: key: edge-tiling
244 Window manager warning: key: keybindings/
245 Window manager warning: bailing out: keybindings/
246 Window manager warning: key: live-hidden-windows
247 Window manager warning: key: no-tab-popup
248 Window manager warning: key: overlay-key
249 Window manager warning: key: workspaces-only-on-primary
271 JS ERROR: !!! Exception was: Error: disconnect() takes one arg, the signal handler id
272 JS ERROR: !!! lineNumber = '0'
273 JS ERROR: !!! fileName = '"gjs_throw"'
274 JS ERROR: !!! stack = '"("disconnect() takes one arg, the signal handler id")@gjs_throw:0
275 ([object _private_Gio_Settings],"activate-menu-applet-on-hover")@/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js:513
276 "'
277 JS ERROR: !!! message = '"disconnect() takes one arg, the signal handler id"'

I'm going to fix the error in the menu applet and see what happens.

@autarkper
Copy link
Contributor Author

Sorry, didn't mean to close the issue!

Yes, fixing the JS error, made cinnamon survive! But still, I wish somebody could figure out why there is what appears to a global refresh of all settings all of a sudden.

@autarkper autarkper reopened this Jul 11, 2012
@autarkper
Copy link
Contributor Author

I have been playing with gsettings_delay, http://developer.gnome.org/gio/2.28/GSettings.html#g-settings-delay, attempting to cut down on the disk access that occurs whenever a setting is changed, the idea being to have an idle task periodically calling gsettings_apply, but that does not seem to have any effect, neither on the disk access pattern nor on the occurrence of the global settings refresh phenomenon.

@autarkper
Copy link
Contributor Author

I'm wondering whether the problem lies not in gsettings but in the backend it uses. I'm not getting these crashes with the "memory" backend, but that backend has a lot of other drawbacks.

@AlbertJP
Copy link
Contributor

It also happens when clicking a favourite in the menu that has only just been added. The mouse hover over such a favourite does not work either.

@autarkper
Copy link
Contributor Author

Sorry to be spamming you on this issue, but I have found the cause of the crash: the panel-launchers applet gets over-excited every time there is a settings update and reloads itself inside the handler function. The fix is easy: offload the reload to a timer event and return immediately.

@autarkper
Copy link
Contributor Author

While waiting for either a quick fix or a thorough rewrite of the panel-launchers applet, you can just remove it from the panel for the time being.

@autarkper
Copy link
Contributor Author

commit 2982a15 works around the issue in a more thorough way that #932.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants