diff options
Diffstat (limited to 'Documentation/kdump/gdbmacros.txt')
-rw-r--r-- | Documentation/kdump/gdbmacros.txt | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/Documentation/kdump/gdbmacros.txt b/Documentation/kdump/gdbmacros.txt new file mode 100644 index 000000000000..bc1b9eb92ae1 --- /dev/null +++ b/Documentation/kdump/gdbmacros.txt | |||
@@ -0,0 +1,179 @@ | |||
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 | ||