#
# 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 dump_log_idx
	set $idx = $arg0
	if ($argc > 1)
		set $prev_flags = $arg1
	else
		set $prev_flags = 0
	end
	set $msg = ((struct printk_log *) (log_buf + $idx))
	set $prefix = 1
	set $newline = 1
	set $log = log_buf + $idx + sizeof(*$msg)

	# prev & LOG_CONT && !(msg->flags & LOG_PREIX)
	if (($prev_flags & 8) && !($msg->flags & 4))
		set $prefix = 0
	end

	# msg->flags & LOG_CONT
	if ($msg->flags & 8)
		# (prev & LOG_CONT && !(prev & LOG_NEWLINE))
		if (($prev_flags & 8) && !($prev_flags & 2))
			set $prefix = 0
		end
		# (!(msg->flags & LOG_NEWLINE))
		if (!($msg->flags & 2))
			set $newline = 0
		end
	end

	if ($prefix)
		printf "[%5lu.%06lu] ", $msg->ts_nsec / 1000000000, $msg->ts_nsec % 1000000000
	end
	if ($msg->text_len != 0)
		eval "printf \"%%%d.%ds\", $log", $msg->text_len, $msg->text_len
	end
	if ($newline)
		printf "\n"
	end
	if ($msg->dict_len > 0)
		set $dict = $log + $msg->text_len
		set $idx = 0
		set $line = 1
		while ($idx < $msg->dict_len)
			if ($line)
				printf " "
				set $line = 0
			end
			set $c = $dict[$idx]
			if ($c == '\0')
				printf "\n"
				set $line = 1
			else
				if ($c < ' ' || $c >= 127 || $c == '\\')
					printf "\\x%02x", $c
				else
					printf "%c", $c
				end
			end
			set $idx = $idx + 1
		end
		printf "\n"
	end
end
document dump_log_idx
	Dump a single log given its index in the log buffer.  The first
	parameter is the index into log_buf, the second is optional and
	specified the previous log buffer's flags, used for properly
	formatting continued lines.
end

define dmesg
	set $i = log_first_idx
	set $end_idx = log_first_idx
	set $prev_flags = 0

	while (1)
		set $msg = ((struct printk_log *) (log_buf + $i))
		if ($msg->len == 0)
			set $i = 0
		else
			dump_log_idx $i $prev_flags
			set $i = $i + $msg->len
			set $prev_flags = $msg->flags
		end
		if ($i == $end_idx)
			loop_break
		end
	end
end
document dmesg
	print the kernel ring buffer
end
