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)
38 # This is the case for debugging a bootstrap
39 init-if-undefined $_debug_ModList = Debug_ModList
43 Initialize debugging convenience variables
48 set $lib = ((struct ExecBase *)$AbsExecBase)->LibList.lh_Head
50 printf "Base OpenC Name\n"
51 printf "---------------------------------------------------------------\n"
52 while ($lib->ln_Succ != 0)
53 printf "%p %5d %s\n", \
55 ((struct Library *)$lib)->lib_OpenCnt, \
57 set $lib = $lib->ln_Succ
61 List the current libraries in the system
66 set $dev = ((struct ExecBase *)$AbsExecBase)->DeviceList.lh_Head
67 printf "Base OpenC Name\n"
68 printf "---------------------------------------------------------------\n"
69 while ($dev->ln_Succ != 0)
70 printf "%p %5d %s\n", \
72 ((struct Library *)$dev)->lib_OpenCnt, \
74 set $dev = $dev->ln_Succ
78 List the current devices in the system
83 set $res = ((struct ExecBase *)$AbsExecBase)->ResourceList.lh_Head
85 printf "---------------------------------------------------------------\n"
86 while ($res->ln_Succ != 0)
87 printf "%p %s\n", $res, $res->ln_Name
88 set $res = $res->ln_Succ
92 List the current resources in the system
97 set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
100 printf "Address Pri Flags Vers Type Name\n"
101 printf "--------------------------------------------------------------\n"
102 while (($resp)[$i] != 0)
103 set $res = ($resp)[$i]
104 printf "%p %4d %02x %3d %3d %s\n", \
106 ((struct Resident *)$res)->rt_Pri, \
107 ((struct Resident *)$res)->rt_Flags, \
108 ((struct Resident *)$res)->rt_Version, \
109 ((struct Resident *)$res)->rt_Type, \
110 ((struct Resident *)$res)->rt_Name
114 document residentlist
115 List the system resident list
120 set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskReady.lh_Head
122 printf "Task SigWait SigRecvd StkSize StkUsed Pri Type Name\n"
123 printf "-----------------------------------------------------------------------------\n"
124 while ($task->tc_Node.ln_Succ != 0)
125 printf "%p %p %p %8d %8d %3d %3ld %s\n", \
128 $task->tc_SigRecvd, \
129 $task->tc_SPUpper - $task->tc_SPLower, \
130 $task->tc_SPUpper - $task->tc_SPReg, \
131 $task->tc_Node.ln_Pri, \
132 $task->tc_Node.ln_Type, \
133 $task->tc_Node.ln_Name
134 set $task = (struct Task *)$task->tc_Node.ln_Succ
138 List of tasks currently ready to run
143 set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskWait.lh_Head
145 printf "Task SigWait SigRecvd StkSize StkUsed Pri Type Name\n"
146 printf "-----------------------------------------------------------------------------\n"
147 while ($task->tc_Node.ln_Succ != 0)
148 printf "%p %p %p %8d %8d %3d %3ld %s\n", \
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
157 set $task = (struct Task *)$task->tc_Node.ln_Succ
161 List of tasks currently waiting for an event
166 set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->ThisTask
167 printf "Task SigWait SigRecvd StkSize StkUsed Pri Type Name\n"
168 printf "-----------------------------------------------------------------------------\n"
169 printf "%p %p %p %8d %8d %3d %3ld %s\n", \
172 $task->tc_SigRecvd, \
173 $task->tc_SPUpper - $task->tc_SPLower, \
174 $task->tc_SPUpper - $task->tc_SPReg, \
175 $task->tc_Node.ln_Pri, \
176 $task->tc_Node.ln_Type, \
177 $task->tc_Node.ln_Name
180 Print out information about the currently running task.
185 printf "Segment Module\n"
188 printf "---------------------------------------------------------------------\n"
189 set $modnode = (module_t *)$_debug_ModList->mlh_Head
191 while ($modnode->m_node.mln_Succ != 0)
193 while ($segidx < $modnode->m_segcnt)
194 set $segnode = $modnode->m_segments[$segidx]
195 printf "%p %12s %2u %42s\n", $segnode->s_lowest, $segnode->s_name, $segnode->s_num, $segnode->s_mod->m_name
196 set $segidx = $segidx + 1
199 set $modnode = (module_t *)$modnode->m_node.mln_Succ
204 List of all the modules currently loaded in memory
207 # Execute a binary search over sorter array of segments
208 # Keep this function synchronized with decodelocation.c, FindSegmentInModule
209 define find_segment_in_module
210 set $arg_address = $arg0
212 set $find_segment_in_module_result = 0
213 set $local_minsegidx = 0
214 set $local_maxsegidx = $arg_mod->m_segcnt - 1
218 set $local_segidx = ($local_maxsegidx + $local_minsegidx) / 2
220 if $arg_mod->m_segments[$local_segidx]->s_lowest <= $arg_address
221 if $arg_mod->m_segments[$local_segidx]->s_highest >= $arg_address
222 set $find_segment_in_module_result = $arg_mod->m_segments[$local_segidx]
225 set $local_minsegidx = $local_segidx + 1
228 set $local_maxsegidx = $local_segidx - 1
231 if $local_maxsegidx < $local_minsegidx
232 # Not found, aborting
238 # Keep this function synchronized with decodelocation.c, FindSegment
241 set $find_segment_result = 0
244 set $modnode = (module_t *)$_debug_ModList->mlh_Head
246 while ($modnode->m_node.mln_Succ != 0)
247 if !($modnode->m_gaplowest <= $arg0 && $modnode->m_gaphighest >= $arg0)
248 if $modnode->m_lowest <= $arg0 && $modnode->m_highest >= $arg0
250 find_segment_in_module $arg0 $modnode
252 if $find_segment_in_module_result
253 set $find_segment_result = $find_segment_in_module_result
258 set $modnode = (module_t *)$modnode->m_node.mln_Succ
267 #first search in modules loaded from disk
268 printf "Searching in the loaded modules...\n"
272 if $find_segment_result
273 set $segnode = $find_segment_result
274 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
278 #then in the resident list
280 printf "Searching in the resident list...\n"
283 set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
286 while (($resp)[$i] != 0) && $cont
287 set $res = ($resp)[$i]
289 if ($arg0 >= $res) && ($arg0 <= $res->rt_EndSkip)
290 printf "Address found in %s, which resides at %p\n", $res->rt_Name, $res
298 printf "No matching module for this address\n"
302 -Shows the module that contains the given address
304 -To debug a problem in AROS, do the following:
306 -1. Get a stacktrace with bt or similar.
307 -2. Use findaddr with such an address to find out in which
309 -3. Use add-symbol-file to load that modules symbols.
310 -4. Now you can run bt (or similar) again and you should see the
311 - addresses resolved as symbols.
317 -(gdb) findaddr 0x4058d45b
319 -Searching in the loaded modules...
320 -Address found in Workbench:contrib/Zune/Libs/muimaster.library, which is loaded at 0x405379a4.
321 -If this is an executable, its .text section starts at 0x405379b0.
322 -(gdb) add-symbol-file contrib/Zune/Libs/muimaster.library 0x405379b0
323 -add symbol table from file "contrib/Zune/Libs/muimaster.library" at
324 - .text_addr = 0x405379b0
326 -Reading symbols from contrib/Zune/Libs/muimaster.library...done.
328 -#0 0x4058d45b in strlen (ptr=0x80 <Address 0x80 out of bounds>) at strlen.c:45
329 -#1 0x00000000 in lastx.78 ()
333 set $list = (struct TagItem *)$arg0
335 printf "Tag Data (Hex) Data (Dec)\n"
336 printf "--------------------------------------\n"
338 while $list->ti_Tag != 0
339 # Handle the possible control tag...
340 if $list->ti_Tag == 1
341 printf "TAG_IGNORE\n"
342 else if $list->ti_Tag == 2
343 printf "TAG_MORE %p\n", $list->ti_Data
344 set $list = (struct TagItem *)$list->ti_Data
345 else if $list->ti_Tag == 3
346 printf "TAG_SKIP %d\n", $list->ti_Data
347 set $list = $list + $list->ti_Tag + 1
349 printf "%p %p %9lu\n", $list->ti_Tag, $list->ti_Data, $list->ti_Data
350 set $list = $list + 1
355 document printtaglist
359 set logging file $arg0
360 set logging redirect on
361 set logging overwrite $arg1
371 set $this_mod = $arg0
373 log_to_file segname.tmp on
374 printf "%s", $this_mod->m_name
376 shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
377 log_to_file loadseg.tmp on
378 printf "add-symbol-file "
380 shell head -n1 segname.tmp >>loadseg.tmp
381 log_to_file loadseg.tmp off
382 printf " %s", $this_mod->m_seggdbhlp
397 if $find_segment_result
398 # This is workaround for some flushing problem when loadseg.tmp had module name before command
401 loadmod $find_segment_result->s_mod
407 printf "No matching module for this address\n"
413 Loads the module that contains the given address
420 set $loadmods_modnode = (module_t *)$_debug_ModList->mlh_Head
422 while ($loadmods_modnode->m_node.mln_Succ != 0)
423 loadmod $loadmods_modnode
424 set $loadmods_modnode = (module_t *)$loadmods_modnode->m_node.mln_Succ
429 Loads all the modules (symbols)
433 log_to_file frameinfo.tmp on
437 shell grep "eip =" frameinfo.tmp >loadseg.tmp
438 shell sed -e 's/eip = \(0x[0-9,a-f]*\).*/loadseg \1/' loadseg.tmp >frameinfo.tmp
443 Loads the symbols for the given stack frame number
452 printf "\nEnter stack frame number to resolve or RETURN to stop: \n\n"
456 shell read _gdb_answer && echo $_gdb_answer | grep -E "[0-9]+" | sed "s/\(.*\)/set \$_answer=\1/" >frameinfo.tmp
469 Interactive multiple loading of symbols for given stack frame numbers
473 set $_frame_counter = 0
477 printf "Checking frame #%d\n", $_frame_counter
481 log_to_file loadseg.tmp on
486 # Check if frame exists
488 log_to_file frameinfo.tmp on
489 printf "shell grep \"#%d .*\" loadseg.tmp | sed \"s/#.*/set \\$_again = 1/\" >loadbt.tmp\n", $_frame_counter
497 # If frame is unresolved ("in ??") transform to "loadseg address"
499 log_to_file frameinfo.tmp on
500 printf "shell grep \"#%d .* in ??\" loadseg.tmp | sed \"s/#.*\\(0x[0-9,a-f]*\\) .*/loadseg \\1/\" >loadbt.tmp\n", $_frame_counter
506 set $_frame_counter = $_frame_counter + 1
507 if ($_frame_counter == 1000)
516 Tries to automatically load the symbols for all unresolved stack frames
524 printf "Hunk num. | Start addr | Size \n"
525 printf "----------+------------+------------\n"
527 printf "%9d | %p | %10d\n", $count, $nextseg + sizeof(BPTR), *((ULONG *)$nextseg - 1) - sizeof(BPTR)
529 set $nextseg = *(BPTR *)$nextseg
530 set $count = $count+1
534 Shows the segments chain of the given seglist
538 set $task = (struct Task *)$arg0
539 if ($task->tc_Node.ln_Type != 1) && ($task->tc_Node.ln_Type != 13)
540 printf "ERROR: Given address does not look like a task or process!\n"
542 #FIXME: The following assumes Linux x86
546 if $task->tc_State == 2
547 printf "WARNING: TS_RUN Task. Showing normal backtrace!\n"
549 set $esp = $task->tc_SPReg
550 set $taskcontext = (struct AROSCPUContext *)$task->tc_UnionETask.tc_ETask.et_RegFrame
551 set $eip = $taskcontext.regs.eip
561 Shows the backtrace of the given TS_READY/TS_WAIT task
565 set $sem = (struct SignalSemaphore *)$arg0
566 if $sem->ss_Link.ln_Type != 15
567 printf "ERROR: Given address does not look like a semaphore!\n"
569 if $sem->ss_QueueCount == -1
570 printf "The semaphore is free\n"
572 if $sem->ss_Owner == 0
573 printf "The semaphore is locked in shared mode by one or more tasks\n"
575 printf "The semaphore is owned by task %p (%s)\n", $sem->ss_Owner, $sem->ss_Owner->tc_Node.ln_Name
578 printf "\nWait Queue:\n\n"
580 set $waitnode = (struct SemaphoreRequest *)$sem->ss_WaitQueue.mlh_Head
582 while ($waitnode->sr_Link.mln_Succ != 0)
583 set $waitertask = $waitnode->sr_Waiter
584 if (int)$waitertask & 1
585 set $waitertask = $waitertask & ~1
590 printf"%p %s\n", $waitertask, $waitertask->tc_Node.ln_Name
591 set $waitnode = (struct SemaphoreRequest *)$waitnode->sr_Link.mln_Succ
597 Shows the owner of the given Exec Semaphore and the Wait Queue