Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kdump: fix dmesg gdbmacro to work with record based printk

Commit 7ff9554bb578 ("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: Corey 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Corey Minyard and committed by
Linus Torvalds
d8bae33d 65ee03c4

+82 -11
+82 -11
Documentation/kdump/gdbmacros.txt
··· 170 170 address the kernel panicked. 171 171 end 172 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 173 242 174 243 define dmesg 175 - set $i = 0 176 - set $end_idx = (log_end - 1) & (log_buf_len - 1) 244 + set $i = log_first_idx 245 + set $end_idx = log_first_idx 246 + set $prev_flags = 0 177 247 178 - while ($i < logged_chars) 179 - set $idx = (log_end - 1 - logged_chars + $i) & (log_buf_len - 1) 180 - 181 - if ($idx + 100 <= $end_idx) || \ 182 - ($end_idx <= $idx && $idx + 100 < log_buf_len) 183 - printf "%.100s", &log_buf[$idx] 184 - set $i = $i + 100 248 + while (1) 249 + set $msg = ((struct printk_log *) (log_buf + $i)) 250 + if ($msg->len == 0) 251 + set $i = 0 185 252 else 186 - printf "%c", log_buf[$idx] 187 - set $i = $i + 1 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 188 259 end 189 260 end 190 261 end