Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 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 | |
| 16 | define 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 |
| 52 | end |
| 53 | document bttnobp |
| 54 | dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER |
| 55 | end |
| 56 | |
| 57 | define 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 |
| 96 | end |
| 97 | document btt |
| 98 | dump all thread stack traces on a kernel compiled with CONFIG_FRAME_POINTER |
| 99 | end |
| 100 | |
| 101 | define 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 |
| 139 | end |
| 140 | document btpid |
| 141 | backtrace of pid |
| 142 | end |
| 143 | |
| 144 | |
| 145 | define 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 | |
| 174 | end |
| 175 | document trapinfo |
| 176 | Run info threads and lookup pid of thread #1 |
| 177 | 'trapinfo <pid>' will tell you by which trap & possibly |
| 178 | addresthe kernel paniced. |
| 179 | end |
Akinobu Mita | 8428cfe | 2006-01-11 12:17:30 -0800 | [diff] [blame] | 180 | |
| 181 | |
| 182 | define 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 |
| 198 | end |
| 199 | document dmesg |
| 200 | print the kernel ring buffer |
| 201 | end |