| 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 | 
| Lee Revell | f18190b | 2006-06-26 18:30:00 +0200 | [diff] [blame] | 178 | 	address the kernel panicked. | 
| Vivek Goyal | b089f4a | 2005-06-25 14:58:15 -0700 | [diff] [blame] | 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 |