About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / kdump / gdbmacros.txt


Based on kernel version 4.16.1. Page generated on 2018-04-09 11:53 EST.

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_log_idx
174		set $idx = $arg0
175		if ($argc > 1)
176			set $prev_flags = $arg1
177		else
178			set $prev_flags = 0
179		end
180		set $msg = ((struct printk_log *) (log_buf + $idx))
181		set $prefix = 1
182		set $newline = 1
183		set $log = log_buf + $idx + sizeof(*$msg)
184	
185		# prev & LOG_CONT && !(msg->flags & LOG_PREIX)
186		if (($prev_flags & 8) && !($msg->flags & 4))
187			set $prefix = 0
188		end
189	
190		# msg->flags & LOG_CONT
191		if ($msg->flags & 8)
192			# (prev & LOG_CONT && !(prev & LOG_NEWLINE))
193			if (($prev_flags & 8) && !($prev_flags & 2))
194				set $prefix = 0
195			end
196			# (!(msg->flags & LOG_NEWLINE))
197			if (!($msg->flags & 2))
198				set $newline = 0
199			end
200		end
201	
202		if ($prefix)
203			printf "[%5lu.%06lu] ", $msg->ts_nsec / 1000000000, $msg->ts_nsec % 1000000000
204		end
205		if ($msg->text_len != 0)
206			eval "printf \"%%%d.%ds\", $log", $msg->text_len, $msg->text_len
207		end
208		if ($newline)
209			printf "\n"
210		end
211		if ($msg->dict_len > 0)
212			set $dict = $log + $msg->text_len
213			set $idx = 0
214			set $line = 1
215			while ($idx < $msg->dict_len)
216				if ($line)
217					printf " "
218					set $line = 0
219				end
220				set $c = $dict[$idx]
221				if ($c == '\0')
222					printf "\n"
223					set $line = 1
224				else
225					if ($c < ' ' || $c >= 127 || $c == '\\')
226						printf "\\x%02x", $c
227					else
228						printf "%c", $c
229					end
230				end
231				set $idx = $idx + 1
232			end
233			printf "\n"
234		end
235	end
236	document dump_log_idx
237		Dump a single log given its index in the log buffer.  The first
238		parameter is the index into log_buf, the second is optional and
239		specified the previous log buffer's flags, used for properly
240		formatting continued lines.
241	end
242	
243	define dmesg
244		set $i = log_first_idx
245		set $end_idx = log_first_idx
246		set $prev_flags = 0
247	
248		while (1)
249			set $msg = ((struct printk_log *) (log_buf + $i))
250			if ($msg->len == 0)
251				set $i = 0
252			else
253				dump_log_idx $i $prev_flags
254				set $i = $i + $msg->len
255				set $prev_flags = $msg->flags
256			end
257			if ($i == $end_idx)
258				loop_break
259			end
260		end
261	end
262	document dmesg
263		print the kernel ring buffer
264	end
Hide Line Numbers


About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog