Added very useful and convenient macro for parsing attribute IDs
[AROS.git] / _gdbinit
blob933327bc84707dacf0c07cf21cbb2b7db1dd3141
1 handle SIGUSR1 pass noprint nostop
2 handle SIGUSR2 pass noprint nostop
3 set follow-fork-mode child
5 # This is a bit tricky, because we have several cases,
6 # and gdb has no easy 'is this symbol defined' tests.
8 # Case 1: Hosted AROSBootstrap (ie linux-i386)
9 #         Provides SysBase, Debug_ModList, and Debug_KickList
10 # Case 2: ROM (ie amiga-m68k)
11 #         Provides AbsExecBase and SysBase
13 define _sysbase_init
14     init-if-undefined $AbsExecBase = 0
15     if $AbsExecBase != 0
16         set $AbsExecBase = (struct IntExecBase *)$AbsExecBase
17     end
18 end
19 document _sysbase_init
20 Initialize $AbsExecBase convenience variables
21 end
23 define _debug_init
24     _sysbase_init
25     init-if-undefined $_debug_DebugBase = 0
27     # This is the case for ROM debugging - the user must
28     #  'set $AbsExecBase = 4', then this kicks in.
29     if $AbsExecBase != 0 && $_debug_DebugBase == 0
30         set $_debug_DebugBase = (struct DebugBase *)($AbsExecBase->DebugBase)
31     end
33     if $_debug_DebugBase != 0
34         set $_debug_DebugBase = (struct DebugBase *)($_debug_DebugBase)
35         # This is the case for debugging a ROM
36         set $_debug_ModList = &($_debug_DebugBase->db_Modules)
37         set $_debug_KickList = $_debug_DebugBase->db_KernelModules
38     else
39         # This is the case for debugging a bootstrap
40         init-if-undefined $_debug_ModList = Debug_ModList
41         init-if-undefined $_debug_KickList = Debug_KickList
42     end
43 end
44 document _debug_init
45 Initialize debugging convenience variables
46 end
48 define liblist
49     _sysbase_init
50     set $lib = ((struct ExecBase *)$AbsExecBase)->LibList.lh_Head
52     printf "Base     OpenC   Name\n"
53     printf "---------------------------------------------------------------\n"
54     while ($lib->ln_Succ != 0)
55     printf "%p %5d   %s\n", \
56         $lib, \
57         ((struct Library *)$lib)->lib_OpenCnt, \
58         $lib->ln_Name
59     set $lib = $lib->ln_Succ
60     end
61 end
62 document liblist
63 List the current libraries in the system
64 end
66 define devlist
67     _debug_init
68     set $dev = ((struct ExecBase *)$AbsExecBase)->DeviceList.lh_Head
69     printf "Base     OpenC   Name\n"
70     printf "---------------------------------------------------------------\n"
71     while ($dev->ln_Succ != 0)
72     printf "%p %5d   %s\n", \
73         $dev, \
74         ((struct Library *)$dev)->lib_OpenCnt, \
75         $dev->ln_Name
76     set $dev = $dev->ln_Succ
77     end
78 end
79 document devlist
80 List the current devices in the system
81 end
83 define resourcelist
84     _debug_init
85     set $res = ((struct ExecBase *)$AbsExecBase)->ResourceList.lh_Head
86     printf "Base     Name\n"
87     printf "---------------------------------------------------------------\n"
88     while ($res->ln_Succ != 0)
89     printf "%p %s\n", $res, $res->ln_Name
90     set $res = $res->ln_Succ
91     end
92 end
93 document resourcelist
94 List the current resources in the system
95 end
97 define residentlist
98     _debug_init
99     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
100     set $i = 0
102     printf "Address    Pri Flags Vers Type  Name\n"
103     printf "--------------------------------------------------------------\n"
104     while (($resp)[$i] != 0)
105     set $res = ($resp)[$i]
106     printf "%p  %4d    %02x  %3d  %3d  %s\n", \
107         $res, \
108         ((struct Resident *)$res)->rt_Pri, \
109         ((struct Resident *)$res)->rt_Flags, \
110         ((struct Resident *)$res)->rt_Version, \
111         ((struct Resident *)$res)->rt_Type, \
112         ((struct Resident *)$res)->rt_Name
113     set $i = $i + 1
114     end
116 document residentlist
117 List the system resident list
120 define taskready
121     _debug_init
122     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskReady.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 taskready
140 List of tasks currently ready to run
143 define taskwait
144     _debug_init
145     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskWait.lh_Head
147     printf "Task     SigWait  SigRecvd StkSize   StkUsed Pri Type Name\n"
148     printf "-----------------------------------------------------------------------------\n"
149     while ($task->tc_Node.ln_Succ != 0)
150     printf "%p %p %p %8d %8d %3d  %3ld %s\n", \
151         $task, \
152         $task->tc_SigWait, \
153         $task->tc_SigRecvd, \
154         $task->tc_SPUpper - $task->tc_SPLower, \
155         $task->tc_SPUpper - $task->tc_SPReg, \
156         $task->tc_Node.ln_Pri, \
157         $task->tc_Node.ln_Type, \
158         $task->tc_Node.ln_Name
159     set $task = (struct Task *)$task->tc_Node.ln_Succ
160     end
162 document taskwait
163 List of tasks currently waiting for an event
166 define thistask
167     _debug_init
168     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->ThisTask
169     printf "Task     SigWait  SigRecvd StkSize   StkUsed Pri Type Name\n"
170     printf "-----------------------------------------------------------------------------\n"
171     printf "%p %p %p %8d %8d %3d  %3ld %s\n", \
172     $task, \
173     $task->tc_SigWait, \
174     $task->tc_SigRecvd, \
175     $task->tc_SPUpper - $task->tc_SPLower, \
176     $task->tc_SPUpper - $task->tc_SPReg, \
177     $task->tc_Node.ln_Pri, \
178     $task->tc_Node.ln_Type, \
179     $task->tc_Node.ln_Name
181 document thistask
182 Print out information about the currently running task.
185 define modlist
186     _debug_init
187     printf "Segment           Module\n"
189     if $_debug_ModList
190         printf "---------------------------------------------------------------------\n"
191         set $segnode = (struct segment *)$_debug_ModList->mlh_Head
193         while ($segnode->s_node.mln_Succ != 0)
194             printf "%p %12s %2u %32s\n", $segnode->s_lowest, $segnode->s_name, $segnode->s_num, $segnode->s_mod->m_name
196             set $segnode = (struct segment *)$segnode->s_node.mln_Succ
197         end
198     end
200     printf "---------------------------------------------------------------------\n"
201     set $kicknode = $_debug_KickList
203     while ($kicknode != 0)
204         set $eh = $kicknode->eh
205         set $sh = $kicknode->sh
206         set $shnum = $eh->shnum
208         set $i = 0
209         while ($i < $shnum)
210             if ($sh->addr != 0) && ($sh->size != 0)
211         printf "%p              %2u %32s\n", $sh->addr, $i, $kicknode->Name
212         end
213         set $sh = $sh + 1
214         set $i = $i + 1
215     end
216         set $kicknode = $kicknode->Next
217     end
219 document modlist
220 List of all the modules currently loaded in memory
223 define findaddr
224     _debug_init
225     set $cont = 1
227     #first search in modules loaded from disk
228     printf "Searching in the loaded modules...\n"
229     if $_debug_ModList
230         set $segnode = (struct segment *)$_debug_ModList->mlh_Head
232         while ($segnode->s_node.mln_Succ != 0) && $cont
233         if $arg0 >= $segnode->s_lowest && $arg0 <= $segnode->s_highest
234                 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
236                 set $cont = 0
237             end
238             set $segnode = (struct segment *)$segnode->s_node.mln_Succ
239         end
240     end
242     if $cont
243     printf "Searching in the kickstart list...\n"
244         set $kicknode = $_debug_KickList
246     while ($kicknode != 0) && $cont
247             set $eh = $kicknode->eh
248             set $sh = $kicknode->sh
249             set $shnum = $eh->shnum
251             set $i = 0
252             while ($i < $shnum) && $cont
253                 if ($sh->addr != 0) && ($sh->size != 0)
254             set $lowest  = $sh->addr
255             set $highest = $sh->addr + $sh->size - 1
257             if $arg0 >= $lowest && $arg0 <= $highest
258                 printf "Address found in %s in section number %d starting at %p.\n", $kicknode->Name, $i, $lowest
259                         set $cont = 0
260                     end
261                 end
263         set $sh = $sh + 1
264         set $i = $i + 1
265         end
266             set $kicknode = $kicknode->Next
267         end
268     end
270     #then in the resident list
271     if $cont
272         printf "Searching in the resident list...\n"
273     end
275     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
276     set $i = 0
278     while (($resp)[$i] != 0) && $cont
279     set $res = ($resp)[$i]
281         if ($arg0 >= $res) && ($arg0 <= $res->rt_EndSkip)
282             printf "Address found in %s, which resides at %p\n", $res->rt_Name, $res
283             set $cont = 0
284         end
286         set $i = $i + 1
287     end
289     if $cont
290         printf "No matching module for this address\n"
291     end
293 document findaddr
294 -Shows the module that contains the given address
296 -To debug a problem in AROS, do the following:
298 -1. Get a stacktrace with bt or similar.
299 -2. Use findaddr with such an address to find out in which
300 -   module it is:
301 -3. Use add-symbol-file to load that modules symbols.
302 -4. Now you can run bt (or similar) again and you should see the
303 -   addresses resolved as symbols.
305 -Example:
307 -0x4058d45b in ?? ()
309 -(gdb) findaddr 0x4058d45b
311 -Searching in the loaded modules...
312 -Address found in Workbench:contrib/Zune/Libs/muimaster.library, which is loaded at 0x405379a4.
313 -If this is an executable, its .text section starts at 0x405379b0.
314 -(gdb) add-symbol-file contrib/Zune/Libs/muimaster.library 0x405379b0
315 -add symbol table from file "contrib/Zune/Libs/muimaster.library" at
316 -        .text_addr = 0x405379b0
317 -(y or n) y
318 -Reading symbols from contrib/Zune/Libs/muimaster.library...done.
319 -(gdb) bt
320 -#0  0x4058d45b in strlen (ptr=0x80 <Address 0x80 out of bounds>) at strlen.c:45
321 -#1  0x00000000 in lastx.78 ()
324 define printtaglist
325     set $list = (struct TagItem *)$arg0
327     printf "Tag         Data (Hex)     Data (Dec)\n"
328     printf "--------------------------------------\n"
330     while $list->ti_Tag != 0
331     # Handle the possible control tag...
332     if $list->ti_Tag == 1
333         printf "TAG_IGNORE\n"
334     else if $list->ti_Tag == 2
335         printf "TAG_MORE    %p\n", $list->ti_Data
336         set $list = (struct TagItem *)$list->ti_Data
337     else if $list->ti_Tag == 3
338         printf "TAG_SKIP    %d\n", $list->ti_Data
339         set $list = $list + $list->ti_Tag + 1
340     else
341         printf "%p  %p      %9lu\n", $list->ti_Tag, $list->ti_Data, $list->ti_Data
342         set $list = $list + 1
343     end
344     end
345     printf "TAG_DONE\n"
347 document printtaglist
350 define log_to_file
351   set logging file $arg0
352   set logging redirect on
353   set logging overwrite $arg1
354   set logging on
357 define end_log
358   set logging off
361 define loadseg
362     _debug_init
363     dont-repeat
364     if $_debug_ModList
365         set $step = 1
366         set $segnode = (struct segment *)$_debug_ModList->mlh_Head
367         while ($segnode->s_node.mln_Succ != 0) && $step == 1
368             if $arg0 >= $segnode->s_lowest && $arg0 <= $segnode->s_highest
369                 log_to_file segname.tmp on
370                 printf "%s", $segnode->s_mod->m_name
371                 end_log
372                 shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
373                 log_to_file loadseg.tmp on
374                 printf "add-symbol-file "
375                 end_log
376                 shell head -n1 segname.tmp >>loadseg.tmp
377                 log_to_file loadseg.tmp off
378                 printf " %p", $segnode->s_lowest
379                 if $segnode->s_node.mln_Succ != 0
380                     set $segnode = (struct segment *)$segnode->s_node.mln_Succ
381                     while ($segnode->s_node.mln_Succ != 0) && $step < 5
382                         if strcmp($segnode->s_name, ".text") == 0
383                             loop_break
384                         end
385                         printf " -s %s %p", $segnode->s_name, $segnode->s_lowest
386                         set $step = $step + 1
387                         set $segnode = (struct segment *)$segnode->s_node.mln_Succ
388                     end
389                 end
390                 end_log
391                 source loadseg.tmp
392                 loop_break
393             end
394             set $segnode = (struct segment *)$segnode->s_node.mln_Succ
395         end
398         if $step < 2
399             set $kicknode = $_debug_KickList
401             while ($kicknode != 0) && $step == 1
402                 set $eh = $kicknode->eh
403                 set $sh = $kicknode->sh
404                 set $shnum = $eh->shnum
406                 set $i = 0
407                 while ($i < $shnum)
408                     if ($sh->addr != 0) && ($sh->size != 0)
409                         set $lowest  = $sh->addr
410                         set $highest = $sh->addr + $sh->size - 1
412                         if $arg0 >= $lowest && $arg0 <= $highest
413                             set $shstrndx = $eh->shstrndx
414                             set $shstr = 0
416                             if ($shstrndx < 0xFF00)
417                                 set $shstr = $shstrndx
418                             end
419                             if ($shstrndx > 0xFFFF)
420                                 set $shstr = $shstrndx - (0x10000 - 0xFF00)
421                             end
423                             log_to_file segname.tmp on
424                             printf "%s", $kicknode->Name
425                             end_log
426                             shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
427                             log_to_file loadseg.tmp on
428                             printf "add-symbol-file "
429                             end_log
430                             shell head -n1 segname.tmp >>loadseg.tmp
431                             log_to_file loadseg.tmp off
432                             printf " %p", $lowest
434                             set $sh = $sh + 1
435                             set $i = $i + 1
437                             while ($i < $shnum)
438                                 if ($sh->addr != 0) && ($sh->size != 0)
439 #                                   This code does not work, cause error. I have no knowledge on how to make it work.
440 #                                    set $segname = $kicknode->sh[$shstr] + $sh->name
441 #                                    printf " -s %s %p", $segname, $sh->addr
442                                 end
443                                 set $step = $step + 1
444                                 set $sh = $sh + 1
445                                 set $i = $i + 1
446                             end
448                             end_log
449                             source loadseg.tmp
450                             loop_break
451                         end
452                     end
454                     set $sh = $sh + 1
455                     set $i = $i + 1
456                 end
457                 set $kicknode = $kicknode->Next
458             end
459         end
461         if $step < 2
462             printf "No matching module for this address\n"
463         end
466     end
468 document loadseg
469 Loads the module that contains the given address
472 define loadkick
473     _debug_init
474     set $_kicknode = $_debug_KickList
476     while ($_kicknode != 0)
477         set $_eh = $_kicknode->eh
478         set $_sh = $_kicknode->sh
479         set $_shnum = $_eh->shnum
481         set $_i = 0
482         while ($_i < $_shnum)
483             if ($_i == 1) && ($_sh->addr != 0) && ($_sh->size != 0)
484                 loadseg $_sh->addr
485             end
486             set $_sh = $_sh + 1
487             set $_i = $_i + 1
488         end
489         set $_kicknode = $_kicknode->Next
490     end
492 document loadkick
493 Loads the Kickstart (symbols)
496 define loadmods
497     _debug_init
498     
499     if $_debug_ModList
500         set $_segnode = (struct segment *)$_debug_ModList->mlh_Head
502         while ($_segnode->s_node.mln_Succ != 0)
503             if $_segnode->s_num == 1
504                 loadseg $_segnode->s_lowest
505             end
506             set $_segnode = (struct segment *)$_segnode->s_node.mln_Succ
507         end
508     end
510 document loadmods
511 Loads all the modules (symbols)
514 define loadall
515     loadkick
516     loadmods
518 document loadall
519 Loads the symbols of the Kickstart and all modules
522 define loadframe
523     log_to_file frameinfo.tmp on
524     info frame $arg0
525     end_log
526     
527     shell grep "eip =" frameinfo.tmp >loadseg.tmp
528     shell sed -e 's/eip = \(0x[0-9,a-f]*\).*/loadseg \1/' loadseg.tmp >frameinfo.tmp
529     
530     source frameinfo.tmp
532 document loadframe
533 Loads the symbols for the given stack frame number
536 define loadframes
537     set $_again = 1
538     printf "\n\n"
539     
540     while ($_again == 1)
541         bt
542         printf "\nEnter stack frame number to resolve or RETURN to stop: \n\n"
544         set $_answer = 1000
546         shell read _gdb_answer && echo $_gdb_answer | grep -E "[0-9]+" | sed "s/\(.*\)/set \$_answer=\1/" >frameinfo.tmp
548         source frameinfo.tmp
549         printf "\n\n"
551         if $_answer == 1000
552             set $_again = 0
553         else
554             loadframe $_answer
555         end
556     end
558 document loadframes
559 Interactive multiple loading of symbols for given stack frame numbers
562 define loadbt
563     set $_frame_counter = 0
565     set $_again = 1
566     while ($_again == 1)
567         printf "Checking frame #%d\n", $_frame_counter
568         
569         set $_again = 0
570         
571         log_to_file loadseg.tmp on
572         bt
573         end_log
575         # Check if frame exists
576         
577         log_to_file frameinfo.tmp on
578         printf "shell grep \"#%d .*\" loadseg.tmp | sed \"s/#.*/set \\$_again = 1/\" >loadbt.tmp\n", $_frame_counter
579         end_log
580         
581         source frameinfo.tmp
582         source loadbt.tmp
584         if $_again == 1
585         
586             # If frame is unresolved ("in ??") transform to "loadseg address"
587             
588             log_to_file frameinfo.tmp on
589             printf "shell grep \"#%d .* in ??\" loadseg.tmp | sed \"s/#.*\\(0x[0-9,a-f]*\\) .*/loadseg \\1/\" >loadbt.tmp\n", $_frame_counter
590             end_log
592             source frameinfo.tmp
593             source loadbt.tmp
595             set $_frame_counter = $_frame_counter + 1        
596             if ($_frame_counter == 1000)
597                 set $_again = 0
598             end
599         end
600     end        
602 document loadbt
603 Tries to automatically load the symbols for all unresolved stack frames
606 define seglistdump
607     _debug_init
608     set $nextseg = $arg0
609     set $count   = 1
611     printf "Hunk num. | Start addr | Size       \n"
612     printf "----------+------------+------------\n"
613     while $nextseg
614         printf "%9d | %p | %10d\n", $count, $nextseg + sizeof(BPTR), *((ULONG *)$nextseg - 1) - sizeof(BPTR)
616         set $nextseg = *(BPTR *)$nextseg
617         set $count = $count+1
618     end
620 document seglistdump
621 Shows the segments chain of the given seglist
624 define bttask
625     set $task = (struct Task *)$arg0
626     if ($task->tc_Node.ln_Type != 1) && ($task->tc_Node.ln_Type != 13)
627         printf "ERROR: Given address does not look like a task or process!\n"
628     else
629         #FIXME: The following assumes Linux x86
630         set $old_esp = $esp
631         set $old_eip = $eip
632         
633         if $task->tc_State == 2
634             printf "WARNING: TS_RUN Task. Showing normal backtrace!\n"
635         else
636             set $esp = $task->tc_SPReg
637             set $taskcontext = (struct AROSCPUContext *)$task->tc_UnionETask.tc_ETask.et_RegFrame
638             set $eip = $taskcontext.regs.eip
639         end
640         
641         bt
643         set $esp = $old_esp
644         set $eip = $old_eip
645     end
647 document bttask
648 Shows the backtrace of the given TS_READY/TS_WAIT task
651 define semowner
652     set $sem = (struct SignalSemaphore *)$arg0
653     if $sem->ss_Link.ln_Type != 15
654         printf "ERROR: Given address does not look like a semaphore!\n"
655     else
656         if $sem->ss_QueueCount == -1
657             printf "The semaphore is free\n"
658         else
659             if $sem->ss_Owner == 0
660                 printf "The semaphore is locked in shared mode by one or more tasks\n"
661             else
662                     printf "The semaphore is owned by task %p (%s)\n", $sem->ss_Owner, $sem->ss_Owner->tc_Node.ln_Name
663             end
665             printf "\nWait Queue:\n\n"
667             set $waitnode = (struct SemaphoreRequest *)$sem->ss_WaitQueue.mlh_Head
669             while ($waitnode->sr_Link.mln_Succ != 0)
670                 set $waitertask = $waitnode->sr_Waiter
671                 if (int)$waitertask & 1
672                     set $waitertask = $waitertask & ~1
673                     printf " SHARED    "
674                 else
675                     printf " EXCLUSIVE "
676                 end
677                 printf"%p %s\n", $waitertask, $waitertask->tc_Node.ln_Name
678                 set $waitnode = (struct SemaphoreRequest *)$waitnode->sr_Link.mln_Succ
679             end
680         end
681     end
683 document semowner
684 Shows the owner of the given Exec Semaphore and the Wait Queue