start service tasks separately in-case platforms need to perform additional set-up...
[AROS.git] / _gdbinit
blob12effb6c3dab18fbdcdd6cbc0348c0786b761923
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
13 define _sysbase_init
14     init-if-undefined $AbsExecBase = 0
15     if $AbsExecBase != 0
16         set $AbsExecBase = (struct IntExecBase *)$AbsExecBase
17     end
18 end
19 document _sysbase_init
20 Initialize $AbsExecBase convenience variables
21 end
23 define _debug_init
24     _sysbase_init
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)
31     end
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     else
38         # This is the case for debugging a bootstrap
39         init-if-undefined $_debug_ModList = Debug_ModList
40     end
41 end
42 document _debug_init
43 Initialize debugging convenience variables
44 end
46 define liblist
47     _sysbase_init
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", \
54         $lib, \
55         ((struct Library *)$lib)->lib_OpenCnt, \
56         $lib->ln_Name
57     set $lib = $lib->ln_Succ
58     end
59 end
60 document liblist
61 List the current libraries in the system
62 end
64 define devlist
65     _debug_init
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", \
71         $dev, \
72         ((struct Library *)$dev)->lib_OpenCnt, \
73         $dev->ln_Name
74     set $dev = $dev->ln_Succ
75     end
76 end
77 document devlist
78 List the current devices in the system
79 end
81 define resourcelist
82     _debug_init
83     set $res = ((struct ExecBase *)$AbsExecBase)->ResourceList.lh_Head
84     printf "Base     Name\n"
85     printf "---------------------------------------------------------------\n"
86     while ($res->ln_Succ != 0)
87     printf "%p %s\n", $res, $res->ln_Name
88     set $res = $res->ln_Succ
89     end
90 end
91 document resourcelist
92 List the current resources in the system
93 end
95 define residentlist
96     _debug_init
97     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
98     set $i = 0
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", \
105         $res, \
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
111     set $i = $i + 1
112     end
114 document residentlist
115 List the system resident list
118 define taskready
119     _debug_init
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", \
126         $task, \
127         $task->tc_SigWait, \
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
135     end
137 document taskready
138 List of tasks currently ready to run
141 define taskwait
142     _debug_init
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", \
149         $task, \
150         $task->tc_SigWait, \
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
158     end
160 document taskwait
161 List of tasks currently waiting for an event
164 define thistask
165     _debug_init
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", \
170     $task, \
171     $task->tc_SigWait, \
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
179 document thistask
180 Print out information about the currently running task.
183 define modlist
184     _debug_init
185     printf "Segment                                   Module\n"
187     if $_debug_ModList
188         printf "---------------------------------------------------------------------\n"
189         set $modnode = (module_t *)$_debug_ModList->mlh_Head
191         while ($modnode->m_node.mln_Succ != 0)
192             set $segidx = 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
197             end
199             set $modnode = (module_t *)$modnode->m_node.mln_Succ
200         end
201     end
203 document modlist
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
211     set $arg_mod = $arg1
212     set $find_segment_in_module_result = 0
213     set $local_minsegidx = 0
214     set $local_maxsegidx = $arg_mod->m_segcnt - 1
215     set $_again = 1
217     while ($_again == 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]
223                 loop_break
224             else
225                 set $local_minsegidx = $local_segidx + 1
226             end
227         else
228             set $local_maxsegidx = $local_segidx - 1
229         end
231         if $local_maxsegidx < $local_minsegidx
232             # Not found, aborting
233             loop_break
234         end
235     end
238 # Keep this function synchronized with decodelocation.c, FindSegment
239 define find_segment
240     _debug_init
241     set $find_segment_result = 0
243     if $_debug_ModList
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
254                         loop_break
255                     end
256                 end
257             end
258             set $modnode = (module_t *)$modnode->m_node.mln_Succ
259         end
260     end
263 define findaddr
264     _debug_init
265     set $cont = 1
267     #first search in modules loaded from disk
268     printf "Searching in the loaded modules...\n"
270     find_segment $arg0
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
275         set $cont = 0
276     end
278     #then in the resident list
279     if $cont
280         printf "Searching in the resident list...\n"
281     end
283     set $resp = (struct Resident **)((struct ExecBase *)$AbsExecBase)->ResModules
284     set $i = 0
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
291             set $cont = 0
292         end
294         set $i = $i + 1
295     end
297     if $cont
298         printf "No matching module for this address\n"
299     end
301 document findaddr
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
308 -   module it is:
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.
313 -Example:
315 -0x4058d45b in ?? ()
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
325 -(y or n) y
326 -Reading symbols from contrib/Zune/Libs/muimaster.library...done.
327 -(gdb) bt
328 -#0  0x4058d45b in strlen (ptr=0x80 <Address 0x80 out of bounds>) at strlen.c:45
329 -#1  0x00000000 in lastx.78 ()
332 define printtaglist
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
348     else
349         printf "%p  %p      %9lu\n", $list->ti_Tag, $list->ti_Data, $list->ti_Data
350         set $list = $list + 1
351     end
352     end
353     printf "TAG_DONE\n"
355 document printtaglist
358 define log_to_file
359   set logging file $arg0
360   set logging redirect on
361   set logging overwrite $arg1
362   set logging on
365 define end_log
366   set logging off
369 define loadmod
370     set pagination off
371     set $this_mod = $arg0
373     log_to_file segname.tmp on
374     printf "%s", $this_mod->m_name
375     end_log
376     shell sed -i 's/.*:\(.*\)/\1/' segname.tmp
377     log_to_file loadseg.tmp on
378     printf "add-symbol-file \""
379     end_log
380     shell head -n1 segname.tmp >>loadseg.tmp
381     log_to_file loadseg.tmp off
382     printf "\" %s", $this_mod->m_seggdbhlp
383     end_log
385     source loadseg.tmp
386     set pagination on
389 define loadseg
390     _debug_init
391     dont-repeat
392     if $_debug_ModList
393         set $step = 1
395         find_segment $arg0
397         if $find_segment_result
398             # This is workaround for some flushing problem when loadseg.tmp had module name before command
399             printf "\n"
401             loadmod $find_segment_result->s_mod
403             set $step = 2
404         end
406         if $step < 2
407             printf "No matching module for this address\n"
408         end
410     end
412 document loadseg
413 Loads the module that contains the given address
416 define loadmods
417     _debug_init
419     if $_debug_ModList
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
425         end
426     end
428 document loadmods
429 Loads all the modules (symbols)
432 define loadframe
433     log_to_file frameinfo.tmp on
434     info frame $arg0
435     end_log
436     
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
439     
440     source frameinfo.tmp
442 document loadframe
443 Loads the symbols for the given stack frame number
446 define loadframes
447     set $_again = 1
448     printf "\n\n"
449     
450     while ($_again == 1)
451         bt
452         printf "\nEnter stack frame number to resolve or RETURN to stop: \n\n"
454         set $_answer = 1000
456         shell read _gdb_answer && echo $_gdb_answer | grep -E "[0-9]+" | sed "s/\(.*\)/set \$_answer=\1/" >frameinfo.tmp
458         source frameinfo.tmp
459         printf "\n\n"
461         if $_answer == 1000
462             set $_again = 0
463         else
464             loadframe $_answer
465         end
466     end
468 document loadframes
469 Interactive multiple loading of symbols for given stack frame numbers
472 define loadbt
473     set $_frame_counter = 0
475     set $_again = 1
476     while ($_again == 1)
477         printf "Checking frame #%d\n", $_frame_counter
479         set $_again = 0
481         log_to_file loadseg.tmp on
482         set pagination off
483         bt
484         end_log
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
490         end_log
492         source frameinfo.tmp
493         source loadbt.tmp
495         if $_again == 1
497             # If frame is unresolved ("in ??") transform to "loadseg address"
498             
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
501             end_log
503             source frameinfo.tmp
504             source loadbt.tmp
506             set $_frame_counter = $_frame_counter + 1
507             if ($_frame_counter == 1000)
508                 set $_again = 0
509             end
510         end
511     end
513     set pagination on
515 document loadbt
516 Tries to automatically load the symbols for all unresolved stack frames
519 define seglistdump
520     _debug_init
521     set $nextseg = $arg0
522     set $count   = 1
524     printf "Hunk num. | Start addr | Size       \n"
525     printf "----------+------------+------------\n"
526     while $nextseg
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
531     end
533 document seglistdump
534 Shows the segments chain of the given seglist
537 define bttask
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"
541     else
542         #FIXME: The following assumes Linux x86
543         set $old_esp = $esp
544         set $old_eip = $eip
545         
546         if $task->tc_State == 2
547             printf "WARNING: TS_RUN Task. Showing normal backtrace!\n"
548         else
549             set $esp = $task->tc_SPReg
550             set $taskcontext = (struct AROSCPUContext *)$task->tc_UnionETask.tc_ETask.et_RegFrame
551             set $eip = $taskcontext.regs.eip
552         end
553         
554         bt
556         set $esp = $old_esp
557         set $eip = $old_eip
558     end
560 document bttask
561 Shows the backtrace of the given TS_READY/TS_WAIT task
564 define semowner
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"
568     else
569         if $sem->ss_QueueCount == -1
570             printf "The semaphore is free\n"
571         else
572             if $sem->ss_Owner == 0
573                 printf "The semaphore is locked in shared mode by one or more tasks\n"
574             else
575                     printf "The semaphore is owned by task %p (%s)\n", $sem->ss_Owner, $sem->ss_Owner->tc_Node.ln_Name
576             end
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
586                     printf " SHARED    "
587                 else
588                     printf " EXCLUSIVE "
589                 end
590                 printf"%p %s\n", $waitertask, $waitertask->tc_Node.ln_Name
591                 set $waitnode = (struct SemaphoreRequest *)$waitnode->sr_Link.mln_Succ
592             end
593         end
594     end
596 document semowner
597 Shows the owner of the given Exec Semaphore and the Wait Queue