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) |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 18 | set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 19 | set $init_t=&init_task |
| 20 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 21 | set var $stacksize = sizeof(union thread_union) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 22 | while ($next_t != $init_t) |
| 23 | set $next_t=(struct task_struct *)$next_t |
| 24 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm |
| 25 | printf "===================\n" |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 26 | set var $stackp = $next_t.thread.sp |
| 27 | set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 28 | |
| 29 | while ($stackp < $stack_top) |
| 30 | if (*($stackp) > _stext && *($stackp) < _sinittext) |
| 31 | info symbol *($stackp) |
| 32 | end |
| 33 | set $stackp += 4 |
| 34 | end |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 35 | set $next_th=(((char *)$next_t->thread_group.next) - $pid_off) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 36 | while ($next_th != $next_t) |
| 37 | set $next_th=(struct task_struct *)$next_th |
| 38 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm |
| 39 | printf "===================\n" |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 40 | set var $stackp = $next_t.thread.sp |
| 41 | set var $stack_top = ($stackp & ~($stacksize - 1)) + stacksize |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 42 | |
| 43 | while ($stackp < $stack_top) |
| 44 | if (*($stackp) > _stext && *($stackp) < _sinittext) |
| 45 | info symbol *($stackp) |
| 46 | end |
| 47 | set $stackp += 4 |
| 48 | end |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 49 | set $next_th=(((char *)$next_th->thread_group.next) - $pid_off) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 50 | end |
| 51 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off |
| 52 | end |
| 53 | end |
| 54 | document bttnobp |
| 55 | dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER |
| 56 | end |
| 57 | |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 58 | define btthreadstack |
| 59 | set var $pid_task = $arg0 |
| 60 | |
| 61 | printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm |
| 62 | printf "task struct: " |
| 63 | print $pid_task |
| 64 | printf "===================\n" |
| 65 | set var $stackp = $pid_task.thread.sp |
| 66 | set var $stacksize = sizeof(union thread_union) |
| 67 | set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize |
| 68 | set var $stack_bot = ($stackp & ~($stacksize - 1)) |
| 69 | |
| 70 | set $stackp = *((unsigned long *) $stackp) |
| 71 | while (($stackp < $stack_top) && ($stackp > $stack_bot)) |
| 72 | set var $addr = *(((unsigned long *) $stackp) + 1) |
| 73 | info symbol $addr |
| 74 | set $stackp = *((unsigned long *) $stackp) |
| 75 | end |
| 76 | end |
| 77 | document btthreadstack |
| 78 | dump a thread stack using the given task structure pointer |
| 79 | end |
| 80 | |
| 81 | |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 82 | define btt |
| 83 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 84 | set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 85 | set $init_t=&init_task |
| 86 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) |
| 87 | while ($next_t != $init_t) |
| 88 | set $next_t=(struct task_struct *)$next_t |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 89 | btthreadstack $next_t |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 90 | |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 91 | set $next_th=(((char *)$next_t->thread_group.next) - $pid_off) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 92 | while ($next_th != $next_t) |
| 93 | set $next_th=(struct task_struct *)$next_th |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 94 | btthreadstack $next_th |
| 95 | set $next_th=(((char *)$next_th->thread_group.next) - $pid_off) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 96 | end |
| 97 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off |
| 98 | end |
| 99 | end |
| 100 | document btt |
| 101 | dump all thread stack traces on a kernel compiled with CONFIG_FRAME_POINTER |
| 102 | end |
| 103 | |
| 104 | define btpid |
| 105 | set var $pid = $arg0 |
| 106 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 107 | set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 108 | set $init_t=&init_task |
| 109 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) |
| 110 | set var $pid_task = 0 |
| 111 | |
| 112 | while ($next_t != $init_t) |
| 113 | set $next_t=(struct task_struct *)$next_t |
| 114 | |
| 115 | if ($next_t.pid == $pid) |
| 116 | set $pid_task = $next_t |
| 117 | end |
| 118 | |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 119 | set $next_th=(((char *)$next_t->thread_group.next) - $pid_off) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 120 | while ($next_th != $next_t) |
| 121 | set $next_th=(struct task_struct *)$next_th |
| 122 | if ($next_th.pid == $pid) |
| 123 | set $pid_task = $next_th |
| 124 | end |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 125 | set $next_th=(((char *)$next_th->thread_group.next) - $pid_off) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 126 | end |
| 127 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off |
| 128 | end |
| 129 | |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 130 | btthreadstack $pid_task |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 131 | end |
| 132 | document btpid |
| 133 | backtrace of pid |
| 134 | end |
| 135 | |
| 136 | |
| 137 | define trapinfo |
| 138 | set var $pid = $arg0 |
| 139 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 140 | set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 141 | set $init_t=&init_task |
| 142 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) |
| 143 | set var $pid_task = 0 |
| 144 | |
| 145 | while ($next_t != $init_t) |
| 146 | set $next_t=(struct task_struct *)$next_t |
| 147 | |
| 148 | if ($next_t.pid == $pid) |
| 149 | set $pid_task = $next_t |
| 150 | end |
| 151 | |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 152 | set $next_th=(((char *)$next_t->thread_group.next) - $pid_off) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 153 | while ($next_th != $next_t) |
| 154 | set $next_th=(struct task_struct *)$next_th |
| 155 | if ($next_th.pid == $pid) |
| 156 | set $pid_task = $next_th |
| 157 | end |
Corey Minyard | a0c20de | 2016-05-23 16:24:25 -0700 | [diff] [blame] | 158 | set $next_th=(((char *)$next_th->thread_group.next) - $pid_off) |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 159 | end |
| 160 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off |
| 161 | end |
| 162 | |
| 163 | printf "Trapno %ld, cr2 0x%lx, error_code %ld\n", $pid_task.thread.trap_no, \ |
| 164 | $pid_task.thread.cr2, $pid_task.thread.error_code |
| 165 | |
| 166 | end |
| 167 | document trapinfo |
| 168 | Run info threads and lookup pid of thread #1 |
| 169 | 'trapinfo <pid>' will tell you by which trap & possibly |
Lee Revell | f18190b | 2006-06-26 18:30:00 +0200 | [diff] [blame] | 170 | address the kernel panicked. |
Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 171 | end |
Akinobu Mita | 8428cfe | 2006-01-11 12:17:30 -0800 | [diff] [blame] | 172 | |
| 173 | |
| 174 | define dmesg |
| 175 | set $i = 0 |
| 176 | set $end_idx = (log_end - 1) & (log_buf_len - 1) |
| 177 | |
| 178 | while ($i < logged_chars) |
| 179 | set $idx = (log_end - 1 - logged_chars + $i) & (log_buf_len - 1) |
| 180 | |
| 181 | if ($idx + 100 <= $end_idx) || \ |
| 182 | ($end_idx <= $idx && $idx + 100 < log_buf_len) |
| 183 | printf "%.100s", &log_buf[$idx] |
| 184 | set $i = $i + 100 |
| 185 | else |
| 186 | printf "%c", log_buf[$idx] |
| 187 | set $i = $i + 1 |
| 188 | end |
| 189 | end |
| 190 | end |
| 191 | document dmesg |
| 192 | print the kernel ring buffer |
| 193 | end |