Commit ca210ba3 authored by Joel Colledge's avatar Joel Colledge Committed by Linus Torvalds

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.comSigned-off-by: default avatarJoel Colledge <joel.colledge@linbit.com>
Reviewed-by: default avatarJan Kiszka <jan.kiszka@siemens.com>
Cc: Kieran Bingham <kbingham@kernel.org>
Cc: Leonard Crestez <leonard.crestez@nxp.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 96c804a6
...@@ -16,6 +16,8 @@ import sys ...@@ -16,6 +16,8 @@ import sys
from linux import utils from linux import utils
printk_log_type = utils.CachedType("struct printk_log")
class LxDmesg(gdb.Command): class LxDmesg(gdb.Command):
"""Print Linux kernel log buffer.""" """Print Linux kernel log buffer."""
...@@ -42,9 +44,14 @@ class LxDmesg(gdb.Command): ...@@ -42,9 +44,14 @@ class LxDmesg(gdb.Command):
b = utils.read_memoryview(inf, log_buf_addr, log_next_idx) b = utils.read_memoryview(inf, log_buf_addr, log_next_idx)
log_buf = a.tobytes() + b.tobytes() 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 pos = 0
while pos < log_buf.__len__(): 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 length == 0:
if log_buf_2nd_half == -1: if log_buf_2nd_half == -1:
gdb.write("Corrupted log buffer!\n") gdb.write("Corrupted log buffer!\n")
...@@ -52,10 +59,11 @@ class LxDmesg(gdb.Command): ...@@ -52,10 +59,11 @@ class LxDmesg(gdb.Command):
pos = log_buf_2nd_half pos = log_buf_2nd_half
continue continue
text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) text_len = utils.read_u16(log_buf, pos + text_len_offset)
text = log_buf[pos + 16:pos + 16 + text_len].decode( text_start = pos + text_offset
text = log_buf[text_start:text_start + text_len].decode(
encoding='utf8', errors='replace') 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(): for line in text.splitlines():
msg = u"[{time:12.6f}] {line}\n".format( msg = u"[{time:12.6f}] {line}\n".format(
......
...@@ -92,15 +92,16 @@ def read_memoryview(inf, start, length): ...@@ -92,15 +92,16 @@ def read_memoryview(inf, start, length):
return memoryview(inf.read_memory(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] value = [0, 0]
if type(buffer[0]) is str: if type(buffer_val[0]) is str:
value[0] = ord(buffer[0]) value[0] = ord(buffer_val[0])
value[1] = ord(buffer[1]) value[1] = ord(buffer_val[1])
else: else:
value[0] = buffer[0] value[0] = buffer_val[0]
value[1] = buffer[1] value[1] = buffer_val[1]
if get_target_endianness() == LITTLE_ENDIAN: if get_target_endianness() == LITTLE_ENDIAN:
return value[0] + (value[1] << 8) return value[0] + (value[1] << 8)
...@@ -108,18 +109,18 @@ def read_u16(buffer): ...@@ -108,18 +109,18 @@ def read_u16(buffer):
return value[1] + (value[0] << 8) return value[1] + (value[0] << 8)
def read_u32(buffer): def read_u32(buffer, offset):
if get_target_endianness() == LITTLE_ENDIAN: 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: 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: 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: 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 target_arch = None
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment