linux/Documentation/kdump/gdbmacros.txt
<<
>>
Prefs
   1#
   2# This file contains a few gdb macros (user defined commands) to extract
   3# useful information from kernel crashdump (kdump) like stack traces of
   4# all the processes or a particular process and trapinfo.
   5#
   6# These macros can be used by copying this file in .gdbinit (put in home
   7# directory or current directory) or by invoking gdb command with
   8# --command=<command-file-name> option
   9#
  10# Credits:
  11# Alexander Nyberg <alexn@telia.com>
  12# V Srivatsa <vatsa@in.ibm.com>
  13# Maneesh Soni <maneesh@in.ibm.com>
  14#
  15
  16define bttnobp
  17        set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
  18        set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
  19        set $init_t=&init_task
  20        set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
  21        while ($next_t != $init_t)
  22                set $next_t=(struct task_struct *)$next_t
  23                printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
  24                printf "===================\n"
  25                set var $stackp = $next_t.thread.esp
  26                set var $stack_top = ($stackp & ~4095) + 4096
  27
  28                while ($stackp < $stack_top)
  29                        if (*($stackp) > _stext && *($stackp) < _sinittext)
  30                                info symbol *($stackp)
  31                        end
  32                        set $stackp += 4
  33                end
  34                set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
  35                while ($next_th != $next_t)
  36                        set $next_th=(struct task_struct *)$next_th
  37                        printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
  38                        printf "===================\n"
  39                        set var $stackp = $next_t.thread.esp
  40                        set var $stack_top = ($stackp & ~4095) + 4096
  41
  42                        while ($stackp < $stack_top)
  43                                if (*($stackp) > _stext && *($stackp) < _sinittext)
  44                                        info symbol *($stackp)
  45                                end
  46                                set $stackp += 4
  47                        end
  48                        set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
  49                end
  50                set $next_t=(char *)($next_t->tasks.next) - $tasks_off
  51        end
  52end
  53document bttnobp
  54        dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER
  55end
  56
  57define btt
  58        set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
  59        set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
  60        set $init_t=&init_task
  61        set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
  62        while ($next_t != $init_t)
  63                set $next_t=(struct task_struct *)$next_t
  64                printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
  65                printf "===================\n"
  66                set var $stackp = $next_t.thread.esp
  67                set var $stack_top = ($stackp & ~4095) + 4096
  68                set var $stack_bot = ($stackp & ~4095)
  69
  70                set $stackp = *($stackp)
  71                while (($stackp < $stack_top) && ($stackp > $stack_bot))
  72                        set var $addr = *($stackp + 4)
  73                        info symbol $addr
  74                        set $stackp = *($stackp)
  75                end
  76
  77                set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
  78                while ($next_th != $next_t)
  79                        set $next_th=(struct task_struct *)$next_th
  80                        printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
  81                        printf "===================\n"
  82                        set var $stackp = $next_t.thread.esp
  83                        set var $stack_top = ($stackp & ~4095) + 4096
  84                        set var $stack_bot = ($stackp & ~4095)
  85
  86                        set $stackp = *($stackp)
  87                        while (($stackp < $stack_top) && ($stackp > $stack_bot))
  88                                set var $addr = *($stackp + 4)
  89                                info symbol $addr
  90                                set $stackp = *($stackp)
  91                        end
  92                        set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
  93                end
  94                set $next_t=(char *)($next_t->tasks.next) - $tasks_off
  95        end
  96end
  97document btt
  98        dump all thread stack traces on a kernel compiled with CONFIG_FRAME_POINTER
  99end
 100
 101define btpid
 102        set var $pid = $arg0
 103        set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
 104        set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
 105        set $init_t=&init_task
 106        set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
 107        set var $pid_task = 0
 108
 109        while ($next_t != $init_t)
 110                set $next_t=(struct task_struct *)$next_t
 111
 112                if ($next_t.pid == $pid)
 113                        set $pid_task = $next_t
 114                end
 115
 116                set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
 117                while ($next_th != $next_t)
 118                        set $next_th=(struct task_struct *)$next_th
 119                        if ($next_th.pid == $pid)
 120                                set $pid_task = $next_th
 121                        end
 122                        set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
 123                end
 124                set $next_t=(char *)($next_t->tasks.next) - $tasks_off
 125        end
 126
 127        printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm
 128        printf "===================\n"
 129        set var $stackp = $pid_task.thread.esp
 130        set var $stack_top = ($stackp & ~4095) + 4096
 131        set var $stack_bot = ($stackp & ~4095)
 132
 133        set $stackp = *($stackp)
 134        while (($stackp < $stack_top) && ($stackp > $stack_bot))
 135                set var $addr = *($stackp + 4)
 136                info symbol $addr
 137                set $stackp = *($stackp)
 138        end
 139end
 140document btpid
 141        backtrace of pid
 142end
 143
 144
 145define trapinfo
 146        set var $pid = $arg0
 147        set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
 148        set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
 149        set $init_t=&init_task
 150        set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
 151        set var $pid_task = 0
 152
 153        while ($next_t != $init_t)
 154                set $next_t=(struct task_struct *)$next_t
 155
 156                if ($next_t.pid == $pid)
 157                        set $pid_task = $next_t
 158                end
 159
 160                set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
 161                while ($next_th != $next_t)
 162                        set $next_th=(struct task_struct *)$next_th
 163                        if ($next_th.pid == $pid)
 164                                set $pid_task = $next_th
 165                        end
 166                        set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
 167                end
 168                set $next_t=(char *)($next_t->tasks.next) - $tasks_off
 169        end
 170
 171        printf "Trapno %ld, cr2 0x%lx, error_code %ld\n", $pid_task.thread.trap_no, \
 172                                $pid_task.thread.cr2, $pid_task.thread.error_code
 173
 174end
 175document trapinfo
 176        Run info threads and lookup pid of thread #1
 177        'trapinfo <pid>' will tell you by which trap & possibly
 178        address the kernel panicked.
 179end
 180
 181
 182define dmesg
 183        set $i = 0
 184        set $end_idx = (log_end - 1) & (log_buf_len - 1)
 185
 186        while ($i < logged_chars)
 187                set $idx = (log_end - 1 - logged_chars + $i) & (log_buf_len - 1)
 188
 189                if ($idx + 100 <= $end_idx) || \
 190                   ($end_idx <= $idx && $idx + 100 < log_buf_len)
 191                        printf "%.100s", &log_buf[$idx]
 192                        set $i = $i + 100
 193                else
 194                        printf "%c", log_buf[$idx]
 195                        set $i = $i + 1
 196                end
 197        end
 198end
 199document dmesg
 200        print the kernel ring buffer
 201end
 202