scripts/gdb: fix lx-dmesg when CONFIG_PRINTK_CALLER is set

When CONFIG_PRINTK_CALLER is set, struct printk_log contains an
additional member caller_id.  This affects the offset of the log text.
Account for this by using the type information from gdb to determine all
the offsets instead of using hardcoded values.

This fixes following error:

  (gdb) lx-dmesg
  Python Exception <class 'ValueError'> embedded null character:
  Error occurred in Python command: embedded null character

The read_u* utility functions now take an offset argument to make them
easier to use.

Link: http://lkml.kernel.org/r/20191011142500.2339-1-joel.colledge@linbit.com
Signed-off-by: Joel Colledge <joel.colledge@linbit.com>
Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Kieran Bingham <kbingham@kernel.org>
Cc: Leonard Crestez <leonard.crestez@nxp.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Joel Colledge 2019-10-18 20:19:26 -07:00 committed by Linus Torvalds
parent 96c804a6ae
commit ca210ba32e
2 changed files with 25 additions and 16 deletions

View File

@ -16,6 +16,8 @@ import sys
from linux import utils
printk_log_type = utils.CachedType("struct printk_log")
class LxDmesg(gdb.Command):
"""Print Linux kernel log buffer."""
@ -42,9 +44,14 @@ class LxDmesg(gdb.Command):
b = utils.read_memoryview(inf, log_buf_addr, log_next_idx)
log_buf = a.tobytes() + b.tobytes()
length_offset = printk_log_type.get_type()['len'].bitpos // 8
text_len_offset = printk_log_type.get_type()['text_len'].bitpos // 8
time_stamp_offset = printk_log_type.get_type()['ts_nsec'].bitpos // 8
text_offset = printk_log_type.get_type().sizeof
pos = 0
while pos < log_buf.__len__():
length = utils.read_u16(log_buf[pos + 8:pos + 10])
length = utils.read_u16(log_buf, pos + length_offset)
if length == 0:
if log_buf_2nd_half == -1:
gdb.write("Corrupted log buffer!\n")
@ -52,10 +59,11 @@ class LxDmesg(gdb.Command):
pos = log_buf_2nd_half
continue
text_len = utils.read_u16(log_buf[pos + 10:pos + 12])
text = log_buf[pos + 16:pos + 16 + text_len].decode(
text_len = utils.read_u16(log_buf, pos + text_len_offset)
text_start = pos + text_offset
text = log_buf[text_start:text_start + text_len].decode(
encoding='utf8', errors='replace')
time_stamp = utils.read_u64(log_buf[pos:pos + 8])
time_stamp = utils.read_u64(log_buf, pos + time_stamp_offset)
for line in text.splitlines():
msg = u"[{time:12.6f}] {line}\n".format(

View File

@ -92,15 +92,16 @@ def read_memoryview(inf, start, length):
return memoryview(inf.read_memory(start, length))
def read_u16(buffer):
def read_u16(buffer, offset):
buffer_val = buffer[offset:offset + 2]
value = [0, 0]
if type(buffer[0]) is str:
value[0] = ord(buffer[0])
value[1] = ord(buffer[1])
if type(buffer_val[0]) is str:
value[0] = ord(buffer_val[0])
value[1] = ord(buffer_val[1])
else:
value[0] = buffer[0]
value[1] = buffer[1]
value[0] = buffer_val[0]
value[1] = buffer_val[1]
if get_target_endianness() == LITTLE_ENDIAN:
return value[0] + (value[1] << 8)
@ -108,18 +109,18 @@ def read_u16(buffer):
return value[1] + (value[0] << 8)
def read_u32(buffer):
def read_u32(buffer, offset):
if get_target_endianness() == LITTLE_ENDIAN:
return read_u16(buffer[0:2]) + (read_u16(buffer[2:4]) << 16)
return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16)
else:
return read_u16(buffer[2:4]) + (read_u16(buffer[0:2]) << 16)
return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16)
def read_u64(buffer):
def read_u64(buffer, offset):
if get_target_endianness() == LITTLE_ENDIAN:
return read_u32(buffer[0:4]) + (read_u32(buffer[4:8]) << 32)
return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32)
else:
return read_u32(buffer[4:8]) + (read_u32(buffer[0:4]) << 32)
return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32)
target_arch = None