~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/xfree86/doc/devel/DebuggingHints

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
                        Xserver Debugging
 
3
                        =================
 
4
 
 
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.
 
9
 
 
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:
 
13
 
 
14
         www.dawa.demon.co.uk/xfree-gdb
 
15
 
 
16
This web-site also contains the patches to gdb 4.18 so you may port it
 
17
to other platforms.
 
18
 
 
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.
 
24
 
 
25
If no module aware gdb is available the following hints might help:
 
26
 
 
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
 
36
         
 
37
   gdb> handle SIGUSR1 nostop
 
38
 
 
39
   gdb waits  for you to continue  the program which  cannot happen as
 
40
   you don't have access to gdb's console.
 
41
 
 
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:
 
45
            
 
46
   # rm <file>.o
 
47
   # xc/config/util/makeg.sh <file>.o
 
48
 
 
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.
 
53
 
 
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:
 
56
    
 
57
   # make <file>.s
 
58
   
 
59
   or 
 
60
 
 
61
   # xc/config/util/makeg.sh <file>.s
 
62
 
 
63
   Make will use exactly the same rules it uses for building *.o files.
 
64
 
 
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
 
68
 
 
69
   xf86Break1(), xf86Break2() and xf86Break3()
 
70
 
 
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.
 
75
 
 
76
5. Without module support gdb is  not able to print the function where
 
77
   an error occurred in a module.
 
78
 
 
79
     If you get a line like:
 
80
 
 
81
   (gdb) bt
 
82
   #0  0x823b4f5 in ?? ()
 
83
   ....
 
84
 
 
85
   You may obtain the function the address belongs to by calling 
 
86
   LoaderPrintSymbol():
 
87
 
 
88
   (gdb) call LoaderPrintSymbol(0x823b4f5)
 
89
 
 
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:
 
95
 
 
96
   # objdump --disassemble <file>.o
 
97
 
 
98
   <file>.o is the name of the object file containing the symbol printed.
 
99
 
 
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
 
104
   
 
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:
 
109
 
 
110
   create a file 1-<name>.c in tmp/
 
111
   containing:
 
112
   void Dummy-<name>() {}
 
113
    
 
114
   Compile it:
 
115
 
 
116
   # gcc -c 1-<name>.c
 
117
 
 
118
   and do the link step above.
 
119
 
 
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
 
123
   this static one.
 
124
 
 
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
 
127
   object file and do
 
128
 
 
129
   # makeg
 
130
 
 
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.
 
139
 
 
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:
 
142
 
 
143
   CARD32 xf86DummyVar1;
 
144
   CARD32 xf86DummyVar2;
 
145
   CARD32 xf86DummyVar3;
 
146
 
 
147
   The variable can  be assigned to one of them. One  can then use gdb
 
148
   to return the value of this variable:
 
149
 
 
150
   gdb> p /x xf86DummyVar1
 
151
 
 
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
 
154
   by doing:
 
155
 
 
156
   make <filename>.i
 
157
 
 
158
   This will generate a preprocessed source in <filename>.i.
 
159
 
 
160
10. xfree() can catch  if one tries to free a  memory range twice. You
 
161
    will get the message:
 
162
 
 
163
       Xalloc error: range already freed in Xrealloc() :-(
 
164
 
 
165
  To  find  the  location  from  which  xfree()  was  called  one  can
 
166
  breakpoint on XfreeTrap(). The backtrace should show the origin of the
 
167
  call this call. 
 
168
 
 
169
11. To access mapped physical  memory the following functions might be
 
170
    useful.  
 
171
 
 
172
    These may be used to  access physical memory that was mapped using
 
173
    the flags VIDMEM_FRAMEBUFFER or VIDMEM_MMIO32:
 
174
 
 
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);
 
181
 
 
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.
 
185
 
 
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);
 
192