Jan Kiszka | ae7dbaa | 2015-02-17 13:47:04 -0800 | [diff] [blame] | 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 |
Leonard Crestez | 46d10a0 | 2017-07-12 14:34:19 -0700 | [diff] [blame] | 15 | import sys |
Jan Kiszka | ae7dbaa | 2015-02-17 13:47:04 -0800 | [diff] [blame] | 16 | |
| 17 | from linux import utils |
| 18 | |
Joel Colledge | ca210ba | 2019-10-18 20:19:26 -0700 | [diff] [blame^] | 19 | printk_log_type = utils.CachedType("struct printk_log") |
| 20 | |
Jan Kiszka | ae7dbaa | 2015-02-17 13:47:04 -0800 | [diff] [blame] | 21 | |
| 22 | class LxDmesg(gdb.Command): |
| 23 | """Print Linux kernel log buffer.""" |
| 24 | |
| 25 | def __init__(self): |
| 26 | super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA) |
| 27 | |
| 28 | def invoke(self, arg, from_tty): |
André Draszik | d6c9708 | 2017-06-02 14:46:51 -0700 | [diff] [blame] | 29 | log_buf_addr = int(str(gdb.parse_and_eval( |
Leonard Crestez | c454756 | 2017-07-12 14:34:16 -0700 | [diff] [blame] | 30 | "(void *)'printk.c'::log_buf")).split()[0], 16) |
André Draszik | d6c9708 | 2017-06-02 14:46:51 -0700 | [diff] [blame] | 31 | log_first_idx = int(gdb.parse_and_eval("'printk.c'::log_first_idx")) |
| 32 | log_next_idx = int(gdb.parse_and_eval("'printk.c'::log_next_idx")) |
| 33 | log_buf_len = int(gdb.parse_and_eval("'printk.c'::log_buf_len")) |
Jan Kiszka | ae7dbaa | 2015-02-17 13:47:04 -0800 | [diff] [blame] | 34 | |
| 35 | inf = gdb.inferiors()[0] |
| 36 | start = log_buf_addr + log_first_idx |
| 37 | if log_first_idx < log_next_idx: |
| 38 | log_buf_2nd_half = -1 |
| 39 | length = log_next_idx - log_first_idx |
Dom Cote | d21d5b9eb | 2016-05-23 16:25:19 -0700 | [diff] [blame] | 40 | log_buf = utils.read_memoryview(inf, start, length).tobytes() |
Jan Kiszka | ae7dbaa | 2015-02-17 13:47:04 -0800 | [diff] [blame] | 41 | else: |
| 42 | log_buf_2nd_half = log_buf_len - log_first_idx |
Dom Cote | d21d5b9eb | 2016-05-23 16:25:19 -0700 | [diff] [blame] | 43 | a = utils.read_memoryview(inf, start, log_buf_2nd_half) |
| 44 | b = utils.read_memoryview(inf, log_buf_addr, log_next_idx) |
| 45 | log_buf = a.tobytes() + b.tobytes() |
Jan Kiszka | ae7dbaa | 2015-02-17 13:47:04 -0800 | [diff] [blame] | 46 | |
Joel Colledge | ca210ba | 2019-10-18 20:19:26 -0700 | [diff] [blame^] | 47 | length_offset = printk_log_type.get_type()['len'].bitpos // 8 |
| 48 | text_len_offset = printk_log_type.get_type()['text_len'].bitpos // 8 |
| 49 | time_stamp_offset = printk_log_type.get_type()['ts_nsec'].bitpos // 8 |
| 50 | text_offset = printk_log_type.get_type().sizeof |
| 51 | |
Jan Kiszka | ae7dbaa | 2015-02-17 13:47:04 -0800 | [diff] [blame] | 52 | pos = 0 |
| 53 | while pos < log_buf.__len__(): |
Joel Colledge | ca210ba | 2019-10-18 20:19:26 -0700 | [diff] [blame^] | 54 | length = utils.read_u16(log_buf, pos + length_offset) |
Jan Kiszka | ae7dbaa | 2015-02-17 13:47:04 -0800 | [diff] [blame] | 55 | if length == 0: |
| 56 | if log_buf_2nd_half == -1: |
| 57 | gdb.write("Corrupted log buffer!\n") |
| 58 | break |
| 59 | pos = log_buf_2nd_half |
| 60 | continue |
| 61 | |
Joel Colledge | ca210ba | 2019-10-18 20:19:26 -0700 | [diff] [blame^] | 62 | text_len = utils.read_u16(log_buf, pos + text_len_offset) |
| 63 | text_start = pos + text_offset |
| 64 | text = log_buf[text_start:text_start + text_len].decode( |
Leonard Crestez | 46d10a0 | 2017-07-12 14:34:19 -0700 | [diff] [blame] | 65 | encoding='utf8', errors='replace') |
Joel Colledge | ca210ba | 2019-10-18 20:19:26 -0700 | [diff] [blame^] | 66 | time_stamp = utils.read_u64(log_buf, pos + time_stamp_offset) |
Jan Kiszka | ae7dbaa | 2015-02-17 13:47:04 -0800 | [diff] [blame] | 67 | |
Kieran Bingham | b3b0842 | 2016-05-23 16:25:21 -0700 | [diff] [blame] | 68 | for line in text.splitlines(): |
Leonard Crestez | 46d10a0 | 2017-07-12 14:34:19 -0700 | [diff] [blame] | 69 | msg = u"[{time:12.6f}] {line}\n".format( |
Jan Kiszka | ae7dbaa | 2015-02-17 13:47:04 -0800 | [diff] [blame] | 70 | time=time_stamp / 1000000000.0, |
Leonard Crestez | 46d10a0 | 2017-07-12 14:34:19 -0700 | [diff] [blame] | 71 | line=line) |
| 72 | # With python2 gdb.write will attempt to convert unicode to |
| 73 | # ascii and might fail so pass an utf8-encoded str instead. |
| 74 | if sys.hexversion < 0x03000000: |
| 75 | msg = msg.encode(encoding='utf8', errors='replace') |
| 76 | gdb.write(msg) |
Jan Kiszka | ae7dbaa | 2015-02-17 13:47:04 -0800 | [diff] [blame] | 77 | |
| 78 | pos += length |
| 79 | |
| 80 | |
| 81 | LxDmesg() |