Two ease-of-use improvements:
[AROS.git] / _gdbinit
blobb8a1729dd2ee09686e1e25e57e7b0916ae1536e9
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 _debug_init
14     init-if-undefined $AbsExecBase = 0
15     init-if-undefined $_debug_DebugBase = 0
17     # This is the case for ROM debugging - the user must
18     #  'set $AbsExecBase = 4', then this kicks in.
19     if $AbsExecBase != 0 && $_debug_DebugBase == 0
20         set $AbsExecBase = (struct IntExecBase *)$AbsExecBase
21         set $_debug_DebugBase = (struct DebugBase *)($AbsExecBase->DebugBase)
22     end
24     if $_debug_DebugBase != 0
25         # This is the case for debugging a ROM
26         set $_debug_ModList = &($_debug_DebugBase->db_Modules)
27         set $_debug_KickList = $_debug_DebugBase->db_KernelModules
28     else
29         # This is the case for debugging a bootstrap
30         init-if-undefined $_debug_ModList = Debug_ModList
31         init-if-undefined $_debug_KickList = Debug_KickList
32     end
33 end
34 document _debug_init
35 Initialize debugging convenience variables
36 end
38 define liblist
39     _debug_init
40     set $lib = ((struct ExecBase *)$AbsExecBase)->LibList.lh_Head
42     printf "Base     OpenC   Name\n"
43     printf "---------------------------------------------------------------\n"
44     while ($lib->ln_Succ != 0)
45     printf "%p %5d   %s\n", \
46         $lib, \
47         ((struct Library *)$lib)->lib_OpenCnt, \
48         $lib->ln_Name
49     set $lib = $lib->ln_Succ
50     end
51 end
52 document liblist
53 List the current libraries in the system
54 end
56 define devlist
57     _debug_init
58     set $dev = ((struct ExecBase *)$AbsExecBase)->DeviceList.lh_Head
59     printf "Base     OpenC   Name\n"
60     printf "---------------------------------------------------------------\n"
61     while ($dev->ln_Succ != 0)
62     printf "%p %5d   %s\n", \
63         $dev, \
64         ((struct Library *)$dev)->lib_OpenCnt, \
65         $dev->ln_Name
66     set $dev = $dev->ln_Succ
67     end
68 end
69 document devlist
70 List the current devices in the system
71 end
73 define resourcelist
74     _debug_init
75     set $res = ((struct ExecBase *)$AbsExecBase)->ResourceList.lh_Head
76     printf "Base     Name\n"
77     printf "---------------------------------------------------------------\n"
78     while ($res->ln_Succ != 0)
79     printf "%p %s\n", $res, $res->ln_Name
80     set $res = $res->ln_Succ
81     end
82 end
83 document resourcelist
84 List the current resources in the system
85 end
87 define residentlist
88     _debug_init
89     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
90     set $i = 0
92     printf "Address    Pri Flags Vers Type  Name\n"
93     printf "--------------------------------------------------------------\n"
94     while (($resp)[$i] != 0)
95     set $res = ($resp)[$i]
96     printf "%p  %4d    %02x  %3d  %3d  %s\n", \
97         $res, \
98         ((struct Resident *)$res)->rt_Pri, \
99         ((struct Resident *)$res)->rt_Flags, \
100         ((struct Resident *)$res)->rt_Version, \
101         ((struct Resident *)$res)->rt_Type, \
102         ((struct Resident *)$res)->rt_Name
103     set $i = $i + 1
104     end
106 document residentlist
107 List the system resident list
110 define taskready
111     _debug_init
112     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskReady.lh_Head
114     printf "Task     SigWait  SigRecvd StkSize   StkUsed Pri Type Name\n"
115     printf "-----------------------------------------------------------------------------\n"
116     while ($task->tc_Node.ln_Succ != 0)
117     printf "%p %p %p %8d %8d %3d  %3ld %s\n", \
118         $task, \
119         $task->tc_SigWait, \
120         $task->tc_SigRecvd, \
121         $task->tc_SPUpper - $task->tc_SPLower, \
122         $task->tc_SPUpper - $task->tc_SPReg, \
123         $task->tc_Node.ln_Pri, \
124         $task->tc_Node.ln_Type, \
125         $task->tc_Node.ln_Name
126     set $task = (struct Task *)$task->tc_Node.ln_Succ
127     end
129 document taskready
130 List of tasks currently ready to run
133 define taskwait
134     _debug_init
135     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskWait.lh_Head
137     printf "Task     SigWait  SigRecvd StkSize   StkUsed Pri Type Name\n"
138     printf "-----------------------------------------------------------------------------\n"
139     while ($task->tc_Node.ln_Succ != 0)
140     printf "%p %p %p %8d %8d %3d  %3ld %s\n", \
141         $task, \
142         $task->tc_SigWait, \
143         $task->tc_SigRecvd, \
144         $task->tc_SPUpper - $task->tc_SPLower, \
145         $task->tc_SPUpper - $task->tc_SPReg, \
146         $task->tc_Node.ln_Pri, \
147         $task->tc_Node.ln_Type, \
148         $task->tc_Node.ln_Name
149     set $task = (struct Task *)$task->tc_Node.ln_Succ
150     end
152 document taskwait
153 List of tasks currently waiting for an event
156 define thistask
157     _debug_init
158     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->ThisTask
159     printf "Task     SigWait  SigRecvd StkSize   StkUsed Pri Type Name\n"
160     printf "-----------------------------------------------------------------------------\n"
161     printf "%p %p %p %8d %8d %3d  %3ld %s\n", \
162     $task, \
163     $task->tc_SigWait, \
164     $task->tc_SigRecvd, \
165     $task->tc_SPUpper - $task->tc_SPLower, \
166     $task->tc_SPUpper - $task->tc_SPReg, \
167     $task->tc_Node.ln_Pri, \
168     $task->tc_Node.ln_Type, \
169     $task->tc_Node.ln_Name
171 document thistask
172 Print out information about the currently running task.
175 define modlist
176     _debug_init
177     printf "Segment           Module\n"
179     if $_debug_ModList
180         printf "---------------------------------------------------------------------\n"
181         set $segnode = (struct segment *)$_debug_ModList->mlh_Head
183         while ($segnode->s_node.mln_Succ != 0)
184             printf "%p %12s %2u %32s\n", $segnode->s_lowest, $segnode->s_name, $segnode->s_num, $segnode->s_mod->m_name
186             set $segnode = (struct segment *)$segnode->s_node.mln_Succ
187         end
188     end
190     printf "---------------------------------------------------------------------\n"
191     set $kicknode = $_debug_KickList
193     while ($kicknode != 0)
194         set $eh = $kicknode->eh
195         set $sh = $kicknode->sh
196         set $shnum = $eh->shnum
198         set $i = 0
199         while ($i < $shnum)
200             if ($sh->addr != 0) && ($sh->size != 0)
201         printf "%p              %2u %32s\n", $sh->addr, $i, $kicknode->Name
202         end
203         set $sh = $sh + 1
204         set $i = $i + 1
205     end
206         set $kicknode = $kicknode->Next
207     end
209 document modlist
210 List of all the modules currently loaded in memory
213 define findaddr
214     _debug_init
215     set $cont = 1
217     #first search in modules loaded from disk
218     printf "Searching in the loaded modules...\n"
219     if $_debug_ModList
220         set $segnode = (struct segment *)$_debug_ModList->mlh_Head
222         while ($segnode->s_node.mln_Succ != 0) && $cont
223         if $arg0 >= $segnode->s_lowest && $arg0 <= $segnode->s_highest
224                 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
226                 set $cont = 0
227             end
228             set $segnode = (struct segment *)$segnode->s_node.mln_Succ
229         end
230     end
232     if $cont
233     printf "Searching in the kickstart list...\n"
234         set $kicknode = $_debug_KickList
236     while ($kicknode != 0) && $cont
237             set $eh = $kicknode->eh
238             set $sh = $kicknode->sh
239             set $shnum = $eh->shnum
241             set $i = 0
242             while ($i < $shnum) && $cont
243                 if ($sh->addr != 0) && ($sh->size != 0)
244             set $lowest  = $sh->addr
245             set $highest = $sh->addr + $sh->size - 1
247             if $arg0 >= $lowest && $arg0 <= $highest
248                 printf "Address found in %s in section number %d starting at %p.\n", $kicknode->Name, $i, $lowest
249                         set $cont = 0
250                     end
251                 end
253         set $sh = $sh + 1
254         set $i = $i + 1
255         end
256             set $kicknode = $kicknode->Next
257         end
258     end
260     #then in the resident list
261     if $cont
262         printf "Searching in the resident list...\n"
263     end
265     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
266     set $i = 0
268     while (($resp)[$i] != 0) && $cont
269     set $res = ($resp)[$i]
271         if ($arg0 >= $res) && ($arg0 <= $res->rt_EndSkip)
272             printf "Address found in %s, which resides at %p\n", $res->rt_Name, $res
273             set $cont = 0
274         end
276         set $i = $i + 1
277     end
279     if $cont
280         printf "No matching module for this address\n"
281     end
283 document findaddr
284 -Shows the module that contains the given address
286 -To debug a problem in AROS, do the following:
288 -1. Get a stacktrace with bt or similar.
289 -2. Use findaddr with such an address to find out in which
290 -   module it is:
291 -3. Use add-symbol-file to load that modules symbols.
292 -4. Now you can run bt (or similar) again and you should see the
293 -   addresses resolved as symbols.
295 -Example:
297 -0x4058d45b in ?? ()
299 -(gdb) findaddr 0x4058d45b
301 -Searching in the loaded modules...
302 -Address found in Workbench:contrib/Zune/Libs/muimaster.library, which is loaded at 0x405379a4.
303 -If this is an executable, its .text section starts at 0x405379b0.
304 -(gdb) add-symbol-file contrib/Zune/Libs/muimaster.library 0x405379b0
305 -add symbol table from file "contrib/Zune/Libs/muimaster.library" at
306 -        .text_addr = 0x405379b0
307 -(y or n) y
308 -Reading symbols from contrib/Zune/Libs/muimaster.library...done.
309 -(gdb) bt
310 -#0  0x4058d45b in strlen (ptr=0x80 <Address 0x80 out of bounds>) at strlen.c:45
311 -#1  0x00000000 in lastx.78 ()
314 define printtaglist
315     set $list = (struct TagItem *)$arg0
317     printf "Tag         Data (Hex)     Data (Dec)\n"
318     printf "--------------------------------------\n"
320     while $list->ti_Tag != 0
321     # Handle the possible control tag...
322     if $list->ti_Tag == 1
323         printf "TAG_IGNORE\n"
324     else if $list->ti_Tag == 2
325         printf "TAG_MORE    %p\n", $list->ti_Data
326         set $list = (struct TagItem *)$list->ti_Data
327     else if $list->ti_Tag == 3
328         printf "TAG_SKIP    %d\n", $list->ti_Data
329         set $list = $list + $list->ti_Tag + 1
330     else
331         printf "%p  %p      %9lu\n", $list->ti_Tag, $list->ti_Data, $list->ti_Data
332         set $list = $list + 1
333     end
334     end
335     printf "TAG_DONE\n"
337 document printtaglist
340 define log_to_file
341   set logging file $arg0
342   set logging redirect on
343   set logging overwrite $arg1
344   set logging on
347 define end_log
348   set logging off
351 define loadseg
352     _debug_init
353     dont-repeat
354     if $_debug_ModList
355         set $step = 1
356         set $segnode = (struct segment *)$_debug_ModList->mlh_Head
357         while ($segnode->s_node.mln_Succ != 0) && $step == 1
358             if $arg0 >= $segnode->s_lowest && $arg0 <= $segnode->s_highest
359                 log_to_file segname.tmp on
360                 printf "%s", $segnode->s_mod->m_name
361                 end_log
362                 shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
363                 log_to_file loadseg.tmp on
364                 printf "add-symbol-file "
365                 end_log
366                 shell head -n1 segname.tmp >>loadseg.tmp
367                 log_to_file loadseg.tmp off
368                 printf " %p", $segnode->s_lowest
369                 if $segnode->s_node.mln_Succ != 0
370                     set $segnode = (struct segment *)$segnode->s_node.mln_Succ
371                     while ($segnode->s_node.mln_Succ != 0) && $step < 5
372                         if strcmp($segnode->s_name, ".text") == 0
373                             loop_break
374                         end
375                         printf " -s %s %p", $segnode->s_name, $segnode->s_lowest
376                         set $step = $step + 1
377                         set $segnode = (struct segment *)$segnode->s_node.mln_Succ
378                     end
379                 end
380                 end_log
381                 source loadseg.tmp
382                 loop_break
383             end
384             set $segnode = (struct segment *)$segnode->s_node.mln_Succ
385         end
388         if $step < 2
389             set $kicknode = $_debug_KickList
391             while ($kicknode != 0) && $step == 1
392                 set $eh = $kicknode->eh
393                 set $sh = $kicknode->sh
394                 set $shnum = $eh->shnum
396                 set $i = 0
397                 while ($i < $shnum)
398                     if ($sh->addr != 0) && ($sh->size != 0)
399                         set $lowest  = $sh->addr
400                         set $highest = $sh->addr + $sh->size - 1
402                         if $arg0 >= $lowest && $arg0 <= $highest
403                             set $shstrndx = $eh->shstrndx
404                             set $shstr = 0
406                             if ($shstrndx < 0xFF00)
407                                 set $shstr = $shstrndx
408                             end
409                             if ($shstrndx > 0xFFFF)
410                                 set $shstr = $shstrndx - (0x10000 - 0xFF00)
411                             end
413                             log_to_file segname.tmp on
414                             printf "%s", $kicknode->Name
415                             end_log
416                             shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
417                             log_to_file loadseg.tmp on
418                             printf "add-symbol-file "
419                             end_log
420                             shell head -n1 segname.tmp >>loadseg.tmp
421                             log_to_file loadseg.tmp off
422                             printf " %p", $lowest
424                             set $sh = $sh + 1
425                             set $i = $i + 1
427                             while ($i < $shnum)
428                                 if ($sh->addr != 0) && ($sh->size != 0)
429 #                                   This code does not work, cause error. I have no knowledge on how to make it work.
430 #                                    set $segname = $kicknode->sh[$shstr] + $sh->name
431 #                                    printf " -s %s %p", $segname, $sh->addr
432                                 end
433                                 set $step = $step + 1
434                                 set $sh = $sh + 1
435                                 set $i = $i + 1
436                             end
438                             end_log
439                             source loadseg.tmp
440                             loop_break
441                         end
442                     end
444                     set $sh = $sh + 1
445                     set $i = $i + 1
446                 end
447                 set $kicknode = $kicknode->Next
448             end
449         end
451         if $step < 2
452             printf "No matching module for this address\n"
453         end
456     end
458 document loadseg
459 Loads the module that contains the given address
462 define loadkick
463     _debug_init
464     set $_kicknode = $_debug_KickList
466     while ($_kicknode != 0)
467         set $_eh = $_kicknode->eh
468         set $_sh = $_kicknode->sh
469         set $_shnum = $_eh->shnum
471         set $_i = 0
472         while ($_i < $_shnum)
473             if ($_i == 1) && ($_sh->addr != 0) && ($_sh->size != 0)
474                 loadseg $_sh->addr
475             end
476             set $_sh = $_sh + 1
477             set $_i = $_i + 1
478         end
479         set $_kicknode = $_kicknode->Next
480     end
482 document loadkick
483 Loads the Kickstart (symbols)
486 define loadmods
487     _debug_init
488     
489     if $_debug_ModList
490         set $_segnode = (struct segment *)$_debug_ModList->mlh_Head
492         while ($_segnode->s_node.mln_Succ != 0)
493             if $_segnode->s_num == 1
494                 loadseg $_segnode->s_lowest
495             end
496             set $_segnode = (struct segment *)$_segnode->s_node.mln_Succ
497         end
498     end
500 document loadmods
501 Loads all the modules (symbols)
504 define loadall
505     loadkick
506     loadmods
508 document loadall
509 Loads the symbols of the Kickstart and all modules
512 define loadframe
513     log_to_file frameinfo.tmp on
514     info frame $arg0
515     end_log
516     
517     shell grep "eip =" frameinfo.tmp >loadseg.tmp
518     shell sed -e 's/eip = \(0x[0-9,a-f]*\).*/loadseg \1/' loadseg.tmp >frameinfo.tmp
519     
520     source frameinfo.tmp
522 document loadframe
523 Loads the symbols for the given stack frame number
526 define loadframes
527     set $_again = 1
528     printf "\n\n"
529     
530     while ($_again == 1)
531         bt
532         printf "\nEnter stack frame number to resolve or RETURN to stop: \n\n"
534         set $_answer = 1000
536         shell read _gdb_answer && echo $_gdb_answer | grep -E "[0-9]+" | sed "s/\(.*\)/set \$_answer=\1/" >frameinfo.tmp
538         source frameinfo.tmp
539         printf "\n\n"
541         if $_answer == 1000
542             set $_again = 0
543         else
544             loadframe $_answer
545         end
546     end
548 document loadframes
549 Interactive multiple loading of symbols for given stack frame numbers
552 define loadbt
553     set $_frame_counter = 0
555     set $_again = 1
556     while ($_again == 1)
557         printf "Checking frame #%d\n", $_frame_counter
558         
559         set $_again = 0
560         
561         log_to_file loadseg.tmp on
562         bt
563         end_log
565         # Check if frame exists
566         
567         log_to_file frameinfo.tmp on
568         printf "shell grep \"#%d .*\" loadseg.tmp | sed \"s/#.*/set \\$_again = 1/\" >loadbt.tmp\n", $_frame_counter
569         end_log
570         
571         source frameinfo.tmp
572         source loadbt.tmp
574         if $_again == 1
575         
576             # If frame is unresolved ("in ??") transform to "loadseg address"
577             
578             log_to_file frameinfo.tmp on
579             printf "shell grep \"#%d .* in ??\" loadseg.tmp | sed \"s/#.*\\(0x[0-9,a-f]*\\) .*/loadseg \\1/\" >loadbt.tmp\n", $_frame_counter
580             end_log
582             source frameinfo.tmp
583             source loadbt.tmp
585             set $_frame_counter = $_frame_counter + 1        
586             if ($_frame_counter == 1000)
587                 set $_again = 0
588             end
589         end
590     end        
592 document loadbt
593 Tries to automatically load the symbols for all unresolved stack frames
596 define seglistdump
597     _debug_init
598     set $nextseg = $arg0
599     set $count   = 1
601     printf "Hunk num. | Start addr | Size       \n"
602     printf "----------+------------+------------\n"
603     while $nextseg
604         printf "%9d | %p | %10d\n", $count, $nextseg + sizeof(BPTR), *((ULONG *)$nextseg - 1) - sizeof(BPTR)
606         set $nextseg = *(BPTR *)$nextseg
607         set $count = $count+1
608     end
610 document seglistdump
611 Shows the segments chain of the given seglist
614 define bttask
615     set $task = (struct Task *)$arg0
616     if ($task->tc_Node.ln_Type != 1) && ($task->tc_Node.ln_Type != 13)
617         printf "ERROR: Given address does not look like a task or process!\n"
618     else
619         #FIXME: The following assumes Linux x86
620         set $old_esp = $esp
621         set $old_eip = $eip
622         
623         if $task->tc_State == 2
624             printf "WARNING: TS_RUN Task. Showing normal backtrace!\n"
625         else
626             set $esp = $task->tc_SPReg
627             set $taskcontext = (struct AROSCPUContext *)$task->tc_UnionETask.tc_ETask.et_RegFrame
628             set $eip = $taskcontext.regs.eip
629         end
630         
631         bt
633         set $esp = $old_esp
634         set $eip = $old_eip
635     end
637 document bttask
638 Shows the backtrace of the given TS_READY/TS_WAIT task
641 define semowner
642     set $sem = (struct SignalSemaphore *)$arg0
643     if $sem->ss_Link.ln_Type != 15
644         printf "ERROR: Given address does not look like a semaphore!\n"
645     else
646         if $sem->ss_QueueCount == -1
647             printf "The semaphore is free\n"
648         else
649             if $sem->ss_Owner == 0
650                 printf "The semaphore is locked in shared mode by one or more tasks\n"
651             else
652                     printf "The semaphore is owned by task %p (%s)\n", $sem->ss_Owner, $sem->ss_Owner->tc_Node.ln_Name
653             end
655             printf "\nWait Queue:\n\n"
657             set $waitnode = (struct SemaphoreRequest *)$sem->ss_WaitQueue.mlh_Head
659             while ($waitnode->sr_Link.mln_Succ != 0)
660                 set $waitertask = $waitnode->sr_Waiter
661                 if (int)$waitertask & 1
662                     set $waitertask = $waitertask & ~1
663                     printf " SHARED    "
664                 else
665                     printf " EXCLUSIVE "
666                 end
667                 printf"%p %s\n", $waitertask, $waitertask->tc_Node.ln_Name
668                 set $waitnode = (struct SemaphoreRequest *)$waitnode->sr_Link.mln_Succ
669             end
670         end
671     end
673 document semowner
674 Shows the owner of the given Exec Semaphore and the Wait Queue