1 handle SIGUSR1 pass noprint nostop
2 handle SIGUSR2 pass noprint nostop
3 set follow-fork-mode child
7 set logging redirect on
8 set logging overwrite $arg1
16 # Define $symbol = (type)addr if it exists, undefined if not
18 log_to_file symbol.tmp on
22 shell sed -i -e '/^[^\$]/d' -e 's/^\$[0-9]* =/set $'$arg0' =/' symbol.tmp
26 # This is a bit tricky, because we have several cases,
27 # and gdb has no easy 'is this symbol defined' tests.
29 # Case 1: Hosted AROSBootstrap (ie linux-i386)
30 # Provides SysBase, Debug_ModList, and Debug_KickList
31 # Case 2: ROM (ie amiga-m68k)
32 # Provides AbsExecBase and SysBase
34 # AROSBootstrap does not define 'struct IntExecBase', so we
38 init-if-undefined $AbsExecBase = 0
39 init-if-undefined $SysBase = 0
40 symbol_check AbsExecBase
42 if $SysBase != 0 && $AbsExecBase == 0
43 set $AbsExecBase = $SysBase
45 if $SysBase == 0 && $AbsExecBase != 0
46 set $SysBase = $AbsExecBase
49 document _sysbase_init
50 Initialize $AbsExecBase convenience variables
55 symbol_check Debug_ModList
57 init-if-undefined $Debug_ModList = 0
58 init-if-undefined $_debug_DebugBase = 0
60 if $_debug_DebugBase == 0
61 if $Debug_ModList == 0
62 set $_debug_DebugBase = (struct DebugBase *)($AbsExecBase->DebugBase)
63 # This is the case for debugging a ROM
64 set $_debug_ModList = &($_debug_DebugBase->db_Modules)
66 set $_debug_ModList = $Debug_ModList
71 Initialize debugging convenience variables
76 set $lib = ((struct ExecBase *)$AbsExecBase)->LibList.lh_Head
78 printf "Base OpenC Name\n"
79 printf "---------------------------------------------------------------\n"
80 while ($lib->ln_Succ != 0)
81 printf "%p %5d %s\n", \
83 ((struct Library *)$lib)->lib_OpenCnt, \
85 set $lib = $lib->ln_Succ
89 List the current libraries in the system
94 set $dev = ((struct ExecBase *)$AbsExecBase)->DeviceList.lh_Head
95 printf "Base OpenC Name\n"
96 printf "---------------------------------------------------------------\n"
97 while ($dev->ln_Succ != 0)
98 printf "%p %5d %s\n", \
100 ((struct Library *)$dev)->lib_OpenCnt, \
102 set $dev = $dev->ln_Succ
106 List the current devices in the system
111 set $res = ((struct ExecBase *)$AbsExecBase)->ResourceList.lh_Head
113 printf "---------------------------------------------------------------\n"
114 while ($res->ln_Succ != 0)
115 printf "%p %s\n", $res, $res->ln_Name
116 set $res = $res->ln_Succ
119 document resourcelist
120 List the current resources in the system
125 set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
128 printf "Address Pri Flags Vers Type Name\n"
129 printf "--------------------------------------------------------------\n"
130 while (($resp)[$i] != 0)
131 set $res = ($resp)[$i]
132 printf "%p %4d %02x %3d %3d %s\n", \
134 ((struct Resident *)$res)->rt_Pri, \
135 ((struct Resident *)$res)->rt_Flags, \
136 ((struct Resident *)$res)->rt_Version, \
137 ((struct Resident *)$res)->rt_Type, \
138 ((struct Resident *)$res)->rt_Name
142 document residentlist
143 List the system resident list
148 set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskReady.lh_Head
150 printf "Task SigWait SigRecvd StkSize StkUsed Pri Type Name\n"
151 printf "-----------------------------------------------------------------------------\n"
152 while ($task->tc_Node.ln_Succ != 0)
153 printf "%p %p %p %8d %8d %3d %3ld %s\n", \
156 $task->tc_SigRecvd, \
157 $task->tc_SPUpper - $task->tc_SPLower, \
158 $task->tc_SPUpper - $task->tc_SPReg, \
159 $task->tc_Node.ln_Pri, \
160 $task->tc_Node.ln_Type, \
161 $task->tc_Node.ln_Name
162 set $task = (struct Task *)$task->tc_Node.ln_Succ
166 List of tasks currently ready to run
171 set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskWait.lh_Head
173 printf "Task SigWait SigRecvd StkSize StkUsed Pri Type Name\n"
174 printf "-----------------------------------------------------------------------------\n"
175 while ($task->tc_Node.ln_Succ != 0)
176 printf "%p %p %p %8d %8d %3d %3ld %s\n", \
179 $task->tc_SigRecvd, \
180 $task->tc_SPUpper - $task->tc_SPLower, \
181 $task->tc_SPUpper - $task->tc_SPReg, \
182 $task->tc_Node.ln_Pri, \
183 $task->tc_Node.ln_Type, \
184 $task->tc_Node.ln_Name
185 set $task = (struct Task *)$task->tc_Node.ln_Succ
189 List of tasks currently waiting for an event
194 set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->ThisTask
195 printf "Task SigWait SigRecvd StkSize StkUsed Pri Type Name\n"
196 printf "-----------------------------------------------------------------------------\n"
197 printf "%p %p %p %8d %8d %3d %3ld %s\n", \
200 $task->tc_SigRecvd, \
201 $task->tc_SPUpper - $task->tc_SPLower, \
202 $task->tc_SPUpper - $task->tc_SPReg, \
203 $task->tc_Node.ln_Pri, \
204 $task->tc_Node.ln_Type, \
205 $task->tc_Node.ln_Name
208 Print out information about the currently running task.
213 printf "Segment Module\n"
216 printf "---------------------------------------------------------------------\n"
217 set $modnode = (module_t *)$_debug_ModList->mlh_Head
219 while ($modnode->m_node.mln_Succ != 0)
221 while ($segidx < $modnode->m_segcnt)
222 set $segnode = $modnode->m_segments[$segidx]
223 printf "%p %12s %2u %42s\n", $segnode->s_lowest, $segnode->s_name, $segnode->s_num, $segnode->s_mod->m_name
224 set $segidx = $segidx + 1
227 set $modnode = (module_t *)$modnode->m_node.mln_Succ
232 List of all the modules currently loaded in memory
235 # Execute a binary search over sorter array of segments
236 # Keep this function synchronized with decodelocation.c, FindSegmentInModule
237 define find_segment_in_module
238 set $arg_address = $arg0
240 set $find_segment_in_module_result = 0
241 set $local_minsegidx = 0
242 set $local_maxsegidx = $arg_mod->m_segcnt - 1
246 set $local_segidx = ($local_maxsegidx + $local_minsegidx) / 2
248 if $arg_mod->m_segments[$local_segidx]->s_lowest <= $arg_address
249 if $arg_mod->m_segments[$local_segidx]->s_highest >= $arg_address
250 set $find_segment_in_module_result = $arg_mod->m_segments[$local_segidx]
253 set $local_minsegidx = $local_segidx + 1
256 set $local_maxsegidx = $local_segidx - 1
259 if $local_maxsegidx < $local_minsegidx
260 # Not found, aborting
266 # Keep this function synchronized with decodelocation.c, FindSegment
269 set $find_segment_result = 0
272 set $modnode = (module_t *)$_debug_ModList->mlh_Head
274 while ($modnode->m_node.mln_Succ != 0)
275 if !($modnode->m_gaplowest <= $arg0 && $modnode->m_gaphighest >= $arg0)
276 if $modnode->m_lowest <= $arg0 && $modnode->m_highest >= $arg0
278 find_segment_in_module $arg0 $modnode
280 if $find_segment_in_module_result
281 set $find_segment_result = $find_segment_in_module_result
286 set $modnode = (module_t *)$modnode->m_node.mln_Succ
295 #first search in modules loaded from disk
296 printf "Searching in the loaded modules...\n"
300 if $find_segment_result
301 set $segnode = $find_segment_result
302 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
306 #then in the resident list
308 printf "Searching in the resident list...\n"
311 set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
314 while (($resp)[$i] != 0) && $cont
315 set $res = ($resp)[$i]
317 if ($arg0 >= $res) && ($arg0 <= $res->rt_EndSkip)
318 printf "Address found in %s, which resides at %p\n", $res->rt_Name, $res
326 printf "No matching module for this address\n"
330 -Shows the module that contains the given address
332 -To debug a problem in AROS, do the following:
334 -1. Get a stacktrace with bt or similar.
335 -2. Use findaddr with such an address to find out in which
337 -3. Use add-symbol-file to load that modules symbols.
338 -4. Now you can run bt (or similar) again and you should see the
339 - addresses resolved as symbols.
345 -(gdb) findaddr 0x4058d45b
347 -Searching in the loaded modules...
348 -Address found in Workbench:contrib/Zune/Libs/muimaster.library, which is loaded at 0x405379a4.
349 -If this is an executable, its .text section starts at 0x405379b0.
350 -(gdb) add-symbol-file contrib/Zune/Libs/muimaster.library.dbg 0x405379b0
351 -add symbol table from file "contrib/Zune/Libs/muimaster.library.dbg" at
352 - .text_addr = 0x405379b0
354 -Reading symbols from contrib/Zune/Libs/muimaster.library.dbg...done.
356 -#0 0x4058d45b in strlen (ptr=0x80 <Address 0x80 out of bounds>) at strlen.c:45
357 -#1 0x00000000 in lastx.78 ()
361 set $list = (struct TagItem *)$arg0
363 printf "Tag Data (Hex) Data (Dec)\n"
364 printf "--------------------------------------\n"
366 while $list->ti_Tag != 0
367 # Handle the possible control tag...
368 if $list->ti_Tag == 1
369 printf "TAG_IGNORE\n"
370 else if $list->ti_Tag == 2
371 printf "TAG_MORE %p\n", $list->ti_Data
372 set $list = (struct TagItem *)$list->ti_Data
373 else if $list->ti_Tag == 3
374 printf "TAG_SKIP %d\n", $list->ti_Data
375 set $list = $list + $list->ti_Tag + 1
377 printf "%p %p %9lu\n", $list->ti_Tag, $list->ti_Data, $list->ti_Data
378 set $list = $list + 1
383 document printtaglist
388 set $this_mod = $arg0
390 log_to_file segname.tmp on
391 printf "%s", $this_mod->m_name
393 shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
394 log_to_file loadseg.tmp on
395 printf "add-symbol-file \""
397 shell head -n1 segname.tmp >>loadseg.tmp
398 log_to_file loadseg.tmp off
399 printf "\" %s", $this_mod->m_seggdbhlp
414 if $find_segment_result
415 # This is workaround for some flushing problem when loadseg.tmp had module name before command
418 loadmod $find_segment_result->s_mod
424 printf "No matching module for this address\n"
430 Loads the module that contains the given address
437 set $loadmods_modnode = (module_t *)$_debug_ModList->mlh_Head
439 while ($loadmods_modnode->m_node.mln_Succ != 0)
440 loadmod $loadmods_modnode
441 set $loadmods_modnode = (module_t *)$loadmods_modnode->m_node.mln_Succ
446 Loads all the modules (symbols)
450 log_to_file frameinfo.tmp on
454 shell grep "eip =" frameinfo.tmp >loadseg.tmp
455 shell sed -e 's/eip = \(0x[0-9,a-f]*\).*/loadseg \1/' loadseg.tmp >frameinfo.tmp
460 Loads the symbols for the given stack frame number
469 printf "\nEnter stack frame number to resolve or RETURN to stop: \n\n"
473 shell read _gdb_answer && echo $_gdb_answer | grep -E "[0-9]+" | sed "s/\(.*\)/set \$_answer=\1/" >frameinfo.tmp
486 Interactive multiple loading of symbols for given stack frame numbers
490 set $_frame_counter = 0
494 printf "Checking frame #%d\n", $_frame_counter
498 log_to_file loadseg.tmp on
503 # Check if frame exists
505 log_to_file frameinfo.tmp on
506 printf "shell grep \"#%d .*\" loadseg.tmp | sed \"s/#.*/set \\$_again = 1/\" >loadbt.tmp\n", $_frame_counter
514 # If frame is unresolved ("in ??") transform to "loadseg address"
516 log_to_file frameinfo.tmp on
517 printf "shell grep \"#%d .* in ??\" loadseg.tmp | sed \"s/#.*\\(0x[0-9,a-f]*\\) .*/loadseg \\1/\" >loadbt.tmp\n", $_frame_counter
523 set $_frame_counter = $_frame_counter + 1
524 if ($_frame_counter == 1000)
533 Tries to automatically load the symbols for all unresolved stack frames
541 printf "Hunk num. | Start addr | Size \n"
542 printf "----------+------------+------------\n"
544 printf "%9d | %p | %10d\n", $count, $nextseg + sizeof(BPTR), *((ULONG *)$nextseg - 1) - sizeof(BPTR)
546 set $nextseg = *(BPTR *)$nextseg
547 set $count = $count+1
551 Shows the segments chain of the given seglist
555 set $task = (struct Task *)$arg0
556 if ($task->tc_Node.ln_Type != 1) && ($task->tc_Node.ln_Type != 13)
557 printf "ERROR: Given address does not look like a task or process!\n"
559 #FIXME: The following assumes Linux x86
563 if $task->tc_State == 2
564 printf "WARNING: TS_RUN Task. Showing normal backtrace!\n"
566 set $esp = $task->tc_SPReg
567 set $taskcontext = (struct AROSCPUContext *)$task->tc_UnionETask.tc_ETask.et_RegFrame
568 set $eip = $taskcontext.regs.eip
578 Shows the backtrace of the given TS_READY/TS_WAIT task
582 set $sem = (struct SignalSemaphore *)$arg0
583 if $sem->ss_Link.ln_Type != 15
584 printf "ERROR: Given address does not look like a semaphore!\n"
586 if $sem->ss_QueueCount == -1
587 printf "The semaphore is free\n"
589 if $sem->ss_Owner == 0
590 printf "The semaphore is locked in shared mode by one or more tasks\n"
592 printf "The semaphore is owned by task %p (%s)\n", $sem->ss_Owner, $sem->ss_Owner->tc_Node.ln_Name
595 printf "\nWait Queue:\n\n"
597 set $waitnode = (struct SemaphoreRequest *)$sem->ss_WaitQueue.mlh_Head
599 while ($waitnode->sr_Link.mln_Succ != 0)
600 set $waitertask = $waitnode->sr_Waiter
601 if (int)$waitertask & 1
602 set $waitertask = $waitertask & ~1
607 printf"%p %s\n", $waitertask, $waitertask->tc_Node.ln_Name
608 set $waitnode = (struct SemaphoreRequest *)$waitnode->sr_Link.mln_Succ
614 Shows the owner of the given Exec Semaphore and the Wait Queue