5
This file is intended to collect helpful hints on Xserver debugging.
6
I merely outline my experiences here. Somebody else might have better
7
methods on doing it. This person is therefore invited to share this
8
experience with the rest of the world by adding it here.
10
Paul Flinders has made some patches to gdb to add support for loadable
11
modules. This version of gdb is currently available as binary for
12
Linux/x86 on Paul's web site:
14
www.dawa.demon.co.uk/xfree-gdb
16
This web-site also contains the patches to gdb 4.18 so you may port it
19
It loads the module symbols and supports all gdb features like
20
breakpointing, disassembling and single stepping. It also shows the
21
exact location of a signal 11. Paul has fixed the code so that all of
22
this is working even if using modules compiled without -g. You can
23
find his latest version on his web site.
25
If no module aware gdb is available the following hints might help:
27
1. Use remote login. This can be done thru a network connection or
28
simply by connecting a serial console. This enables you to watch
29
the Xservers output while running set breakpoints with gdb etc.
30
Don't even try to run the Xserver from a system console. Whenever
31
something happens gdb waits for input. However the Xserver has
32
locked the system console including the keyboard, therefore you'll
33
never be able to send any input to gdb. Even if your process
34
doesn't crash or you haven't set any breakpoints a vt switch can be
35
hazardous: When doing vt switching a signal is sent; unless you did
37
gdb> handle SIGUSR1 nostop
39
gdb waits for you to continue the program which cannot happen as
40
you don't have access to gdb's console.
42
2. You can compile any source file with debugging symbols to obtain
43
more information about where an error occurred. Simply go to the
44
directory which holds the corresponding object file and do:
47
# xc/config/util/makeg.sh <file>.o
49
After relinking the server or module gdb is able to obtain the
50
necessary debugging information and will show the exact line in the
51
source where the error ccurred. See also:
52
xc/config/util/makeg.man.
54
3. In some cases it might be useful to have the assembler output of a
55
compiled source file. This can be obtained by doing:
61
# xc/config/util/makeg.sh <file>.s
63
Make will use exactly the same rules it uses for building *.o files.
65
4. In some cases it might be useful to set breakpoints in modules. If
66
no module aware gdb is available you should add a call to one of
67
the three dummy breakpoint functions
69
xf86Break1(), xf86Break2() and xf86Break3()
71
to the source file and recompile the module. You now just have to
72
set a breakpoint onto the appropriate dummy functions. These
73
functions are located in the core part of the server and therefore
74
will be available any time.
76
5. Without module support gdb is not able to print the function where
77
an error occurred in a module.
79
If you get a line like:
85
You may obtain the function the address belongs to by calling
88
(gdb) call LoaderPrintSymbol(0x823b4f5)
90
The symbol returned might not always be the name of the function
91
which contains the address. In case of static functions the symbol
92
is not known to the loader. However LoaderPrintSymbol() will print
93
the nearest known function and the offset from its start. You may
94
easily find the exact location of the address if you do:
96
# objdump --disassemble <file>.o
98
<file>.o is the name of the object file containing the symbol printed.
100
6. Locating static symbols in modules is simpler if the module is a
101
single object file instead of a library. Such a object file can
102
easily be build from a library: # mkdir tmp # cd tmp; ar x
103
module-path/<libname>.a # ld -r *.o -o module-path/<name>.o
105
When calling LoaderPrintSymbol() the closes public symbol will be
106
printed together with the offset from the symbol's address. If a
107
static symbol comes before the first public symbol in a module The
108
following trick may help:
110
create a file 1-<name>.c in tmp/
112
void Dummy-<name>() {}
118
and do the link step above.
120
This way Dummy-<name>() will be the first public function in the
121
module. All addresses in static function can now be printed
122
relatively to this address if no other public function comes before
125
7. In some situations it is quite helpful to add debugging symbols to
126
the binary. This can be done per object file. Simply remove the
131
When looking for a bug in a module these debugging infos can be
132
very helpful: Calling LoaderPrintSymbol() as described above will
133
return a function and an offset giving the exact location of the
134
address with respect to this function entry point. When
135
disassembling an object file with debugging symbols: # objdump -d
136
-l <file>.o one will receive a disassembled output containing line
137
number information. Thus one can locate the exact line of code
138
where the error occurred.
140
8. To quickly trace the value of a variable declared in a module three
141
dummy variables have been added to the core part:
143
CARD32 xf86DummyVar1;
144
CARD32 xf86DummyVar2;
145
CARD32 xf86DummyVar3;
147
The variable can be assigned to one of them. One can then use gdb
148
to return the value of this variable:
150
gdb> p /x xf86DummyVar1
152
9. Sometimes it might be useful to check how the preprocessor replaced
153
symbols. One can obtain a preprocessed version of the source file
158
This will generate a preprocessed source in <filename>.i.
160
10. xfree() can catch if one tries to free a memory range twice. You
161
will get the message:
163
Xalloc error: range already freed in Xrealloc() :-(
165
To find the location from which xfree() was called one can
166
breakpoint on XfreeTrap(). The backtrace should show the origin of the
169
11. To access mapped physical memory the following functions might be
172
These may be used to access physical memory that was mapped using
173
the flags VIDMEM_FRAMEBUFFER or VIDMEM_MMIO32:
175
CARD8 xf86PeekFb8(CARD8 *p);
176
CARD16 xf86PeekFb16(CARD16 *p);
177
CARD32 xf86PeekFb32(CARD32 *p);
178
void xf86PokeFb8(CARD8 *p, CARD8 v);
179
void xf86PokeFb16(CARD16 *p, CARD16 v);
180
void xf86PokeFb32(CARD16 *p, CARD32 v);
182
Physical memory which was mapped by setting VIDMEM_MMIO should be
183
accessed using the following. Here the base address to which the
184
memory is mapped and the offset are required separately.
186
CARD8 xf86PeekMmio8(pointer Base, unsigned long Offset);
187
CARD16 xf86PeekMmio16(pointer Base, unsigned long Offset);
188
CARD32 xf86PeekMmio32(pointer Base, unsigned long Offset);
189
void xf86PokeMmio8(pointer Base, unsigned long Offset, CARD8 v);
190
void xf86PokeMmio16(pointer Base, unsigned long Offset, CARD16 v);
191
void xf86PokeMmio32(pointer Base, unsigned long Offset, CARD32 v);