]>
Commit | Line | Data |
---|---|---|
ae7dbaad JK |
1 | # |
2 | # gdb helper commands and functions for Linux kernel debugging | |
3 | # | |
4 | # kernel log buffer dump | |
5 | # | |
6 | # Copyright (c) Siemens AG, 2011, 2012 | |
7 | # | |
8 | # Authors: | |
9 | # Jan Kiszka <jan.kiszka@siemens.com> | |
10 | # | |
11 | # This work is licensed under the terms of the GNU GPL version 2. | |
12 | # | |
13 | ||
14 | import gdb | |
46d10a09 | 15 | import sys |
ae7dbaad JK |
16 | |
17 | from linux import utils | |
18 | ||
19 | ||
20 | class LxDmesg(gdb.Command): | |
21 | """Print Linux kernel log buffer.""" | |
22 | ||
23 | def __init__(self): | |
24 | super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA) | |
25 | ||
26 | def invoke(self, arg, from_tty): | |
d6c97087 | 27 | log_buf_addr = int(str(gdb.parse_and_eval( |
c454756f | 28 | "(void *)'printk.c'::log_buf")).split()[0], 16) |
d6c97087 AD |
29 | log_first_idx = int(gdb.parse_and_eval("'printk.c'::log_first_idx")) |
30 | log_next_idx = int(gdb.parse_and_eval("'printk.c'::log_next_idx")) | |
31 | log_buf_len = int(gdb.parse_and_eval("'printk.c'::log_buf_len")) | |
ae7dbaad JK |
32 | |
33 | inf = gdb.inferiors()[0] | |
34 | start = log_buf_addr + log_first_idx | |
35 | if log_first_idx < log_next_idx: | |
36 | log_buf_2nd_half = -1 | |
37 | length = log_next_idx - log_first_idx | |
d21d5b9e | 38 | log_buf = utils.read_memoryview(inf, start, length).tobytes() |
ae7dbaad JK |
39 | else: |
40 | log_buf_2nd_half = log_buf_len - log_first_idx | |
d21d5b9e DC |
41 | a = utils.read_memoryview(inf, start, log_buf_2nd_half) |
42 | b = utils.read_memoryview(inf, log_buf_addr, log_next_idx) | |
43 | log_buf = a.tobytes() + b.tobytes() | |
ae7dbaad JK |
44 | |
45 | pos = 0 | |
46 | while pos < log_buf.__len__(): | |
47 | length = utils.read_u16(log_buf[pos + 8:pos + 10]) | |
48 | if length == 0: | |
49 | if log_buf_2nd_half == -1: | |
50 | gdb.write("Corrupted log buffer!\n") | |
51 | break | |
52 | pos = log_buf_2nd_half | |
53 | continue | |
54 | ||
55 | text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) | |
46d10a09 LC |
56 | text = log_buf[pos + 16:pos + 16 + text_len].decode( |
57 | encoding='utf8', errors='replace') | |
ae7dbaad JK |
58 | time_stamp = utils.read_u64(log_buf[pos:pos + 8]) |
59 | ||
b3b08429 | 60 | for line in text.splitlines(): |
46d10a09 | 61 | msg = u"[{time:12.6f}] {line}\n".format( |
ae7dbaad | 62 | time=time_stamp / 1000000000.0, |
46d10a09 LC |
63 | line=line) |
64 | # With python2 gdb.write will attempt to convert unicode to | |
65 | # ascii and might fail so pass an utf8-encoded str instead. | |
66 | if sys.hexversion < 0x03000000: | |
67 | msg = msg.encode(encoding='utf8', errors='replace') | |
68 | gdb.write(msg) | |
ae7dbaad JK |
69 | |
70 | pos += length | |
71 | ||
72 | ||
73 | LxDmesg() |