提交 deaee270 编写于 作者: J John Ogness 提交者: Petr Mladek

scripts/gdb: lx-dmesg: read records individually

For the gdb command lx-dmesg, the entire descriptor, info, and text
data regions are read into memory before printing any records. For
large kernel log buffers, this not only causes a huge delay before
seeing any records, but it may also lead to python errors of too
much memory allocation.

Rather than reading in all these regions in advance, read them as
needed and only read the regions for the particular record that is
being printed.

The gdb macro "dmesg" in Documentation/admin-guide/kdump/gdbmacros.txt
already prints out the kernel log buffer like this.
Signed-off-by: NJohn Ogness <john.ogness@linutronix.de>
Signed-off-by: NPetr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/874k79c3a9.fsf@jogness.linutronix.de
上级 52e68cd6
...@@ -44,19 +44,17 @@ class LxDmesg(gdb.Command): ...@@ -44,19 +44,17 @@ class LxDmesg(gdb.Command):
sz = prb_desc_ring_type.get_type().sizeof sz = prb_desc_ring_type.get_type().sizeof
desc_ring = utils.read_memoryview(inf, addr, sz).tobytes() desc_ring = utils.read_memoryview(inf, addr, sz).tobytes()
# read in descriptor array # read in descriptor count, size, and address
off = prb_desc_ring_type.get_type()['count_bits'].bitpos // 8 off = prb_desc_ring_type.get_type()['count_bits'].bitpos // 8
desc_ring_count = 1 << utils.read_u32(desc_ring, off) desc_ring_count = 1 << utils.read_u32(desc_ring, off)
desc_sz = prb_desc_type.get_type().sizeof desc_sz = prb_desc_type.get_type().sizeof
off = prb_desc_ring_type.get_type()['descs'].bitpos // 8 off = prb_desc_ring_type.get_type()['descs'].bitpos // 8
addr = utils.read_ulong(desc_ring, off) desc_addr = utils.read_ulong(desc_ring, off)
descs = utils.read_memoryview(inf, addr, desc_sz * desc_ring_count).tobytes()
# read in info array # read in info size and address
info_sz = printk_info_type.get_type().sizeof info_sz = printk_info_type.get_type().sizeof
off = prb_desc_ring_type.get_type()['infos'].bitpos // 8 off = prb_desc_ring_type.get_type()['infos'].bitpos // 8
addr = utils.read_ulong(desc_ring, off) info_addr = utils.read_ulong(desc_ring, off)
infos = utils.read_memoryview(inf, addr, info_sz * desc_ring_count).tobytes()
# read in text data ring structure # read in text data ring structure
off = printk_ringbuffer_type.get_type()['text_data_ring'].bitpos // 8 off = printk_ringbuffer_type.get_type()['text_data_ring'].bitpos // 8
...@@ -64,12 +62,11 @@ class LxDmesg(gdb.Command): ...@@ -64,12 +62,11 @@ class LxDmesg(gdb.Command):
sz = prb_data_ring_type.get_type().sizeof sz = prb_data_ring_type.get_type().sizeof
text_data_ring = utils.read_memoryview(inf, addr, sz).tobytes() text_data_ring = utils.read_memoryview(inf, addr, sz).tobytes()
# read in text data # read in text data size and address
off = prb_data_ring_type.get_type()['size_bits'].bitpos // 8 off = prb_data_ring_type.get_type()['size_bits'].bitpos // 8
text_data_sz = 1 << utils.read_u32(text_data_ring, off) text_data_sz = 1 << utils.read_u32(text_data_ring, off)
off = prb_data_ring_type.get_type()['data'].bitpos // 8 off = prb_data_ring_type.get_type()['data'].bitpos // 8
addr = utils.read_ulong(text_data_ring, off) text_data_addr = utils.read_ulong(text_data_ring, off)
text_data = utils.read_memoryview(inf, addr, text_data_sz).tobytes()
counter_off = atomic_long_type.get_type()['counter'].bitpos // 8 counter_off = atomic_long_type.get_type()['counter'].bitpos // 8
...@@ -102,17 +99,20 @@ class LxDmesg(gdb.Command): ...@@ -102,17 +99,20 @@ class LxDmesg(gdb.Command):
desc_off = desc_sz * ind desc_off = desc_sz * ind
info_off = info_sz * ind info_off = info_sz * ind
desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes()
# skip non-committed record # skip non-committed record
state = 3 & (utils.read_u64(descs, desc_off + sv_off + state = 3 & (utils.read_u64(desc, sv_off + counter_off) >> desc_flags_shift)
counter_off) >> desc_flags_shift)
if state != desc_committed and state != desc_finalized: if state != desc_committed and state != desc_finalized:
if did == head_id: if did == head_id:
break break
did = (did + 1) & desc_id_mask did = (did + 1) & desc_id_mask
continue continue
begin = utils.read_ulong(descs, desc_off + begin_off) % text_data_sz begin = utils.read_ulong(desc, begin_off) % text_data_sz
end = utils.read_ulong(descs, desc_off + next_off) % text_data_sz end = utils.read_ulong(desc, next_off) % text_data_sz
info = utils.read_memoryview(inf, info_addr + info_off, info_sz).tobytes()
# handle data-less record # handle data-less record
if begin & 1 == 1: if begin & 1 == 1:
...@@ -125,16 +125,17 @@ class LxDmesg(gdb.Command): ...@@ -125,16 +125,17 @@ class LxDmesg(gdb.Command):
# skip over descriptor id # skip over descriptor id
text_start = begin + utils.get_long_type().sizeof text_start = begin + utils.get_long_type().sizeof
text_len = utils.read_u16(infos, info_off + len_off) text_len = utils.read_u16(info, len_off)
# handle truncated message # handle truncated message
if end - text_start < text_len: if end - text_start < text_len:
text_len = end - text_start text_len = end - text_start
text = text_data[text_start:text_start + text_len].decode( text_data = utils.read_memoryview(inf, text_data_addr + text_start,
encoding='utf8', errors='replace') text_len).tobytes()
text = text_data[0:text_len].decode(encoding='utf8', errors='replace')
time_stamp = utils.read_u64(infos, info_off + ts_off) time_stamp = utils.read_u64(info, ts_off)
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(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册