crash_log_parser review comment fixes

pull/5847/head
Senthil Ramakrishnan 2018-01-29 14:54:30 -06:00
parent 96d900c99f
commit 8967b52bfb
1 changed files with 75 additions and 132 deletions

View File

@ -20,28 +20,22 @@ LIBRARIES BUILD
from __future__ import print_function
from os import path
import re, bisect
import re
import bisect
from subprocess import check_output
import sys
#arm-none-eabi-nm -nl <elf file>
NM_EXEC = "arm-none-eabi-nm"
OPT = "-nlC"
ptn = re.compile("([0-9a-f]*) ([Tt]) ([^\t\n]*)(?:\t(.*):([0-9]*))?")
fnt = None
fnt = ""
_NM_EXEC = "arm-none-eabi-nm"
_OPT = "-nlC"
_PTN = re.compile("([0-9a-f]*) ([Tt]) ([^\t\n]*)(?:\t(.*):([0-9]*))?")
class ElfHelper(object):
def __init__(self, p,m):
if path.isfile(p):
elf_path = p
if path.isfile(m):
map_path = m
def __init__(self, elf_file,map_file):
op = check_output([NM_EXEC, OPT, elf_path])
map_file = open(map_path)
op = check_output([_NM_EXEC, _OPT, elf_file.name])
self.maplines = map_file.readlines()
self.matches = ptn.findall(op)
self.matches = _PTN.findall(op)
self.addrs = [int(x[0],16) for x in self.matches]
def function_addrs(self):
@ -52,19 +46,7 @@ class ElfHelper(object):
funcname = self.matches[i-1][2]
return funcname
def file_name_for_function_name(self, funcname):
for eachline in self.maplines:
result = eachline.find(funcname)
if(result != -1):
break
toks = eachline.split()
if(len(toks) <= 0):
print("WARN: Unable to find %s in map file"%(str(funcname)))
return ("%s [FUNCTION]"%(str(funcname)))
else:
return toks[-1]
def parseHFSR(hfsr):
def print_HFSR_info(hfsr):
if(hfsr != 0):
if( int(hfsr,16) & 0x80000000 ):
print("\t\tDebug Event Occured")
@ -73,7 +55,7 @@ def parseHFSR(hfsr):
if( int(hfsr,16) & 0x2 ):
print("\t\tVector table read fault has occurred")
def parseMMFSR(mmfsr,mmfar):
def print_MMFSR_info(mmfsr,mmfar):
if(mmfsr != 0):
if( int(mmfsr,16) & 0x20 ):
print("\t\tA MemManage fault occurred during FP lazy state preservation")
@ -89,7 +71,7 @@ def parseMMFSR(mmfsr,mmfar):
if( int(mmfsr,16) & 0x1 ):
print("\t\tMPU or Execute Never (XN) default memory map access violation on an instruction fetch has occurred")
def parseBFSR(bfsr,bfar):
def print_BFSR_info(bfsr,bfar):
if(bfsr != 0):
if( int(bfsr,16) & 0x20 ):
print("\t\tA bus fault occurred during FP lazy state preservation")
@ -107,7 +89,7 @@ def parseBFSR(bfsr,bfar):
if( int(bfsr,16) & 0x1 ):
print("\t\tA bus fault on an instruction prefetch has occurred")
def parseUFSR(ufsr):
def print_UFSR_info(ufsr):
if(ufsr != 0):
if( int(ufsr,16) & 0x200 ):
print("\t\tDivide by zero error has occurred")
@ -122,7 +104,7 @@ def parseUFSR(ufsr):
if( int(ufsr,16) & 0x1 ):
print("\t\tThe processor has attempted to execute an undefined instruction")
def parseCPUID(cpuid):
def print_CPUID_info(cpuid):
if( ( ( int(cpuid,16) & 0xF0000 ) >> 16 ) == 0xC ):
print("\t\tProcessor Arch: ARM-V6M")
else:
@ -130,148 +112,109 @@ def parseCPUID(cpuid):
print("\t\tProcessor Variant: %X"%(( ( int(cpuid,16) & 0xFFF0 ) >> 4 )))
def parse_line_for_register(line):
line = re.findall(r"[\w']+", line)
line = [x.strip() for x in line if x != '']
tag, register_val = line
return register_val
def main(input):
global fnt, pc_val, pc_name, lr_val, lr_name, sp_val, hfsr_val, mmfsr_val, ufsr_val, bfsr_val, cpuid_val, mmfar_val, bfar_val
start_parsing = False
def main(crash_log,elfhelper):
global pc_val, pc_name, lr_val, lr_name, sp_val, hfsr_val, mmfsr_val, ufsr_val, bfsr_val, cpuid_val, mmfar_val, bfar_val
mmfar_val = 0
bfar_val = 0
crash_file = open(input)
lines = crash_file.readlines()
lines = crash_log.readlines()
cnt = 0
for eachline in lines:
idx = eachline.find("MbedOS Fault Handler")
if(-1 != idx):
if "++ MbedOS Fault Handler ++" in eachline:
break
cnt=cnt+1
if(idx == -1):
else:
print("ERROR: Unable to find \"MbedOS Fault Handler\" header")
return
print("\n\nParsed Crash Info:")
for i in range(cnt,len(lines)):
eachline=lines[i]
if(-1 != eachline.find("--- MbedOS Fault Handler ---")):
for eachline in lines:
if("-- MbedOS Fault Handler --" in eachline):
break
if(eachline.startswith("PC")):
l = re.findall(r"[\w']+", eachline)
l = [x.strip() for x in l if x != '']
tag, pc_val = l
pc_name = fnt.function_name_for_addr(int(pc_val,16))
elif(eachline.startswith("PC")):
pc_val = parse_line_for_register(eachline)
pc_name = elfhelper.function_name_for_addr(int(pc_val,16))
if(eachline.startswith("LR")):
l = re.findall(r"[\w']+", eachline)
l = [x.strip() for x in l if x != '']
tag, lr_val = l
lr_name = fnt.function_name_for_addr(int(lr_val,16))
elif(eachline.startswith("LR")):
lr_val = parse_line_for_register(eachline)
lr_name = elfhelper.function_name_for_addr(int(lr_val,16))
if(eachline.startswith("SP")):
l = re.findall(r"[\w']+", eachline)
l = [x.strip() for x in l if x != '']
tag, sp_val = l
elif(eachline.startswith("SP")):
sp_val = parse_line_for_register(eachline)
if(eachline.startswith("HFSR")):
l = re.findall(r"[\w']+", eachline)
l = [x.strip() for x in l if x != '']
tag, hfsr_val = l
elif(eachline.startswith("HFSR")):
hfsr_val = parse_line_for_register(eachline)
if(eachline.startswith("MMFSR")):
l = re.findall(r"[\w']+", eachline)
l = [x.strip() for x in l if x != '']
tag, mmfsr_val = l
elif(eachline.startswith("MMFSR")):
mmfsr_val = parse_line_for_register(eachline)
if(eachline.startswith("BFSR")):
l = re.findall(r"[\w']+", eachline)
l = [x.strip() for x in l if x != '']
tag, bfsr_val = l
elif(eachline.startswith("BFSR")):
bfsr_val = parse_line_for_register(eachline)
if(eachline.startswith("UFSR")):
l = re.findall(r"[\w']+", eachline)
l = [x.strip() for x in l if x != '']
tag, ufsr_val = l
elif(eachline.startswith("UFSR")):
ufsr_val = parse_line_for_register(eachline)
if(eachline.startswith("CPUID")):
l = re.findall(r"[\w']+", eachline)
l = [x.strip() for x in l if x != '']
tag, cpuid_val = l
elif(eachline.startswith("CPUID")):
cpuid_val = parse_line_for_register(eachline)
if(eachline.startswith("MMFAR")):
l = re.findall(r"[\w']+", eachline)
l = [x.strip() for x in l if x != '']
tag, mmfar_val = l
elif(eachline.startswith("MMFAR")):
mmfar_val = parse_line_for_register(eachline)
if(eachline.startswith("BFAR")):
l = re.findall(r"[\w']+", eachline)
l = [x.strip() for x in l if x != '']
tag, bfar_val = l
elif(eachline.startswith("BFAR")):
bfar_val = parse_line_for_register(eachline)
print("\n\nCrash Info:")
print("\tCrash location = %s [%s] (based on PC value)"%(pc_name.strip(),str(pc_val)))
print("\tCaller location = %s [%s] (based on LR value)"%(lr_name.strip(),str(lr_val)))
print("\tStack Pointer at the time of crash = [%s]"%(str(sp_val)))
print("\tTarget/Fault Info:")
parseCPUID(cpuid_val)
parseHFSR(hfsr_val)
parseMMFSR(mmfsr_val,mmfar_val)
parseBFSR(bfsr_val,bfar_val)
parseUFSR(ufsr_val)
print("\nDone parsing...")
print("\tTarget and Fault Info:")
print_CPUID_info(cpuid_val)
print_HFSR_info(hfsr_val)
print_MMFSR_info(mmfsr_val,mmfar_val)
print_BFSR_info(bfsr_val,bfar_val)
print_UFSR_info(ufsr_val)
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(
description='Analyse mbed-os crash log')
parser = argparse.ArgumentParser(description='Analyse mbed-os crash log. This tool requires arm-gcc binary utilities to be available in current path as it uses \'nm\' command')
# specify arguments
parser.add_argument('-i','--input', metavar='<path to input file with crash log output>', type=str,
parser.add_argument('-i','--input', metavar='<path to input file with crash log output>', type=argparse.FileType('rb', 0), required=True,
help='path to input file')
parser.add_argument('-e','--elfpath', metavar='<module or elf file path>', type=str,
parser.add_argument('-e','--elfpath', metavar='<module or elf file path>', type=argparse.FileType('rb', 0), required=True,
help='path to elf file')
parser.add_argument('-m','--mappath', metavar='<map file path>', type=str,
parser.add_argument('-m','--mappath', metavar='<map file path>', type=argparse.FileType('rb', 0), required=True,
help='path to map file')
# get and validate arguments
args = parser.parse_args()
p = args.elfpath
m = args.mappath
i = args.input
if(p == None or m == None or i == None):
print("Invalid arguments, exiting")
parser.print_usage()
sys.exit(1)
if not path.exists(p):
print("Elf path %s does not exist"%(str(p)))
parser.print_usage()
sys.exit(1)
if not path.exists(m):
print("Map path %s does not exist"%(str(m)))
parser.print_usage()
sys.exit(1)
if not path.exists(i):
print("Input crash log path %s does not exist"%(str(i)))
parser.print_usage()
sys.exit(1)
elf_file = args.elfpath
map_file = args.mappath
input_crash_log = args.input
print("Inputs:")
print("\tCrash Log: %s"%(i))
print("\tElf Path: %s"%(p))
print("\tMap Path: %s"%(m))
print("\tCrash Log: %s"%(input_crash_log.name))
print("\tElf Path: %s"%(elf_file.name))
print("\tMap Path: %s"%(map_file.name))
fnt = ElfHelper(p,m)
elfhelper = ElfHelper(elf_file,map_file)
# parse input and write to output
main(i)
main(input_crash_log,elfhelper)
#close all files
elf_file.close()
map_file.close()
input_crash_log.close()