mirror of https://github.com/ARMmbed/mbed-os.git
crash_log_parser review comment fixes
parent
96d900c99f
commit
8967b52bfb
|
@ -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
|
||||
|
||||
op = check_output([NM_EXEC, OPT, elf_path])
|
||||
map_file = open(map_path)
|
||||
def __init__(self, elf_file,map_file):
|
||||
|
||||
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,156 +104,117 @@ 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:
|
||||
print("\t\tProcessor Arch: ARM-V7M or above")
|
||||
|
||||
print("\t\tProcessor Variant: %X"%(( ( int(cpuid,16) & 0xFFF0 ) >> 4 )))
|
||||
|
||||
|
||||
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 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(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()
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue