~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/admin-guide/kdump/gdbmacros.txt

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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)->thread_group.next)
 19         set $init_t=&init_task
 20         set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
 21         set var $stacksize = sizeof(union thread_union)
 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"
 26                 set var $stackp = $next_t.thread.sp
 27                 set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize
 28 
 29                 while ($stackp < $stack_top)
 30                         if (*($stackp) > _stext && *($stackp) < _sinittext)
 31                                 info symbol *($stackp)
 32                         end
 33                         set $stackp += 4
 34                 end
 35                 set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
 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"
 40                         set var $stackp = $next_t.thread.sp
 41                         set var $stack_top = ($stackp & ~($stacksize - 1)) + stacksize
 42 
 43                         while ($stackp < $stack_top)
 44                                 if (*($stackp) > _stext && *($stackp) < _sinittext)
 45                                         info symbol *($stackp)
 46                                 end
 47                                 set $stackp += 4
 48                         end
 49                         set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
 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 
 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 
 82 define btt
 83         set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
 84         set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
 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
 89                 btthreadstack $next_t
 90 
 91                 set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
 92                 while ($next_th != $next_t)
 93                         set $next_th=(struct task_struct *)$next_th
 94                         btthreadstack $next_th
 95                         set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
 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)
107         set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
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 
119                 set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
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
125                         set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
126                 end
127                 set $next_t=(char *)($next_t->tasks.next) - $tasks_off
128         end
129 
130         btthreadstack $pid_task
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)
140         set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
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 
152                 set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
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
158                         set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
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
170         address the kernel panicked.
171 end
172 
173 define dump_record
174         set var $desc = $arg0
175         set var $info = $arg1
176         if ($argc > 2)
177                 set var $prev_flags = $arg2
178         else
179                 set var $prev_flags = 0
180         end
181 
182         set var $prefix = 1
183         set var $newline = 1
184 
185         set var $begin = $desc->text_blk_lpos.begin % (1U << prb->text_data_ring.size_bits)
186         set var $next = $desc->text_blk_lpos.next % (1U << prb->text_data_ring.size_bits)
187 
188         # handle data-less record
189         if ($begin & 1)
190                 set var $text_len = 0
191                 set var $log = ""
192         else
193                 # handle wrapping data block
194                 if ($begin > $next)
195                         set var $begin = 0
196                 end
197 
198                 # skip over descriptor id
199                 set var $begin = $begin + sizeof(long)
200 
201                 # handle truncated message
202                 if ($next - $begin < $info->text_len)
203                         set var $text_len = $next - $begin
204                 else
205                         set var $text_len = $info->text_len
206                 end
207 
208                 set var $log = &prb->text_data_ring.data[$begin]
209         end
210 
211         # prev & LOG_CONT && !(info->flags & LOG_PREIX)
212         if (($prev_flags & 8) && !($info->flags & 4))
213                 set var $prefix = 0
214         end
215 
216         # info->flags & LOG_CONT
217         if ($info->flags & 8)
218                 # (prev & LOG_CONT && !(prev & LOG_NEWLINE))
219                 if (($prev_flags & 8) && !($prev_flags & 2))
220                         set var $prefix = 0
221                 end
222                 # (!(info->flags & LOG_NEWLINE))
223                 if (!($info->flags & 2))
224                         set var $newline = 0
225                 end
226         end
227 
228         if ($prefix)
229                 printf "[%5lu.%06lu] ", $info->ts_nsec / 1000000000, $info->ts_nsec % 1000000000
230         end
231         if ($text_len)
232                 eval "printf \"%%%d.%ds\", $log", $text_len, $text_len
233         end
234         if ($newline)
235                 printf "\n"
236         end
237 
238         # handle dictionary data
239 
240         set var $dict = &$info->dev_info.subsystem[0]
241         set var $dict_len = sizeof($info->dev_info.subsystem)
242         if ($dict[0] != '\0')
243                 printf " SUBSYSTEM="
244                 set var $idx = 0
245                 while ($idx < $dict_len)
246                         set var $c = $dict[$idx]
247                         if ($c == '\0')
248                                 loop_break
249                         else
250                                 if ($c < ' ' || $c >= 127 || $c == '\\')
251                                         printf "\\x%02x", $c
252                                 else
253                                         printf "%c", $c
254                                 end
255                         end
256                         set var $idx = $idx + 1
257                 end
258                 printf "\n"
259         end
260 
261         set var $dict = &$info->dev_info.device[0]
262         set var $dict_len = sizeof($info->dev_info.device)
263         if ($dict[0] != '\0')
264                 printf " DEVICE="
265                 set var $idx = 0
266                 while ($idx < $dict_len)
267                         set var $c = $dict[$idx]
268                         if ($c == '\0')
269                                 loop_break
270                         else
271                                 if ($c < ' ' || $c >= 127 || $c == '\\')
272                                         printf "\\x%02x", $c
273                                 else
274                                         printf "%c", $c
275                                 end
276                         end
277                         set var $idx = $idx + 1
278                 end
279                 printf "\n"
280         end
281 end
282 document dump_record
283         Dump a single record. The first parameter is the descriptor,
284         the second parameter is the info, the third parameter is
285         optional and specifies the previous record's flags, used for
286         properly formatting continued lines.
287 end
288 
289 define dmesg
290         # definitions from kernel/printk/printk_ringbuffer.h
291         set var $desc_committed = 1
292         set var $desc_finalized = 2
293         set var $desc_sv_bits = sizeof(long) * 8
294         set var $desc_flags_shift = $desc_sv_bits - 2
295         set var $desc_flags_mask = 3 << $desc_flags_shift
296         set var $id_mask = ~$desc_flags_mask
297 
298         set var $desc_count = 1U << prb->desc_ring.count_bits
299         set var $prev_flags = 0
300 
301         set var $id = prb->desc_ring.tail_id.counter
302         set var $end_id = prb->desc_ring.head_id.counter
303 
304         while (1)
305                 set var $desc = &prb->desc_ring.descs[$id % $desc_count]
306                 set var $info = &prb->desc_ring.infos[$id % $desc_count]
307 
308                 # skip non-committed record
309                 set var $state = 3 & ($desc->state_var.counter >> $desc_flags_shift)
310                 if ($state == $desc_committed || $state == $desc_finalized)
311                         dump_record $desc $info $prev_flags
312                         set var $prev_flags = $info->flags
313                 end
314 
315                 if ($id == $end_id)
316                         loop_break
317                 end
318                 set var $id = ($id + 1) & $id_mask
319         end
320 end
321 document dmesg
322         print the kernel ring buffer
323 end

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php