Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8bae33d authored by Corey Minyard's avatar Corey Minyard Committed by Linus Torvalds
Browse files

kdump: fix dmesg gdbmacro to work with record based printk

Commit 7ff9554b ("printk: convert byte-buffer to variable-length
record buffer") introduced a record based printk buffer.  Modify
gdbmacros.txt to parse this new structure so dmesg will work properly.

Link: http://lkml.kernel.org/r/1463515794-1599-1-git-send-email-minyard@acm.org


Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 65ee03c4
Loading
Loading
Loading
Loading
+82 −11
Original line number Diff line number Diff line
@@ -170,21 +170,92 @@ document trapinfo
	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)

define dmesg
	set $i = 0
	set $end_idx = (log_end - 1) & (log_buf_len - 1)
	# prev & LOG_CONT && !(msg->flags & LOG_PREIX)
	if (($prev_flags & 8) && !($msg->flags & 4))
		set $prefix = 0
	end

	while ($i < logged_chars)
		set $idx = (log_end - 1 - logged_chars + $i) & (log_buf_len - 1)
	# 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 ($idx + 100 <= $end_idx) || \
		   ($end_idx <= $idx && $idx + 100 < log_buf_len)
			printf "%.100s", &log_buf[$idx]
			set $i = $i + 100
	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", log_buf[$idx]
			set $i = $i + 1
					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