Skip to content
Snippets Groups Projects
Commit 779e720e authored by Mitchel Humpherys's avatar Mitchel Humpherys
Browse files

lrdp-v2: refactor dmesg extraction code

It can be useful to extract the dmesg from contexts other than the
--dmesg parser. Refactor the code into a top-level "library" module and
hook the --dmesg parser into that.

Change-Id: I935c05a081b1096d67343f5ce8617febb674b2e0
parent 97cff249
No related branches found
No related tags found
No related merge requests found
# Copyright (c) 2014, The Linux Foundation. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 and
# only version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
import re
import string
from parser_util import cleanupString
class DmesgLib(object):
def __init__(self, ramdump, outfile):
self.ramdump = ramdump
self.wrap_cnt = 0
self.outfile = outfile
def log_from_idx(self, idx, logbuf):
len_offset = self.ramdump.field_offset('struct log', 'len')
msg = logbuf + idx
msg_len = self.ramdump.read_u16(msg + len_offset)
if (msg_len == 0):
return logbuf
else:
return msg
def log_next(self, idx, logbuf):
len_offset = self.ramdump.field_offset('struct log', 'len')
msg = idx
msg_len = self.ramdump.read_u16(msg + len_offset)
if (msg_len == 0):
self.wrap_cnt += 1
return logbuf
else:
return idx + msg_len
def extract_dmesg_flat(self):
addr = self.ramdump.read_word(self.ramdump.addr_lookup('log_buf'))
size = self.ramdump.read_word(self.ramdump.addr_lookup('log_buf_len'))
dmesg = self.ramdump.read_physical(self.ramdump.virt_to_phys(addr), size)
self.outfile.write(cleanupString(dmesg.decode('ascii', 'ignore')) + '\n')
def extract_dmesg_binary(self):
first_idx_addr = self.ramdump.addr_lookup('log_first_idx')
last_idx_addr = self.ramdump.addr_lookup('log_next_idx')
logbuf_addr = self.ramdump.read_word(self.ramdump.addr_lookup('log_buf'))
time_offset = self.ramdump.field_offset('struct log', 'ts_nsec')
len_offset = self.ramdump.field_offset('struct log', 'len')
text_len_offset = self.ramdump.field_offset('struct log', 'text_len')
log_size = self.ramdump.sizeof('struct log')
first_idx = self.ramdump.read_u32(first_idx_addr)
last_idx = self.ramdump.read_u32(last_idx_addr)
curr_idx = logbuf_addr + first_idx
while curr_idx != logbuf_addr + last_idx and self.wrap_cnt < 2:
timestamp = self.ramdump.read_dword(curr_idx + time_offset)
text_len = self.ramdump.read_u16(curr_idx + text_len_offset)
text_str = self.ramdump.read_cstring(curr_idx + log_size, text_len)
for partial in text_str.split('\n'):
f = '[{0:>5}.{1:0>6d}] {2}\n'.format(
timestamp / 1000000000, (timestamp % 1000000000) / 1000, partial)
self.outfile.write(f)
curr_idx = self.log_next(curr_idx, logbuf_addr)
def extract_dmesg(self):
if re.search('3.7.\d', self.ramdump.version) is not None:
self.extract_dmesg_binary()
elif re.search('3\.10\.\d', self.ramdump.version) is not None:
self.extract_dmesg_binary()
else:
self.extract_dmesg_flat()
...@@ -9,75 +9,12 @@ ...@@ -9,75 +9,12 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
import re from parser_util import register_parser, RamParser
import string import print_out
import dmesglib
from print_out import print_out_str
from parser_util import register_parser, RamParser, cleanupString
@register_parser('--dmesg', 'Print the dmesg', shortopt='-d') @register_parser('--dmesg', 'Print the dmesg', shortopt='-d')
class Dmesg(RamParser): class Dmesg(RamParser):
def __init__(self, *args):
super(Dmesg, self).__init__(*args)
self.wrap_cnt = 0
def extract_dmesg_flat(self, ramdump):
addr = ramdump.read_word(ramdump.addr_lookup('log_buf'))
size = ramdump.read_word(ramdump.addr_lookup('log_buf_len'))
dmesg = ramdump.read_physical(ramdump.virt_to_phys(addr), size)
print_out_str(cleanupString(dmesg.decode('ascii', 'ignore')))
def log_from_idx(self, ramdump, idx, logbuf):
len_offset = ramdump.field_offset('struct log', 'len')
msg = logbuf + idx
msg_len = ramdump.read_u16(msg + len_offset)
if (msg_len == 0):
return logbuf
else:
return msg
def log_next(self, ramdump, idx, logbuf):
len_offset = ramdump.field_offset('struct log', 'len')
msg = idx
msg_len = ramdump.read_u16(msg + len_offset)
if (msg_len == 0):
self.wrap_cnt += 1
return logbuf
else:
return idx + msg_len
def extract_dmesg_binary(self, ramdump):
first_idx_addr = ramdump.addr_lookup('log_first_idx')
last_idx_addr = ramdump.addr_lookup('log_next_idx')
logbuf_addr = ramdump.read_word(ramdump.addr_lookup('log_buf'))
time_offset = ramdump.field_offset('struct log', 'ts_nsec')
len_offset = ramdump.field_offset('struct log', 'len')
text_len_offset = ramdump.field_offset('struct log', 'text_len')
log_size = ramdump.sizeof('struct log')
first_idx = ramdump.read_u32(first_idx_addr)
last_idx = ramdump.read_u32(last_idx_addr)
curr_idx = logbuf_addr + first_idx
while curr_idx != logbuf_addr + last_idx and self.wrap_cnt < 2:
timestamp = ramdump.read_dword(curr_idx + time_offset)
text_len = ramdump.read_u16(curr_idx + text_len_offset)
text_str = ramdump.read_cstring(curr_idx + log_size, text_len)
for partial in text_str.split('\n'):
f = '[{0:>5}.{1:0>6d}] {2}'.format(
timestamp / 1000000000, (timestamp % 1000000000) / 1000, partial)
print_out_str(f)
curr_idx = self.log_next(ramdump, curr_idx, logbuf_addr)
def parse(self): def parse(self):
if re.search('3.7.\d', self.ramdump.version) is not None: dmesglib.DmesgLib(self.ramdump, print_out.out_file).extract_dmesg()
self.extract_dmesg_binary(self.ramdump)
elif re.search('3\.10\.\d', self.ramdump.version) is not None:
self.extract_dmesg_binary(self.ramdump)
else:
self.extract_dmesg_flat(self.ramdump)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment