Table of Contents

Debugging Xfce

Ofcourse, we all know Xfce is bugfree and stable as a rock. So there shouldn't be any reason for this howto to exist.

However, due to some (yet) unexplained cause, it can happen that an application crashes. We are not sure of the origin of these mysterious events. Some people have witnessed the presence of Rodents, maybe there is a relationship, but no-one knows for sure.

However, if these mysterious events happen, this is the way you can help the developers resolve it:

Identifying a crash

When an application crashed, it usually exits due to SIG_SEGV, a segmentation-fault. This means the operating-system has detected that the application tries to access a piece (segment) of memory that it is not allowed to. The operating-system then sends the application a signal causing an immediate abort.

When the application is started from a terminal, this can look like the following example:

stephan@hermes:~$ ristretto
Segmentation fault
stephan@hermes:~$

This message is little descriptive, so lets try to find out why it crashed.

Running the application in a debugger

To find out why the application crashed, the first thing to try is running it in a debugger. The most commonly used debugger on GNU/Linux is gdb, the GNU debugger.

To use gdb, you just start it from the command-line with the application to debug as a first argument to the application, see the following example:

stephan@hermes:~$ gdb ristretto 
GNU gdb (GDB) 7.3-debian
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/local/bin/ristretto...done.
(gdb) 

Now gdb is started, but the application itself is not doing anything yet. To start the application, type run, maybe some arguments you want to supply to the application, and press Enter.

Now, if the application does not crash immediately, you should see it start and a few lines appear in the debugger. (See the following example)

...
(gdb) run
Starting program: /usr/local/bin/ristretto 
[Thread debugging using libthread_db enabled]

Now, perform the actions required to crash the application. The next step of the debugger looks something like this:

(gdb) run
Starting program: /usr/local/bin/ristretto 
[Thread debugging using libthread_db enabled]
[New Thread 0x7fffe5780700 (LWP 26386)]

Program received signal SIGSEGV, Segmentation fault.
0x00000000004206f9 in rstto_monitor_chooser_paint (widget=0x6f1d60)
    at monitor_chooser.c:300
warning: Source file is more recent than executable.
300	                if (monitor->width > monitor->height)
(gdb) 

Ofcourse, the output-lines differ from application to application and from bug to bug, so you shouldn't be worried if it looks different.

The next step is getting a so called 'backtrace'. This backtrace traces the flow through the application that leads to this crash:

(gdb) backtrace
#0  0x00000000004206f9 in rstto_monitor_chooser_paint (widget=0x6f1d60)
    at monitor_chooser.c:300
#1  0x00000000004204b2 in rstto_monitor_chooser_expose (widget=0x6f1d60, 
    event=0x7fffffffc9b0) at monitor_chooser.c:235
#2  0x00007ffff78dc418 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#3  0x00007ffff5d1f03e in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#4  0x00007ffff5d2fced in ?? () from /usr/lib/libgobject-2.0.so.0
#5  0x00007ffff5d3944b in g_signal_emit_valist ()
   from /usr/lib/libgobject-2.0.so.0
#6  0x00007ffff5d39832 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#7  0x00007ffff79f5301 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#8  0x00007ffff78dac30 in gtk_main_do_event ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#9  0x00007ffff752db0c in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
#10 0x00007ffff752dabb in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
#11 0x00007ffff7528ad3 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
#12 0x00007ffff752ac71 in gdk_window_process_all_updates ()
   from /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
#13 0x00007ffff785e301 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#14 0x00007ffff7508286 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
#15 0x00007ffff5454edd in g_main_context_dispatch () from /lib/libglib-2.0.so.0
#16 0x00007ffff54556b8 in ?? () from /lib/libglib-2.0.so.0
#17 0x00007ffff5455cfa in g_main_loop_run () from /lib/libglib-2.0.so.0
#18 0x00007ffff786154b in gtk_dialog_run ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#19 0x0000000000421da6 in rstto_xfce_wallpaper_manager_configure_dialog_run (
    self=0x6cb620, file=0xa68b00) at xfce_wallpaper_manager.c:154
#20 0x000000000041ff76 in rstto_wallpaper_manager_configure_dialog_run (
    self=0x6cb620, file=0xa68b00) at wallpaper_manager.c:38
#21 0x000000000041d689 in cb_rstto_main_window_set_as_wallpaper (
    widget=0x80c810, window=0x66d360) at main_window.c:1890
#22 0x00007ffff5d1f03e in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#23 0x00007ffff5d2fedb in ?? () from /usr/lib/libgobject-2.0.so.0
#24 0x00007ffff5d3968a in g_signal_emit_valist ()
   from /usr/lib/libgobject-2.0.so.0
#25 0x00007ffff5d39832 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#26 0x00007ffff781a683 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#27 0x00007ffff5d1f03e in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#28 0x00007ffff5d2f665 in ?? () from /usr/lib/libgobject-2.0.so.0
#29 0x00007ffff5d3968a in g_signal_emit_valist ()
   from /usr/lib/libgobject-2.0.so.0
#30 0x00007ffff5d39832 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#31 0x00007ffff79f44fe in gtk_widget_activate ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#32 0x00007ffff78ef87d in gtk_menu_shell_activate_item ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#33 0x00007ffff5d1f03e in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#34 0x00007ffff5d2fced in ?? () from /usr/lib/libgobject-2.0.so.0
#35 0x00007ffff5d38c60 in g_signal_emitv () from /usr/lib/libgobject-2.0.so.0
#36 0x00007ffff7827d5a in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#37 0x00007ffff78282b8 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#38 0x00007ffff7828512 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#39 0x00007ffff782946a in gtk_bindings_activate_event ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#40 0x00007ffff78ee928 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#41 0x00007ffff78e54c2 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#42 0x00007ffff78dc418 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#43 0x00007ffff5d1f03e in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#44 0x00007ffff5d2fced in ?? () from /usr/lib/libgobject-2.0.so.0
#45 0x00007ffff5d3944b in g_signal_emit_valist ()
   from /usr/lib/libgobject-2.0.so.0
#46 0x00007ffff5d39832 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#47 0x00007ffff79f5301 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#48 0x00007ffff78da686 in gtk_propagate_event ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#49 0x00007ffff78da933 in gtk_main_do_event ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#50 0x00007ffff754621c in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
#51 0x00007ffff5454edd in g_main_context_dispatch () from /lib/libglib-2.0.so.0
#52 0x00007ffff54556b8 in ?? () from /lib/libglib-2.0.so.0
#53 0x00007ffff5455cfa in g_main_loop_run () from /lib/libglib-2.0.so.0
#54 0x00007ffff78d9987 in gtk_main ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#55 0x000000000042a36d in main (argc=1, argv=0x7fffffffe428) at main.c:157
(gdb)

Copy this to a text-file, and add it to a bugreport on https://bugzilla.xfce.org/

If the last line of the backtrace starts with 0x000000000000 (a NULL-pointer) then the backtrace is not of any good. The application jumped to a NULL-pointer and then wandered through memory aimlessly before finally dying. If this happens, try valgrind. – (to be continued)