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
14 init-if-undefined $AbsExecBase = 0
16 set $AbsExecBase = (struct IntExecBase *)$AbsExecBase
19 document _sysbase_init
20 Initialize $AbsExecBase convenience variables
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)
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
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
45 Initialize debugging convenience variables
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", \
57 ((struct Library *)$lib)->lib_OpenCnt, \
59 set $lib = $lib->ln_Succ
63 List the current libraries in the system
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", \
74 ((struct Library *)$dev)->lib_OpenCnt, \
76 set $dev = $dev->ln_Succ
80 List the current devices in the system
85 set $res = ((struct ExecBase *)$AbsExecBase)->ResourceList.lh_Head
87 printf "---------------------------------------------------------------\n"
88 while ($res->ln_Succ != 0)
89 printf "%p %s\n", $res, $res->ln_Name
90 set $res = $res->ln_Succ
94 List the current resources in the system
99 set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
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", \
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
116 document residentlist
117 List the system resident list
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", \
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
140 List of tasks currently ready to run
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", \
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
163 List of tasks currently waiting for an event
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", \
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
182 Print out information about the currently running task.
187 printf "Segment Module\n"
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
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
210 if ($sh->addr != 0) && ($sh->size != 0)
211 printf "%p %2u %32s\n", $sh->addr, $i, $kicknode->Name
216 set $kicknode = $kicknode->Next
220 List of all the modules currently loaded in memory
227 #first search in modules loaded from disk
228 printf "Searching in the loaded modules...\n"
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
238 set $segnode = (struct segment *)$segnode->s_node.mln_Succ
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
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
266 set $kicknode = $kicknode->Next
270 #then in the resident list
272 printf "Searching in the resident list...\n"
275 set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
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
290 printf "No matching module for this address\n"
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
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.
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
318 -Reading symbols from contrib/Zune/Libs/muimaster.library...done.
320 -#0 0x4058d45b in strlen (ptr=0x80 <Address 0x80 out of bounds>) at strlen.c:45
321 -#1 0x00000000 in lastx.78 ()
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
341 printf "%p %p %9lu\n", $list->ti_Tag, $list->ti_Data, $list->ti_Data
342 set $list = $list + 1
347 document printtaglist
351 set logging file $arg0
352 set logging redirect on
353 set logging overwrite $arg1
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
372 shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
373 log_to_file loadseg.tmp on
374 printf "add-symbol-file "
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
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
394 set $segnode = (struct segment *)$segnode->s_node.mln_Succ
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
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
416 if ($shstrndx < 0xFF00)
417 set $shstr = $shstrndx
419 if ($shstrndx > 0xFFFF)
420 set $shstr = $shstrndx - (0x10000 - 0xFF00)
423 log_to_file segname.tmp on
424 printf "%s", $kicknode->Name
426 shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
427 log_to_file loadseg.tmp on
428 printf "add-symbol-file "
430 shell head -n1 segname.tmp >>loadseg.tmp
431 log_to_file loadseg.tmp off
432 printf " %p", $lowest
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
443 set $step = $step + 1
457 set $kicknode = $kicknode->Next
462 printf "No matching module for this address\n"
469 Loads the module that contains the given address
474 set $_kicknode = $_debug_KickList
476 while ($_kicknode != 0)
477 set $_eh = $_kicknode->eh
478 set $_sh = $_kicknode->sh
479 set $_shnum = $_eh->shnum
482 while ($_i < $_shnum)
483 if ($_i == 1) && ($_sh->addr != 0) && ($_sh->size != 0)
489 set $_kicknode = $_kicknode->Next
493 Loads the Kickstart (symbols)
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
506 set $_segnode = (struct segment *)$_segnode->s_node.mln_Succ
511 Loads all the modules (symbols)
519 Loads the symbols of the Kickstart and all modules
523 log_to_file frameinfo.tmp on
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
533 Loads the symbols for the given stack frame number
542 printf "\nEnter stack frame number to resolve or RETURN to stop: \n\n"
546 shell read _gdb_answer && echo $_gdb_answer | grep -E "[0-9]+" | sed "s/\(.*\)/set \$_answer=\1/" >frameinfo.tmp
559 Interactive multiple loading of symbols for given stack frame numbers
563 set $_frame_counter = 0
567 printf "Checking frame #%d\n", $_frame_counter
571 log_to_file loadseg.tmp on
575 # Check if frame exists
577 log_to_file frameinfo.tmp on
578 printf "shell grep \"#%d .*\" loadseg.tmp | sed \"s/#.*/set \\$_again = 1/\" >loadbt.tmp\n", $_frame_counter
586 # If frame is unresolved ("in ??") transform to "loadseg address"
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
595 set $_frame_counter = $_frame_counter + 1
596 if ($_frame_counter == 1000)
603 Tries to automatically load the symbols for all unresolved stack frames
611 printf "Hunk num. | Start addr | Size \n"
612 printf "----------+------------+------------\n"
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
621 Shows the segments chain of the given seglist
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"
629 #FIXME: The following assumes Linux x86
633 if $task->tc_State == 2
634 printf "WARNING: TS_RUN Task. Showing normal backtrace!\n"
636 set $esp = $task->tc_SPReg
637 set $taskcontext = (struct AROSCPUContext *)$task->tc_UnionETask.tc_ETask.et_RegFrame
638 set $eip = $taskcontext.regs.eip
648 Shows the backtrace of the given TS_READY/TS_WAIT task
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"
656 if $sem->ss_QueueCount == -1
657 printf "The semaphore is free\n"
659 if $sem->ss_Owner == 0
660 printf "The semaphore is locked in shared mode by one or more tasks\n"
662 printf "The semaphore is owned by task %p (%s)\n", $sem->ss_Owner, $sem->ss_Owner->tc_Node.ln_Name
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
677 printf"%p %s\n", $waitertask, $waitertask->tc_Node.ln_Name
678 set $waitnode = (struct SemaphoreRequest *)$waitnode->sr_Link.mln_Succ
684 Shows the owner of the given Exec Semaphore and the Wait Queue