#
# This file contains a few gdb macros (user defined commands) to extract
# useful information from kernel crashdump (kdump) like stack traces of
# all the processes or a particular process and trapinfo.
#
# These macros can be used by copying this file in .gdbinit (put in home
# directory or current directory) or by invoking gdb command with
# --command=<command-file-name> option
#
# Credits:
# Alexander Nyberg <alexn@telia.com>
# V Srivatsa <vatsa@in.ibm.com>
# Maneesh Soni <maneesh@in.ibm.com>
#

define bttnobp
	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
	set $init_t=&init_task
	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
	set var $stacksize = sizeof(union thread_union)
	while ($next_t != $init_t)
		set $next_t=(struct task_struct *)$next_t
		printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
		printf "===================\n"
		set var $stackp = $next_t.thread.sp
		set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize

		while ($stackp < $stack_top)
			if (*($stackp) > _stext && *($stackp) < _sinittext)
				info symbol *($stackp)
			end
			set $stackp += 4
		end
		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
		while ($next_th != $next_t)
			set $next_th=(struct task_struct *)$next_th
			printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
			printf "===================\n"
			set var $stackp = $next_t.thread.sp
			set var $stack_top = ($stackp & ~($stacksize - 1)) + stacksize

			while ($stackp < $stack_top)
				if (*($stackp) > _stext && *($stackp) < _sinittext)
					info symbol *($stackp)
				end
				set $stackp += 4
			end
			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
		end
		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
	end
end
document bttnobp
	dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER
end

define btthreadstack
	set var $pid_task = $arg0

	printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm
	printf "task struct: "
	print $pid_task
	printf "===================\n"
	set var $stackp = $pid_task.thread.sp
	set var $stacksize = sizeof(union thread_union)
	set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize
	set var $stack_bot = ($stackp & ~($stacksize - 1))

	set $stackp = *((unsigned long *) $stackp)
	while (($stackp < $stack_top) && ($stackp > $stack_bot))
		set var $addr = *(((unsigned long *) $stackp) + 1)
		info symbol $addr
		set $stackp = *((unsigned long *) $stackp)
	end
end
document btthreadstack
	 dump a thread stack using the given task structure pointer
end


define btt
	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
	set $init_t=&init_task
	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
	while ($next_t != $init_t)
		set $next_t=(struct task_struct *)$next_t
		btthreadstack $next_t

		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
		while ($next_th != $next_t)
			set $next_th=(struct task_struct *)$next_th
			btthreadstack $next_th
			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
		end
		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
	end
end
document btt
	dump all thread stack traces on a kernel compiled with CONFIG_FRAME_POINTER
end

define btpid
	set var $pid = $arg0
	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
	set $init_t=&init_task
	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
	set var $pid_task = 0

	while ($next_t != $init_t)
		set $next_t=(struct task_struct *)$next_t

		if ($next_t.pid == $pid)
			set $pid_task = $next_t
		end

		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
		while ($next_th != $next_t)
			set $next_th=(struct task_struct *)$next_th
			if ($next_th.pid == $pid)
				set $pid_task = $next_th
			end
			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
		end
		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
	end

	btthreadstack $pid_task
end
document btpid
	backtrace of pid
end


define trapinfo
	set var $pid = $arg0
	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
	set $init_t=&init_task
	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
	set var $pid_task = 0

	while ($next_t != $init_t)
		set $next_t=(struct task_struct *)$next_t

		if ($next_t.pid == $pid)
			set $pid_task = $next_t
		end

		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
		while ($next_th != $next_t)
			set $next_th=(struct task_struct *)$next_th
			if ($next_th.pid == $pid)
				set $pid_task = $next_th
			end
			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
		end
		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
	end

	printf "Trapno %ld, cr2 0x%lx, error_code %ld\n", $pid_task.thread.trap_no, \
				$pid_task.thread.cr2, $pid_task.thread.error_code

end
document trapinfo
	Run info threads and lookup pid of thread #1
	'trapinfo <pid>' will tell you by which trap & possibly
	address the kernel panicked.
end


define dmesg
	set $i = 0
	set $end_idx = (log_end - 1) & (log_buf_len - 1)

	while ($i < logged_chars)
		set $idx = (log_end - 1 - logged_chars + $i) & (log_buf_len - 1)

		if ($idx + 100 <= $end_idx) || \
		   ($end_idx <= $idx && $idx + 100 < log_buf_len)
			printf "%.100s", &log_buf[$idx]
			set $i = $i + 100
		else
			printf "%c", log_buf[$idx]
			set $i = $i + 1
		end
	end
end
document dmesg
	print the kernel ring buffer
end
