revert commit 56204.
[AROS.git] / _gdbinit
blobac0a82be521e86f10741dae8098627d0ea954ab6
1 handle SIGUSR1 pass noprint nostop
2 handle SIGUSR2 pass noprint nostop
3 set follow-fork-mode child
5 define log_to_file
6   set logging file $arg0
7   set logging redirect on
8   set logging overwrite $arg1
9   set logging on
10 end
12 define end_log
13   set logging off
14 end
16 # Define $symbol = (type)addr if it exists,  undefined if not
17 define symbol_check
18   log_to_file symbol.tmp on
19   p $arg0
20   end_log
22   shell sed -i -e '/^[^\$]/d' -e 's/^\$[0-9]* =/set $'$arg0' =/' symbol.tmp
23   source symbol.tmp
24 end
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
35 # can't use it.
37 define _sysbase_init
38     init-if-undefined $AbsExecBase = 0
39     init-if-undefined $SysBase = 0
40     symbol_check AbsExecBase
41     symbol_check SysBase
42     if $SysBase != 0 && $AbsExecBase == 0
43         set $AbsExecBase = $SysBase
44     end
45     if $SysBase == 0 && $AbsExecBase != 0
46         set $SysBase = $AbsExecBase
47     end
48 end
49 document _sysbase_init
50 Initialize $AbsExecBase convenience variables
51 end
53 define _debug_init
54     _sysbase_init
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)
65         else
66            set $_debug_ModList = $Debug_ModList
67         end
68     end
69 end
70 document _debug_init
71 Initialize debugging convenience variables
72 end
74 define liblist
75     _sysbase_init
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", \
82         $lib, \
83         ((struct Library *)$lib)->lib_OpenCnt, \
84         $lib->ln_Name
85     set $lib = $lib->ln_Succ
86     end
87 end
88 document liblist
89 List the current libraries in the system
90 end
92 define devlist
93     _debug_init
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", \
99         $dev, \
100         ((struct Library *)$dev)->lib_OpenCnt, \
101         $dev->ln_Name
102     set $dev = $dev->ln_Succ
103     end
105 document devlist
106 List the current devices in the system
109 define resourcelist
110     _debug_init
111     set $res = ((struct ExecBase *)$AbsExecBase)->ResourceList.lh_Head
112     printf "Base     Name\n"
113     printf "---------------------------------------------------------------\n"
114     while ($res->ln_Succ != 0)
115     printf "%p %s\n", $res, $res->ln_Name
116     set $res = $res->ln_Succ
117     end
119 document resourcelist
120 List the current resources in the system
123 define residentlist
124     _debug_init
125     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
126     set $i = 0
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", \
133         $res, \
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
139     set $i = $i + 1
140     end
142 document residentlist
143 List the system resident list
146 define taskready
147     _debug_init
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", \
154         $task, \
155         $task->tc_SigWait, \
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
163     end
165 document taskready
166 List of tasks currently ready to run
169 define taskwait
170     _debug_init
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", \
177         $task, \
178         $task->tc_SigWait, \
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
186     end
188 document taskwait
189 List of tasks currently waiting for an event
192 define thistask
193     _debug_init
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", \
198     $task, \
199     $task->tc_SigWait, \
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
207 document thistask
208 Print out information about the currently running task.
211 define modlist
212     _debug_init
213     printf "Segment                                   Module\n"
215     if $_debug_ModList
216         printf "---------------------------------------------------------------------\n"
217         set $modnode = (module_t *)$_debug_ModList->mlh_Head
219         while ($modnode->m_node.mln_Succ != 0)
220             set $segidx = 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
225             end
227             set $modnode = (module_t *)$modnode->m_node.mln_Succ
228         end
229     end
231 document modlist
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
239     set $arg_mod = $arg1
240     set $find_segment_in_module_result = 0
241     set $local_minsegidx = 0
242     set $local_maxsegidx = $arg_mod->m_segcnt - 1
243     set $_again = 1
245     while ($_again == 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]
251                 loop_break
252             else
253                 set $local_minsegidx = $local_segidx + 1
254             end
255         else
256             set $local_maxsegidx = $local_segidx - 1
257         end
259         if $local_maxsegidx < $local_minsegidx
260             # Not found, aborting
261             loop_break
262         end
263     end
266 # Keep this function synchronized with decodelocation.c, FindSegment
267 define find_segment
268     _debug_init
269     set $find_segment_result = 0
271     if $_debug_ModList
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
282                         loop_break
283                     end
284                 end
285             end
286             set $modnode = (module_t *)$modnode->m_node.mln_Succ
287         end
288     end
291 define findaddr
292     _debug_init
293     set $cont = 1
295     #first search in modules loaded from disk
296     printf "Searching in the loaded modules...\n"
298     find_segment $arg0
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
303         set $cont = 0
304     end
306     #then in the resident list
307     if $cont
308         printf "Searching in the resident list...\n"
309     end
311     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
312     set $i = 0
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
319             set $cont = 0
320         end
322         set $i = $i + 1
323     end
325     if $cont
326         printf "No matching module for this address\n"
327     end
329 document findaddr
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
336 -   module it is:
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.
341 -Example:
343 -0x4058d45b in ?? ()
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
353 -(y or n) y
354 -Reading symbols from contrib/Zune/Libs/muimaster.library.dbg...done.
355 -(gdb) bt
356 -#0  0x4058d45b in strlen (ptr=0x80 <Address 0x80 out of bounds>) at strlen.c:45
357 -#1  0x00000000 in lastx.78 ()
360 define printtaglist
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
376     else
377         printf "%p  %p      %9lu\n", $list->ti_Tag, $list->ti_Data, $list->ti_Data
378         set $list = $list + 1
379     end
380     end
381     printf "TAG_DONE\n"
383 document printtaglist
386 define loadmod
387     set pagination off
388     set $this_mod = $arg0
390     log_to_file segname.tmp on
391     printf "%s", $this_mod->m_name
392     end_log
393     shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
394     log_to_file loadseg.tmp on
395     printf "add-symbol-file \""
396     end_log
397     shell head -n1 segname.tmp >>loadseg.tmp
398     log_to_file loadseg.tmp off
399     printf "\" %s", $this_mod->m_seggdbhlp
400     end_log
402     source loadseg.tmp
403     set pagination on
406 define loadseg
407     _debug_init
408     dont-repeat
409     if $_debug_ModList
410         set $step = 1
412         find_segment $arg0
414         if $find_segment_result
415             # This is workaround for some flushing problem when loadseg.tmp had module name before command
416             printf "\n"
418             loadmod $find_segment_result->s_mod
420             set $step = 2
421         end
423         if $step < 2
424             printf "No matching module for this address\n"
425         end
427     end
429 document loadseg
430 Loads the module that contains the given address
433 define loadmods
434     _debug_init
436     if $_debug_ModList
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
442         end
443     end
445 document loadmods
446 Loads all the modules (symbols)
449 define loadframe
450     log_to_file frameinfo.tmp on
451     info frame $arg0
452     end_log
453     
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
456     
457     source frameinfo.tmp
459 document loadframe
460 Loads the symbols for the given stack frame number
463 define loadframes
464     set $_again = 1
465     printf "\n\n"
466     
467     while ($_again == 1)
468         bt
469         printf "\nEnter stack frame number to resolve or RETURN to stop: \n\n"
471         set $_answer = 1000
473         shell read _gdb_answer && echo $_gdb_answer | grep -E "[0-9]+" | sed "s/\(.*\)/set \$_answer=\1/" >frameinfo.tmp
475         source frameinfo.tmp
476         printf "\n\n"
478         if $_answer == 1000
479             set $_again = 0
480         else
481             loadframe $_answer
482         end
483     end
485 document loadframes
486 Interactive multiple loading of symbols for given stack frame numbers
489 define loadbt
490     set $_frame_counter = 0
492     set $_again = 1
493     while ($_again == 1)
494         printf "Checking frame #%d\n", $_frame_counter
496         set $_again = 0
498         log_to_file loadseg.tmp on
499         set pagination off
500         bt
501         end_log
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
507         end_log
509         source frameinfo.tmp
510         source loadbt.tmp
512         if $_again == 1
514             # If frame is unresolved ("in ??") transform to "loadseg address"
515             
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
518             end_log
520             source frameinfo.tmp
521             source loadbt.tmp
523             set $_frame_counter = $_frame_counter + 1
524             if ($_frame_counter == 1000)
525                 set $_again = 0
526             end
527         end
528     end
530     set pagination on
532 document loadbt
533 Tries to automatically load the symbols for all unresolved stack frames
536 define seglistdump
537     _debug_init
538     set $nextseg = $arg0
539     set $count   = 1
541     printf "Hunk num. | Start addr | Size       \n"
542     printf "----------+------------+------------\n"
543     while $nextseg
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
548     end
550 document seglistdump
551 Shows the segments chain of the given seglist
554 define bttask
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"
558     else
559         #FIXME: The following assumes Linux x86
560         set $old_esp = $esp
561         set $old_eip = $eip
562         
563         if $task->tc_State == 2
564             printf "WARNING: TS_RUN Task. Showing normal backtrace!\n"
565         else
566             set $esp = $task->tc_SPReg
567             set $taskcontext = (struct AROSCPUContext *)$task->tc_UnionETask.tc_ETask.et_RegFrame
568             set $eip = $taskcontext.regs.eip
569         end
570         
571         bt
573         set $esp = $old_esp
574         set $eip = $old_eip
575     end
577 document bttask
578 Shows the backtrace of the given TS_READY/TS_WAIT task
581 define semowner
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"
585     else
586         if $sem->ss_QueueCount == -1
587             printf "The semaphore is free\n"
588         else
589             if $sem->ss_Owner == 0
590                 printf "The semaphore is locked in shared mode by one or more tasks\n"
591             else
592                     printf "The semaphore is owned by task %p (%s)\n", $sem->ss_Owner, $sem->ss_Owner->tc_Node.ln_Name
593             end
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
603                     printf " SHARED    "
604                 else
605                     printf " EXCLUSIVE "
606                 end
607                 printf"%p %s\n", $waitertask, $waitertask->tc_Node.ln_Name
608                 set $waitnode = (struct SemaphoreRequest *)$waitnode->sr_Link.mln_Succ
609             end
610         end
611     end
613 document semowner
614 Shows the owner of the given Exec Semaphore and the Wait Queue