User loginNavigationNew forum topicsPollSearchRecent blog postsRecent comments
|
gdb macros from Embedded Linux PrimerHere are the macros from the book. Remember that when using these, they are by necessity tied to kernel internal data structures. As such, they are fragile and subject to breakage when kernel data structures are modified. You may have to tweak them for your particular kernel. Thanks to Scott Anderson for the original ideas. Have fun! Listing 14-10
$ cat ~/.gdbinit
set history save on
set history filename ~/.gdb_history
set output-radix 16
define connect
# target remote bdi:2001
target remote /dev/ttyS0
b panic
b sys_sync
end
Listing 14-11 1 # Helper function to find a task given a PID or the 2 # address of a task_struct. 3 # The result is set into $t 4 define find_task 5 # Addresses greater than _end: kernel data... 6 # ...user passed in an address 7 if ((unsigned)$arg0 > (unsigned)&_end) 8 set $t=(struct task_struct *)$arg0 9 else 10 # User entered a numeric PID 11 # Walk the task list to find it 12 set $t=&init_task 13 if (init_task.pid != (unsigned)$arg0) 14 find_next_task $t 15 while (&init_task!=$t && $t->pid != (unsigned)$arg0) 16 find_next_task $t 17 end 18 if ($t == &init_task) 19 printf "Couldn't find task; using init_task\n" 20 end 21 end 22 end 23 printf "Task \"%s\":\n", $t->comm 24 end
Listing 14-12 1 define ps 2 # Print column headers 3 task_struct_header 4 set $t=&init_task 5 task_struct_show $t 6 find_next_task $t 7 # Walk the list 8 while &init_task!=$t 9 # Display useful info about each task 10 task_struct_show $t 11 find_next_task $t 12 end 13 end 14 15 document ps 16 Print points of interest for all tasks 17 end
Listing 14-14 1 define task_struct_show 2 # task_struct addr and PID 3 printf "0x%08X %5d", $arg0, $arg0->pid 4 5 # Place a '<' marker on the current task 6 # if ($arg0 == current) 7 # For PowerPC, register r2 points to the "current" task 8 if ($arg0 == $r2) 9 printf "<" 10 else 11 printf " " 12 end 13 14 # State 15 if ($arg0->state == 0) 16 printf "Running " 17 else 18 if ($arg0->state == 1) 19 printf "Sleeping " 20 else 21 if ($arg0->state == 2) 22 printf "Disksleep " 23 else 24 if ($arg0->state == 4) 25 printf "Zombie " 26 else 27 if ($arg0->state == 8) 28 printf "sTopped " 29 else 30 if ($arg0->state == 16) 31 printf "Wpaging " 32 else 33 printf "%2d ", $arg0->state 34 end 35 end 36 end 37 end 38 end 39 end 40 41 # User NIP 42 if ($arg0->thread.regs) 43 printf "0x%08X ", $arg0->thread.regs->nip 44 else 45 printf " " 46 end 47 48 # Display the kernel stack pointer 49 printf "0x%08X ", $arg0->thread.ksp 50 51 # device 52 if ($arg0->signal->tty) 53 printf "%s ", $arg0->signal->tty->name 54 else 55 printf "(none) " 56 end 57 58 # comm 59 printf "%s\n", $arg0->comm 60 end
Listing 14-15 define find_next_task # Given a task address, find the next task in the linked list set $t = (struct task_struct *)$arg0 set $offset=( (char *)&$t->tasks - (char *)$t) set $t=(struct task_struct *)( (char *)$t->tasks.next-(char *)$offset) end
Listing 14-16 1 define lsmod 2 printf "Address\t\tModule\n" 3 set $m=(struct list_head *)&modules 4 set $done=0 5 while ( !$done ) 6 # list_head is 4-bytes into struct module 7 set $mp=(struct module *)((char *)$m->next - (char *)4) 8 printf "0x%08X\t%s\n", $mp, $mp->name 9 if ( $mp->list->next == &modules) 10 set $done=1 11 end 12 set $m=$m->next 13 end 14 end 15 16 document lsmod 17 List the loaded kernel modules and their start addresses 18 end
|
Kernel Debug
Thanks for posting the macros from the book - cut & paste is a time saver for implementation.
Following the thread of this topic, from LWN.net Debugging kernel modules