]>
git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blob - scripts/gdb/linux/dmesg.py
2 # gdb helper commands and functions for Linux kernel debugging
4 # kernel log buffer dump
6 # Copyright (c) Siemens AG, 2011, 2012
9 # Jan Kiszka <jan.kiszka@siemens.com>
11 # This work is licensed under the terms of the GNU GPL version 2.
17 from linux
import utils
19 printk_info_type
= utils
.CachedType("struct printk_info")
20 prb_data_blk_lpos_type
= utils
.CachedType("struct prb_data_blk_lpos")
21 prb_desc_type
= utils
.CachedType("struct prb_desc")
22 prb_desc_ring_type
= utils
.CachedType("struct prb_desc_ring")
23 prb_data_ring_type
= utils
.CachedType("struct prb_data_ring")
24 printk_ringbuffer_type
= utils
.CachedType("struct printk_ringbuffer")
25 atomic_long_type
= utils
.CachedType("atomic_long_t")
27 class LxDmesg(gdb
.Command
):
28 """Print Linux kernel log buffer."""
31 super(LxDmesg
, self
).__init
__("lx-dmesg", gdb
.COMMAND_DATA
)
33 def invoke(self
, arg
, from_tty
):
34 inf
= gdb
.inferiors()[0]
36 # read in prb structure
37 prb_addr
= int(str(gdb
.parse_and_eval("(void *)'printk.c'::prb")).split()[0], 16)
38 sz
= printk_ringbuffer_type
.get_type().sizeof
39 prb
= utils
.read_memoryview(inf
, prb_addr
, sz
).tobytes()
41 # read in descriptor ring structure
42 off
= printk_ringbuffer_type
.get_type()['desc_ring'].bitpos
// 8
44 sz
= prb_desc_ring_type
.get_type().sizeof
45 desc_ring
= utils
.read_memoryview(inf
, addr
, sz
).tobytes()
47 # read in descriptor array
48 off
= prb_desc_ring_type
.get_type()['count_bits'].bitpos
// 8
49 desc_ring_count
= 1 << utils
.read_u32(desc_ring
, off
)
50 desc_sz
= prb_desc_type
.get_type().sizeof
51 off
= prb_desc_ring_type
.get_type()['descs'].bitpos
// 8
52 addr
= utils
.read_ulong(desc_ring
, off
)
53 descs
= utils
.read_memoryview(inf
, addr
, desc_sz
* desc_ring_count
).tobytes()
56 info_sz
= printk_info_type
.get_type().sizeof
57 off
= prb_desc_ring_type
.get_type()['infos'].bitpos
// 8
58 addr
= utils
.read_ulong(desc_ring
, off
)
59 infos
= utils
.read_memoryview(inf
, addr
, info_sz
* desc_ring_count
).tobytes()
61 # read in text data ring structure
62 off
= printk_ringbuffer_type
.get_type()['text_data_ring'].bitpos
// 8
64 sz
= prb_data_ring_type
.get_type().sizeof
65 text_data_ring
= utils
.read_memoryview(inf
, addr
, sz
).tobytes()
68 off
= prb_data_ring_type
.get_type()['size_bits'].bitpos
// 8
69 text_data_sz
= 1 << utils
.read_u32(text_data_ring
, off
)
70 off
= prb_data_ring_type
.get_type()['data'].bitpos
// 8
71 addr
= utils
.read_ulong(text_data_ring
, off
)
72 text_data
= utils
.read_memoryview(inf
, addr
, text_data_sz
).tobytes()
74 counter_off
= atomic_long_type
.get_type()['counter'].bitpos
// 8
76 sv_off
= prb_desc_type
.get_type()['state_var'].bitpos
// 8
78 off
= prb_desc_type
.get_type()['text_blk_lpos'].bitpos
// 8
79 begin_off
= off
+ (prb_data_blk_lpos_type
.get_type()['begin'].bitpos
// 8)
80 next_off
= off
+ (prb_data_blk_lpos_type
.get_type()['next'].bitpos
// 8)
82 ts_off
= printk_info_type
.get_type()['ts_nsec'].bitpos
// 8
83 len_off
= printk_info_type
.get_type()['text_len'].bitpos
// 8
85 # definitions from kernel/printk/printk_ringbuffer.h
88 desc_sv_bits
= utils
.get_long_type().sizeof
* 8
89 desc_flags_shift
= desc_sv_bits
- 2
90 desc_flags_mask
= 3 << desc_flags_shift
91 desc_id_mask
= ~desc_flags_mask
93 # read in tail and head descriptor ids
94 off
= prb_desc_ring_type
.get_type()['tail_id'].bitpos
// 8
95 tail_id
= utils
.read_u64(desc_ring
, off
+ counter_off
)
96 off
= prb_desc_ring_type
.get_type()['head_id'].bitpos
// 8
97 head_id
= utils
.read_u64(desc_ring
, off
+ counter_off
)
101 ind
= did
% desc_ring_count
102 desc_off
= desc_sz
* ind
103 info_off
= info_sz
* ind
105 # skip non-committed record
106 state
= 3 & (utils
.read_u64(descs
, desc_off
+ sv_off
+
107 counter_off
) >> desc_flags_shift
)
108 if state
!= desc_committed
and state
!= desc_finalized
:
111 did
= (did
+ 1) & desc_id_mask
114 begin
= utils
.read_ulong(descs
, desc_off
+ begin_off
) % text_data_sz
115 end
= utils
.read_ulong(descs
, desc_off
+ next_off
) % text_data_sz
117 # handle data-less record
121 # handle wrapping data block
125 # skip over descriptor id
126 text_start
= begin
+ utils
.get_long_type().sizeof
128 text_len
= utils
.read_u16(infos
, info_off
+ len_off
)
130 # handle truncated message
131 if end
- text_start
< text_len
:
132 text_len
= end
- text_start
134 text
= text_data
[text_start
:text_start
+ text_len
].decode(
135 encoding
='utf8', errors
='replace')
137 time_stamp
= utils
.read_u64(infos
, info_off
+ ts_off
)
139 for line
in text
.splitlines():
140 msg
= u
"[{time:12.6f}] {line}\n".format(
141 time
=time_stamp
/ 1000000000.0,
143 # With python2 gdb.write will attempt to convert unicode to
144 # ascii and might fail so pass an utf8-encoded str instead.
145 if sys
.hexversion
< 0x03000000:
146 msg
= msg
.encode(encoding
='utf8', errors
='replace')
151 did
= (did
+ 1) & desc_id_mask