Merged in MorphOS-specific improvements from MorphOS team.
[AROS.git] / _gdbinit
blob28f0fabf93f0dda4b7195576492f1e5056161423
1 handle SIGUSR1 pass noprint nostop
2 handle SIGUSR2 pass noprint nostop
3 set follow-fork-mode child
5 define _debug_init
6     init-if-undefined $AbsExecBase = (struct ExecBase *)SysBase
8     if AbsExecBase != 0
9         set $AbsExecBase = *(struct IntExecBase **)&AbsExecBase
10         set $_debug_DebugBase = (struct DebugBase *)($AbsExecBase->DebugBase)
12         if $_debug_DebugBase != 0
13             set $_debug_ModList = $_debug_DebugBase->db_Modules
14             set $_debug_KickList = $_debug_DebugBase->db_KernelModules
15         end
16     else
17         init-if-undefined $_debug_ModList = Debug_ModList
18         init-if-undefined $_debug_KickList = Debug_KickList
19     end
20 end
21 document _debug_init
22 Initialize debugging convenience variables
23 end
25 define liblist
26     _debug_init
27     set $lib = ((struct ExecBase *)$AbsExecBase)->LibList.lh_Head
29     printf "Base     OpenC   Name\n"
30     printf "---------------------------------------------------------------\n"
31     while ($lib->ln_Succ != 0)
32     printf "%p %5d   %s\n", \
33         $lib, \
34         ((struct Library *)$lib)->lib_OpenCnt, \
35         $lib->ln_Name
36     set $lib = $lib->ln_Succ
37     end
38 end
39 document liblist
40 List the current libraries in the system
41 end
43 define devlist
44     _debug_init
45     set $dev = ((struct ExecBase *)$AbsExecBase)->DeviceList.lh_Head
46     printf "Base     OpenC   Name\n"
47     printf "---------------------------------------------------------------\n"
48     while ($dev->ln_Succ != 0)
49     printf "%p %5d   %s\n", \
50         $dev, \
51         ((struct Library *)$dev)->lib_OpenCnt, \
52         $dev->ln_Name
53     set $dev = $dev->ln_Succ
54     end
55 end
56 document devlist
57 List the current devices in the system
58 end
60 define resourcelist
61     _debug_init
62     set $res = ((struct ExecBase *)$AbsExecBase)->ResourceList.lh_Head
63     printf "Base     Name\n"
64     printf "---------------------------------------------------------------\n"
65     while ($res->ln_Succ != 0)
66     printf "%p %s\n", $res, $res->ln_Name
67     set $res = $res->ln_Succ
68     end
69 end
70 document resourcelist
71 List the current resources in the system
72 end
74 define residentlist
75     _debug_init
76     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
77     set $i = 0
79     printf "Address    Pri Flags Vers Type  Name\n"
80     printf "--------------------------------------------------------------\n"
81     while (($resp)[$i] != 0)
82     set $res = ($resp)[$i]
83     printf "%p  %4d    %02x  %3d  %3d  %s\n", \
84         $res, \
85         ((struct Resident *)$res)->rt_Pri, \
86         ((struct Resident *)$res)->rt_Flags, \
87         ((struct Resident *)$res)->rt_Version, \
88         ((struct Resident *)$res)->rt_Type, \
89         ((struct Resident *)$res)->rt_Name
90     set $i = $i + 1
91     end
92 end
93 document residentlist
94 List the system resident list
95 end
97 define taskready
98     _debug_init
99     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskReady.lh_Head
101     printf "Task     SigWait  SigRecvd StkSize   StkUsed Pri Type Name\n"
102     printf "-----------------------------------------------------------------------------\n"
103     while ($task->tc_Node.ln_Succ != 0)
104     printf "%p %p %p %8d %8d %3d  %3ld %s\n", \
105         $task, \
106         $task->tc_SigWait, \
107         $task->tc_SigRecvd, \
108         $task->tc_SPUpper - $task->tc_SPLower, \
109         $task->tc_SPUpper - $task->tc_SPReg, \
110         $task->tc_Node.ln_Pri, \
111         $task->tc_Node.ln_Type, \
112         $task->tc_Node.ln_Name
113     set $task = (struct Task *)$task->tc_Node.ln_Succ
114     end
116 document taskready
117 List of tasks currently ready to run
120 define taskwait
121     _debug_init
122     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskWait.lh_Head
124     printf "Task     SigWait  SigRecvd StkSize   StkUsed Pri Type Name\n"
125     printf "-----------------------------------------------------------------------------\n"
126     while ($task->tc_Node.ln_Succ != 0)
127     printf "%p %p %p %8d %8d %3d  %3ld %s\n", \
128         $task, \
129         $task->tc_SigWait, \
130         $task->tc_SigRecvd, \
131         $task->tc_SPUpper - $task->tc_SPLower, \
132         $task->tc_SPUpper - $task->tc_SPReg, \
133         $task->tc_Node.ln_Pri, \
134         $task->tc_Node.ln_Type, \
135         $task->tc_Node.ln_Name
136     set $task = (struct Task *)$task->tc_Node.ln_Succ
137     end
139 document taskwait
140 List of tasks currently waiting for an event
143 define thistask
144     _debug_init
145     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->ThisTask
146     printf "Task     SigWait  SigRecvd StkSize   StkUsed Pri Type Name\n"
147     printf "-----------------------------------------------------------------------------\n"
148     printf "%p %p %p %8d %8d %3d  %3ld %s\n", \
149     $task, \
150     $task->tc_SigWait, \
151     $task->tc_SigRecvd, \
152     $task->tc_SPUpper - $task->tc_SPLower, \
153     $task->tc_SPUpper - $task->tc_SPReg, \
154     $task->tc_Node.ln_Pri, \
155     $task->tc_Node.ln_Type, \
156     $task->tc_Node.ln_Name
158 document thistask
159 Print out information about the currently running task.
162 define modlist
163     _debug_init
164     printf "Segment           Module\n"
166     if $_debug_ModList
167         printf "---------------------------------------------------------------------\n"
168         set $segnode = (struct segment *)$_debug_ModList->mlh_Head
170         while ($segnode->s_node.mln_Succ != 0)
171             printf "%p %12s %2u %32s\n", $segnode->s_lowest, $segnode->s_name, $segnode->s_num, $segnode->s_mod->m_name
173             set $segnode = (struct segment *)$segnode->s_node.mln_Succ
174         end
175     end
177     printf "---------------------------------------------------------------------\n"
178     set $kicknode = $_debug_KickList
180     while ($kicknode != 0)
181         set $eh = $kicknode->eh
182         set $sh = $kicknode->sh
183         set $shnum = $eh->shnum
185         set $i = 0
186         while ($i < $shnum)
187             if ($sh->addr != 0) && ($sh->size != 0)
188         printf "%p              %2u %32s\n", $sh->addr, $i, $kicknode->Name
189         end
190         set $sh = $sh + 1
191         set $i = $i + 1
192     end
193         set $kicknode = $kicknode->Next
194     end
196 document modlist
197 List of all the modules currently loaded in memory
200 define findaddr
201     _debug_init
202     set $cont = 1
204     #first search in modules loaded from disk
205     printf "Searching in the loaded modules...\n"
206     if $_debug_ModList
207         set $segnode = (struct segment *)$_debug_ModList->mlh_Head
209         while ($segnode->s_node.mln_Succ != 0) && $cont
210         if $arg0 >= $segnode->s_lowest && $arg0 <= $segnode->s_highest
211                 printf "Address found in %s, in segment %p.\nIf this is an executable, its .text section starts at %p.\n", $segnode->s_mod->m_name, $segnode->s_seg, $segnode->s_lowest
213                 set $cont = 0
214             end
215             set $segnode = (struct segment *)$segnode->s_node.mln_Succ
216         end
217     end
219     if $cont
220     printf "Searching in the kickstart list...\n"
221         set $kicknode = $_debug_KickList
223     while ($kicknode != 0) && $cont
224             set $eh = $kicknode->eh
225             set $sh = $kicknode->sh
226             set $shnum = $eh->shnum
228             set $i = 0
229             while ($i < $shnum) && $cont
230                 if ($sh->addr != 0) && ($sh->size != 0)
231             set $lowest  = $sh->addr
232             set $highest = $sh->addr + $sh->size - 1
234             if $arg0 >= $lowest && $arg0 <= $highest
235                 printf "Address found in %s in section number %d starting at %p.\n", $kicknode->Name, $i, $lowest
236                         set $cont = 0
237                     end
238                 end
240         set $sh = $sh + 1
241         set $i = $i + 1
242         end
243             set $kicknode = $kicknode->Next
244         end
245     end
247     #then in the resident list
248     if $cont
249         printf "Searching in the resident list...\n"
250     end
252     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
253     set $i = 0
255     while (($resp)[$i] != 0) && $cont
256     set $res = ($resp)[$i]
258         if ($arg0 >= $res) && ($arg0 <= $res->rt_EndSkip)
259             printf "Address found in %s, which resides at %p\n", $res->rt_Name, $res
260             set $cont = 0
261         end
263         set $i = $i + 1
264     end
266     if $cont
267         printf "No matching module for this address\n"
268     end
270 document findaddr
271 -Shows the module that contains the given address
273 -To debug a problem in AROS, do the following:
275 -1. Get a stacktrace with bt or similar.
276 -2. Use findaddr with such an address to find out in which
277 -   module it is:
278 -3. Use add-symbol-file to load that modules symbols.
279 -4. Now you can run bt (or similar) again and you should see the
280 -   addresses resolved as symbols.
282 -Example:
284 -0x4058d45b in ?? ()
286 -(gdb) findaddr 0x4058d45b
288 -Searching in the loaded modules...
289 -Address found in Workbench:contrib/Zune/Libs/muimaster.library, which is loaded at 0x405379a4.
290 -If this is an executable, its .text section starts at 0x405379b0.
291 -(gdb) add-symbol-file contrib/Zune/Libs/muimaster.library 0x405379b0
292 -add symbol table from file "contrib/Zune/Libs/muimaster.library" at
293 -        .text_addr = 0x405379b0
294 -(y or n) y
295 -Reading symbols from contrib/Zune/Libs/muimaster.library...done.
296 -(gdb) bt
297 -#0  0x4058d45b in strlen (ptr=0x80 <Address 0x80 out of bounds>) at strlen.c:45
298 -#1  0x00000000 in lastx.78 ()
301 define printtaglist
302     set $list = (struct TagItem *)$arg0
304     printf "Tag         Data (Hex)     Data (Dec)\n"
305     printf "--------------------------------------\n"
307     while $list->ti_Tag != 0
308     # Handle the possible control tag...
309     if $list->ti_Tag == 1
310         printf "TAG_IGNORE\n"
311     else if $list->ti_Tag == 2
312         printf "TAG_MORE    %p\n", $list->ti_Data
313         set $list = (struct TagItem *)$list->ti_Data
314     else if $list->ti_Tag == 3
315         printf "TAG_SKIP    %d\n", $list->ti_Data
316         set $list = $list + $list->ti_Tag + 1
317     else
318         printf "%p  %p      %9lu\n", $list->ti_Tag, $list->ti_Data, $list->ti_Data
319         set $list = $list + 1
320     end
321     end
322     printf "TAG_DONE\n"
324 document printtaglist
327 define log_to_file
328   set logging file $arg0
329   set logging redirect on
330   set logging overwrite $arg1
331   set logging on
334 define end_log
335   set logging off
338 define loadseg
339     _debug_init
340     dont-repeat
341     if $_debug_ModList
342         set $step = 1
343         set $segnode = (struct segment *)$_debug_ModList->mlh_Head
344         while ($segnode->s_node.mln_Succ != 0) && $step == 1
345             if $arg0 >= $segnode->s_lowest && $arg0 <= $segnode->s_highest
346                 log_to_file segname.tmp on
347                 printf "%s", $segnode->s_mod->m_name
348                 end_log
349                 shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
350                 log_to_file loadseg.tmp on
351                 printf "add-symbol-file "
352                 end_log
353                 shell head -n1 segname.tmp >>loadseg.tmp
354                 log_to_file loadseg.tmp off
355                 printf " %p", $segnode->s_lowest
356                 if $segnode->s_node.mln_Succ != 0
357                     set $segnode = (struct segment *)$segnode->s_node.mln_Succ
358                     while ($segnode->s_node.mln_Succ != 0) && $step < 5
359                         if strcmp($segnode->s_name, ".text") == 0
360                             loop_break
361                         end
362                         printf " -s %s %p", $segnode->s_name, $segnode->s_lowest
363                         set $step = $step + 1
364                         set $segnode = (struct segment *)$segnode->s_node.mln_Succ
365                     end
366                 end
367                 end_log
368                 source loadseg.tmp
369                 loop_break
370             end
371             set $segnode = (struct segment *)$segnode->s_node.mln_Succ
372         end
375         if $step < 2
376             set $kicknode = $_debug_KickList
378             while ($kicknode != 0) && $step == 1
379                 set $eh = $kicknode->eh
380                 set $sh = $kicknode->sh
381                 set $shnum = $eh->shnum
383                 set $i = 0
384                 while ($i < $shnum)
385                     if ($sh->addr != 0) && ($sh->size != 0)
386                         set $lowest  = $sh->addr
387                         set $highest = $sh->addr + $sh->size - 1
389                         if $arg0 >= $lowest && $arg0 <= $highest
390                             set $shstrndx = $eh->shstrndx
391                             set $shstr = 0
393                             if ($shstrndx < 0xFF00)
394                                 set $shstr = $shstrndx
395                             end
396                             if ($shstrndx > 0xFFFF)
397                                 set $shstr = $shstrndx - (0x10000 - 0xFF00)
398                             end
400                             log_to_file segname.tmp on
401                             printf "%s", $kicknode->Name
402                             end_log
403                             shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
404                             log_to_file loadseg.tmp on
405                             printf "add-symbol-file "
406                             end_log
407                             shell head -n1 segname.tmp >>loadseg.tmp
408                             log_to_file loadseg.tmp off
409                             printf " %p", $lowest
411                             set $sh = $sh + 1
412                             set $i = $i + 1
414                             while ($i < $shnum)
415                                 if ($sh->addr != 0) && ($sh->size != 0)
416 #                                   This code does not work, cause error. I have no knowledge on how to make it work.
417 #                                    set $segname = $kicknode->sh[$shstr] + $sh->name
418 #                                    printf " -s %s %p", $segname, $sh->addr
419                                 end
420                                 set $step = $step + 1
421                                 set $sh = $sh + 1
422                                 set $i = $i + 1
423                             end
425                             end_log
426                             source loadseg.tmp
427                             loop_break
428                         end
429                     end
431                     set $sh = $sh + 1
432                     set $i = $i + 1
433                 end
434                 set $kicknode = $kicknode->Next
435             end
436         end
438         if $step < 2
439             printf "No matching module for this address\n"
440         end
443     end
445 document loadseg
446 Loads the module that contains the given address
449 define seglistdump
450     _debug_init
451     set $nextseg = $arg0
452     set $count   = 1
454     printf "Hunk num. | Start addr | Size       \n"
455     printf "----------+------------+------------\n"
456     while $nextseg
457         printf "%9d | %p | %10d\n", $count, $nextseg + sizeof(BPTR), *((ULONG *)$nextseg - 1) - sizeof(BPTR)
459         set $nextseg = *(BPTR *)$nextseg
460         set $count = $count+1
461     end
463 document seglistdump
464 Shows the segments chain of the given seglist