_gdbinit: Add 'symbol_check' define
[AROS.git] / _gdbinit
blob85a08fb558565279ae69196fce310007de48d3bb
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 define _sysbase_init
35     init-if-undefined $AbsExecBase = *(struct IntExecBase **)&SysBase
36 end
37 document _sysbase_init
38 Initialize $AbsExecBase convenience variables
39 end
41 define _debug_init
42     _sysbase_init
43     init-if-undefined $_debug_DebugBase = 0
45     if $AbsExecBase != 0 && $_debug_DebugBase == 0
46         set $_debug_DebugBase = (struct DebugBase *)($AbsExecBase->DebugBase)
47     end
49     if $_debug_DebugBase != 0
50         set $_debug_DebugBase = (struct DebugBase *)($_debug_DebugBase)
51         # This is the case for debugging a ROM
52         set $_debug_ModList = &($_debug_DebugBase->db_Modules)
53     else
54         # This is the case for debugging a bootstrap
55         init-if-undefined $_debug_ModList = Debug_ModList
56     end
57 end
58 document _debug_init
59 Initialize debugging convenience variables
60 end
62 define liblist
63     _sysbase_init
64     set $lib = ((struct ExecBase *)$AbsExecBase)->LibList.lh_Head
66     printf "Base     OpenC   Name\n"
67     printf "---------------------------------------------------------------\n"
68     while ($lib->ln_Succ != 0)
69     printf "%p %5d   %s\n", \
70         $lib, \
71         ((struct Library *)$lib)->lib_OpenCnt, \
72         $lib->ln_Name
73     set $lib = $lib->ln_Succ
74     end
75 end
76 document liblist
77 List the current libraries in the system
78 end
80 define devlist
81     _debug_init
82     set $dev = ((struct ExecBase *)$AbsExecBase)->DeviceList.lh_Head
83     printf "Base     OpenC   Name\n"
84     printf "---------------------------------------------------------------\n"
85     while ($dev->ln_Succ != 0)
86     printf "%p %5d   %s\n", \
87         $dev, \
88         ((struct Library *)$dev)->lib_OpenCnt, \
89         $dev->ln_Name
90     set $dev = $dev->ln_Succ
91     end
92 end
93 document devlist
94 List the current devices in the system
95 end
97 define resourcelist
98     _debug_init
99     set $res = ((struct ExecBase *)$AbsExecBase)->ResourceList.lh_Head
100     printf "Base     Name\n"
101     printf "---------------------------------------------------------------\n"
102     while ($res->ln_Succ != 0)
103     printf "%p %s\n", $res, $res->ln_Name
104     set $res = $res->ln_Succ
105     end
107 document resourcelist
108 List the current resources in the system
111 define residentlist
112     _debug_init
113     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
114     set $i = 0
116     printf "Address    Pri Flags Vers Type  Name\n"
117     printf "--------------------------------------------------------------\n"
118     while (($resp)[$i] != 0)
119     set $res = ($resp)[$i]
120     printf "%p  %4d    %02x  %3d  %3d  %s\n", \
121         $res, \
122         ((struct Resident *)$res)->rt_Pri, \
123         ((struct Resident *)$res)->rt_Flags, \
124         ((struct Resident *)$res)->rt_Version, \
125         ((struct Resident *)$res)->rt_Type, \
126         ((struct Resident *)$res)->rt_Name
127     set $i = $i + 1
128     end
130 document residentlist
131 List the system resident list
134 define taskready
135     _debug_init
136     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskReady.lh_Head
138     printf "Task     SigWait  SigRecvd StkSize   StkUsed Pri Type Name\n"
139     printf "-----------------------------------------------------------------------------\n"
140     while ($task->tc_Node.ln_Succ != 0)
141     printf "%p %p %p %8d %8d %3d  %3ld %s\n", \
142         $task, \
143         $task->tc_SigWait, \
144         $task->tc_SigRecvd, \
145         $task->tc_SPUpper - $task->tc_SPLower, \
146         $task->tc_SPUpper - $task->tc_SPReg, \
147         $task->tc_Node.ln_Pri, \
148         $task->tc_Node.ln_Type, \
149         $task->tc_Node.ln_Name
150     set $task = (struct Task *)$task->tc_Node.ln_Succ
151     end
153 document taskready
154 List of tasks currently ready to run
157 define taskwait
158     _debug_init
159     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->TaskWait.lh_Head
161     printf "Task     SigWait  SigRecvd StkSize   StkUsed Pri Type Name\n"
162     printf "-----------------------------------------------------------------------------\n"
163     while ($task->tc_Node.ln_Succ != 0)
164     printf "%p %p %p %8d %8d %3d  %3ld %s\n", \
165         $task, \
166         $task->tc_SigWait, \
167         $task->tc_SigRecvd, \
168         $task->tc_SPUpper - $task->tc_SPLower, \
169         $task->tc_SPUpper - $task->tc_SPReg, \
170         $task->tc_Node.ln_Pri, \
171         $task->tc_Node.ln_Type, \
172         $task->tc_Node.ln_Name
173     set $task = (struct Task *)$task->tc_Node.ln_Succ
174     end
176 document taskwait
177 List of tasks currently waiting for an event
180 define thistask
181     _debug_init
182     set $task = (struct Task *)((struct ExecBase *)$AbsExecBase)->ThisTask
183     printf "Task     SigWait  SigRecvd StkSize   StkUsed Pri Type Name\n"
184     printf "-----------------------------------------------------------------------------\n"
185     printf "%p %p %p %8d %8d %3d  %3ld %s\n", \
186     $task, \
187     $task->tc_SigWait, \
188     $task->tc_SigRecvd, \
189     $task->tc_SPUpper - $task->tc_SPLower, \
190     $task->tc_SPUpper - $task->tc_SPReg, \
191     $task->tc_Node.ln_Pri, \
192     $task->tc_Node.ln_Type, \
193     $task->tc_Node.ln_Name
195 document thistask
196 Print out information about the currently running task.
199 define modlist
200     _debug_init
201     printf "Segment                                   Module\n"
203     if $_debug_ModList
204         printf "---------------------------------------------------------------------\n"
205         set $modnode = (module_t *)$_debug_ModList->mlh_Head
207         while ($modnode->m_node.mln_Succ != 0)
208             set $segidx = 0
209             while ($segidx < $modnode->m_segcnt)
210                 set $segnode = $modnode->m_segments[$segidx]
211                 printf "%p %12s %2u %42s\n", $segnode->s_lowest, $segnode->s_name, $segnode->s_num, $segnode->s_mod->m_name
212                 set $segidx = $segidx + 1
213             end
215             set $modnode = (module_t *)$modnode->m_node.mln_Succ
216         end
217     end
219 document modlist
220 List of all the modules currently loaded in memory
223 # Execute a binary search over sorter array of segments
224 # Keep this function synchronized with decodelocation.c, FindSegmentInModule
225 define find_segment_in_module
226     set $arg_address = $arg0
227     set $arg_mod = $arg1
228     set $find_segment_in_module_result = 0
229     set $local_minsegidx = 0
230     set $local_maxsegidx = $arg_mod->m_segcnt - 1
231     set $_again = 1
233     while ($_again == 1)
234         set $local_segidx = ($local_maxsegidx + $local_minsegidx) / 2
236         if $arg_mod->m_segments[$local_segidx]->s_lowest <= $arg_address
237             if $arg_mod->m_segments[$local_segidx]->s_highest >= $arg_address
238                 set $find_segment_in_module_result = $arg_mod->m_segments[$local_segidx]
239                 loop_break
240             else
241                 set $local_minsegidx = $local_segidx + 1
242             end
243         else
244             set $local_maxsegidx = $local_segidx - 1
245         end
247         if $local_maxsegidx < $local_minsegidx
248             # Not found, aborting
249             loop_break
250         end
251     end
254 # Keep this function synchronized with decodelocation.c, FindSegment
255 define find_segment
256     _debug_init
257     set $find_segment_result = 0
259     if $_debug_ModList
260         set $modnode = (module_t *)$_debug_ModList->mlh_Head
262         while ($modnode->m_node.mln_Succ != 0)
263             if !($modnode->m_gaplowest <= $arg0 && $modnode->m_gaphighest >= $arg0)
264                 if $modnode->m_lowest <= $arg0 && $modnode->m_highest >= $arg0
266                     find_segment_in_module $arg0 $modnode
268                     if $find_segment_in_module_result
269                         set $find_segment_result = $find_segment_in_module_result
270                         loop_break
271                     end
272                 end
273             end
274             set $modnode = (module_t *)$modnode->m_node.mln_Succ
275         end
276     end
279 define findaddr
280     _debug_init
281     set $cont = 1
283     #first search in modules loaded from disk
284     printf "Searching in the loaded modules...\n"
286     find_segment $arg0
288     if $find_segment_result
289         set $segnode = $find_segment_result
290         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
291         set $cont = 0
292     end
294     #then in the resident list
295     if $cont
296         printf "Searching in the resident list...\n"
297     end
299     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
300     set $i = 0
302     while (($resp)[$i] != 0) && $cont
303     set $res = ($resp)[$i]
305         if ($arg0 >= $res) && ($arg0 <= $res->rt_EndSkip)
306             printf "Address found in %s, which resides at %p\n", $res->rt_Name, $res
307             set $cont = 0
308         end
310         set $i = $i + 1
311     end
313     if $cont
314         printf "No matching module for this address\n"
315     end
317 document findaddr
318 -Shows the module that contains the given address
320 -To debug a problem in AROS, do the following:
322 -1. Get a stacktrace with bt or similar.
323 -2. Use findaddr with such an address to find out in which
324 -   module it is:
325 -3. Use add-symbol-file to load that modules symbols.
326 -4. Now you can run bt (or similar) again and you should see the
327 -   addresses resolved as symbols.
329 -Example:
331 -0x4058d45b in ?? ()
333 -(gdb) findaddr 0x4058d45b
335 -Searching in the loaded modules...
336 -Address found in Workbench:contrib/Zune/Libs/muimaster.library, which is loaded at 0x405379a4.
337 -If this is an executable, its .text section starts at 0x405379b0.
338 -(gdb) add-symbol-file contrib/Zune/Libs/muimaster.library 0x405379b0
339 -add symbol table from file "contrib/Zune/Libs/muimaster.library" at
340 -        .text_addr = 0x405379b0
341 -(y or n) y
342 -Reading symbols from contrib/Zune/Libs/muimaster.library...done.
343 -(gdb) bt
344 -#0  0x4058d45b in strlen (ptr=0x80 <Address 0x80 out of bounds>) at strlen.c:45
345 -#1  0x00000000 in lastx.78 ()
348 define printtaglist
349     set $list = (struct TagItem *)$arg0
351     printf "Tag         Data (Hex)     Data (Dec)\n"
352     printf "--------------------------------------\n"
354     while $list->ti_Tag != 0
355     # Handle the possible control tag...
356     if $list->ti_Tag == 1
357         printf "TAG_IGNORE\n"
358     else if $list->ti_Tag == 2
359         printf "TAG_MORE    %p\n", $list->ti_Data
360         set $list = (struct TagItem *)$list->ti_Data
361     else if $list->ti_Tag == 3
362         printf "TAG_SKIP    %d\n", $list->ti_Data
363         set $list = $list + $list->ti_Tag + 1
364     else
365         printf "%p  %p      %9lu\n", $list->ti_Tag, $list->ti_Data, $list->ti_Data
366         set $list = $list + 1
367     end
368     end
369     printf "TAG_DONE\n"
371 document printtaglist
374 define loadmod
375     set pagination off
376     set $this_mod = $arg0
378     log_to_file segname.tmp on
379     printf "%s", $this_mod->m_name
380     end_log
381     shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
382     log_to_file loadseg.tmp on
383     printf "add-symbol-file \""
384     end_log
385     shell head -n1 segname.tmp >>loadseg.tmp
386     log_to_file loadseg.tmp off
387     printf "\" %s", $this_mod->m_seggdbhlp
388     end_log
390     source loadseg.tmp
391     set pagination on
394 define loadseg
395     _debug_init
396     dont-repeat
397     if $_debug_ModList
398         set $step = 1
400         find_segment $arg0
402         if $find_segment_result
403             # This is workaround for some flushing problem when loadseg.tmp had module name before command
404             printf "\n"
406             loadmod $find_segment_result->s_mod
408             set $step = 2
409         end
411         if $step < 2
412             printf "No matching module for this address\n"
413         end
415     end
417 document loadseg
418 Loads the module that contains the given address
421 define loadmods
422     _debug_init
424     if $_debug_ModList
425         set $loadmods_modnode = (module_t *)$_debug_ModList->mlh_Head
427         while ($loadmods_modnode->m_node.mln_Succ != 0)
428             loadmod $loadmods_modnode
429             set $loadmods_modnode = (module_t *)$loadmods_modnode->m_node.mln_Succ
430         end
431     end
433 document loadmods
434 Loads all the modules (symbols)
437 define loadframe
438     log_to_file frameinfo.tmp on
439     info frame $arg0
440     end_log
441     
442     shell grep "eip =" frameinfo.tmp >loadseg.tmp
443     shell sed -e 's/eip = \(0x[0-9,a-f]*\).*/loadseg \1/' loadseg.tmp >frameinfo.tmp
444     
445     source frameinfo.tmp
447 document loadframe
448 Loads the symbols for the given stack frame number
451 define loadframes
452     set $_again = 1
453     printf "\n\n"
454     
455     while ($_again == 1)
456         bt
457         printf "\nEnter stack frame number to resolve or RETURN to stop: \n\n"
459         set $_answer = 1000
461         shell read _gdb_answer && echo $_gdb_answer | grep -E "[0-9]+" | sed "s/\(.*\)/set \$_answer=\1/" >frameinfo.tmp
463         source frameinfo.tmp
464         printf "\n\n"
466         if $_answer == 1000
467             set $_again = 0
468         else
469             loadframe $_answer
470         end
471     end
473 document loadframes
474 Interactive multiple loading of symbols for given stack frame numbers
477 define loadbt
478     set $_frame_counter = 0
480     set $_again = 1
481     while ($_again == 1)
482         printf "Checking frame #%d\n", $_frame_counter
484         set $_again = 0
486         log_to_file loadseg.tmp on
487         set pagination off
488         bt
489         end_log
491         # Check if frame exists
493         log_to_file frameinfo.tmp on
494         printf "shell grep \"#%d .*\" loadseg.tmp | sed \"s/#.*/set \\$_again = 1/\" >loadbt.tmp\n", $_frame_counter
495         end_log
497         source frameinfo.tmp
498         source loadbt.tmp
500         if $_again == 1
502             # If frame is unresolved ("in ??") transform to "loadseg address"
503             
504             log_to_file frameinfo.tmp on
505             printf "shell grep \"#%d .* in ??\" loadseg.tmp | sed \"s/#.*\\(0x[0-9,a-f]*\\) .*/loadseg \\1/\" >loadbt.tmp\n", $_frame_counter
506             end_log
508             source frameinfo.tmp
509             source loadbt.tmp
511             set $_frame_counter = $_frame_counter + 1
512             if ($_frame_counter == 1000)
513                 set $_again = 0
514             end
515         end
516     end
518     set pagination on
520 document loadbt
521 Tries to automatically load the symbols for all unresolved stack frames
524 define seglistdump
525     _debug_init
526     set $nextseg = $arg0
527     set $count   = 1
529     printf "Hunk num. | Start addr | Size       \n"
530     printf "----------+------------+------------\n"
531     while $nextseg
532         printf "%9d | %p | %10d\n", $count, $nextseg + sizeof(BPTR), *((ULONG *)$nextseg - 1) - sizeof(BPTR)
534         set $nextseg = *(BPTR *)$nextseg
535         set $count = $count+1
536     end
538 document seglistdump
539 Shows the segments chain of the given seglist
542 define bttask
543     set $task = (struct Task *)$arg0
544     if ($task->tc_Node.ln_Type != 1) && ($task->tc_Node.ln_Type != 13)
545         printf "ERROR: Given address does not look like a task or process!\n"
546     else
547         #FIXME: The following assumes Linux x86
548         set $old_esp = $esp
549         set $old_eip = $eip
550         
551         if $task->tc_State == 2
552             printf "WARNING: TS_RUN Task. Showing normal backtrace!\n"
553         else
554             set $esp = $task->tc_SPReg
555             set $taskcontext = (struct AROSCPUContext *)$task->tc_UnionETask.tc_ETask.et_RegFrame
556             set $eip = $taskcontext.regs.eip
557         end
558         
559         bt
561         set $esp = $old_esp
562         set $eip = $old_eip
563     end
565 document bttask
566 Shows the backtrace of the given TS_READY/TS_WAIT task
569 define semowner
570     set $sem = (struct SignalSemaphore *)$arg0
571     if $sem->ss_Link.ln_Type != 15
572         printf "ERROR: Given address does not look like a semaphore!\n"
573     else
574         if $sem->ss_QueueCount == -1
575             printf "The semaphore is free\n"
576         else
577             if $sem->ss_Owner == 0
578                 printf "The semaphore is locked in shared mode by one or more tasks\n"
579             else
580                     printf "The semaphore is owned by task %p (%s)\n", $sem->ss_Owner, $sem->ss_Owner->tc_Node.ln_Name
581             end
583             printf "\nWait Queue:\n\n"
585             set $waitnode = (struct SemaphoreRequest *)$sem->ss_WaitQueue.mlh_Head
587             while ($waitnode->sr_Link.mln_Succ != 0)
588                 set $waitertask = $waitnode->sr_Waiter
589                 if (int)$waitertask & 1
590                     set $waitertask = $waitertask & ~1
591                     printf " SHARED    "
592                 else
593                     printf " EXCLUSIVE "
594                 end
595                 printf"%p %s\n", $waitertask, $waitertask->tc_Node.ln_Name
596                 set $waitnode = (struct SemaphoreRequest *)$waitnode->sr_Link.mln_Succ
597             end
598         end
599     end
601 document semowner
602 Shows the owner of the given Exec Semaphore and the Wait Queue