3
Cyril Brulebois <kibi@debian.org>
8
One should note that X is responsible for VT switching, meaning
9
switching between an X session and console terminals. In other words,
10
`Ctrl+Alt+Fn` is handled by X. If X is stopped, for example because
11
it’s running under `gdb`, one can no longer switch to another
12
VT. That’s why we’re recommending using a second machine to debug
13
X. Nevertheless, here are some instructions to attempt debugging X
14
with a single machine.
16
### One-machine approach
18
This is a *post-mortem* approach. The idea is to run X with the
19
`-core` option. Once it dies, a core file (`/etc/X11/core`) is
20
generated, and can be loaded from `gdb`.
24
1. Getting a core file.
25
2. Loading a core file.
26
3. Displaying/saving a backtrace.
28
### Two-machine approach
30
You pay the “need a second machine” price, but that buys you
31
interactivity. Just log into the first machine from the second one,
36
1. Attaching/Starting X from gdb.
37
2. Displaying/saving a backtrace.
41
Obviously, `gdb` is needed; `xserver-xorg-core-dbg` contains the
42
debugging symbols for the server itself. Other needed packages can be
43
determined by looking at the backtrace. **FIXME: More info about
48
### Getting a core file
50
* Using `gdm3`: The idea is to tweak the daemon’s
51
`LocalXserverCommand` setting, adding the `-core` option. As of
52
`gdm3 2.30`, the defaults can be found in
53
`/usr/share/gdm/gdm.schemas`. Sample `/etc/gdm3/daemon.conf`
57
LocalXserverCommand=/usr/bin/Xorg -br -verbose -audit 0 -novtswitch -core
59
* Using `kdm`: One should look for the `ServerArgsLocal` variable in
60
the `/etc/kde4/kdm/kdmrc` file, and add `-core` there. Example:
62
ServerArgsLocal=-br -nolisten tcp -core
64
* Using `xdm`: It’s sufficient to add `-core` to the command
65
configured through `/etc/X11/xdm/Xservers`, for example:
67
:0 local /usr/bin/X :0 vt7 -nolisten tcp -core
69
### Loading a core file
71
That’s trivial, one just needs to pass both the core file and the path
74
# gdb -c /etc/X11/core /usr/bin/Xorg
76
Now `gdb` is ready to display backtraces.
78
### Attaching X from gdb
80
The way of starting X doesn’t really matter, as `gdb` makes it
81
possible to attach a running process. If there’s a single X instance
82
running, that will do the job:
84
# gdb attach $(pidof X)
86
(gdb) handle SIGPIPE nostop
89
If there are several instances, one can use `ps aux` to determine the
90
PID of the appropriate instance (2nd column → `$pid`), and then attach
95
(gdb) handle SIGPIPE nostop
98
### Starting X from gdb
100
In case X crashes at start-up, one can start X from `gdb` in the
101
following way. In this example, the only parameter is the display, but
102
more parameters can be added.
106
(gdb) handle SIGPIPE nostop
111
`SIGPIPE` is a signal that can reach the X server quite easily,
112
especially when performing a VT switch, or refreshing large parts of
113
the screen. That’s why we ask `gdb` not to stop when such a signal is
114
caught, thanks to the `handle SIGPIPE nostop` command.
116
### How to display a backtrace?
118
Once X is crashed, for example because it received a `SIGSEGV`
119
(segmentation fault, usually because of a NULL pointer dereference),
120
or a `SIGBUS`, one gets back to the `gdb` prompt. One can then request
121
a backtrace (`bt`) or a full backtrace (`bt full`). The latter is what
122
developers are usually interested in, because variable values are also
128
### How to save a backtrace?
130
To save a recording of the gdb session to a file (`gdb.txt` by
135
To save in a different file, use this instead:
137
(gdb) set logging file my-file.txt
140
Once logging is enabled, you can request a (full) backtrace using the