Fix code style issues and update documentation

pull/5847/head
Senthil Ramakrishnan 2018-01-29 17:45:20 -06:00
parent 8967b52bfb
commit 3340a020ed
2 changed files with 91 additions and 110 deletions

View File

@ -4,7 +4,9 @@ This post-processing tool can be used to parse crash log generated by Mbed-OS wh
## Capturing crash log
When an exception happens Mbed-OS will print out the crash information to STDOUT.
The crash information contains register context at the time exception and current threads in the system.
The information printed out to STDOUT will be similar to below.
The information printed out to STDOUT will be similar to below. Registers captured depends on specific
Cortex-M core you are using. For example, if your target is using Cortex-M0, some registers like
MMFSR, BFSR, UFSR may not be available and will not appear in the crash log.
++ MbedOS Fault Handler ++
@ -57,9 +59,9 @@ To generate more information copy and save this crash information to a text file
NOTE: Make sure you copy the section with text "MbedOS Fault Handler" as the this tool looks for that header.
## Running the Crash Log Parser
crash_log_parser.py -i <Path to Crash log> -e <Path to Elf/Axf file of the build> -m <Path to Map file of the build>
crash_log_parser.py <Path to Crash log> <Path to Elf/Axf file of the build> <Path to Map file of the build>
For example:
crashlogparse.py -i crash.log -e C:\MyProject\BUILD\k64f\arm\mbed-os-hf-handler.elf -m C:\MyProject\BUILD\k64f\arm\mbed-os-hf-handler.map
crashlogparse.py crash.log C:\MyProject\BUILD\k64f\arm\mbed-os-hf-handler.elf C:\MyProject\BUILD\k64f\arm\mbed-os-hf-handler.map
An example output from running crash_log_parser is shown below.

View File

@ -31,12 +31,12 @@ _OPT = "-nlC"
_PTN = re.compile("([0-9a-f]*) ([Tt]) ([^\t\n]*)(?:\t(.*):([0-9]*))?")
class ElfHelper(object):
def __init__(self, elf_file,map_file):
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.addrs = [int(x[0],16) for x in self.matches]
self.addrs = [int(x[0], 16) for x in self.matches]
def function_addrs(self):
return self.addrs
@ -47,85 +47,76 @@ class ElfHelper(object):
return funcname
def print_HFSR_info(hfsr):
if(hfsr != 0):
if( int(hfsr,16) & 0x80000000 ):
if int(hfsr, 16) & 0x80000000:
print("\t\tDebug Event Occured")
if( int(hfsr,16) & 0x40000000 ):
if int(hfsr, 16) & 0x40000000:
print("\t\tForced exception, a fault with configurable priority has been escalated to HardFault")
if( int(hfsr,16) & 0x2 ):
if int(hfsr, 16) & 0x2:
print("\t\tVector table read fault has occurred")
def print_MMFSR_info(mmfsr,mmfar):
if(mmfsr != 0):
if( int(mmfsr,16) & 0x20 ):
def print_MMFSR_info(mmfsr, mmfar):
if int(mmfsr, 16) & 0x20:
print("\t\tA MemManage fault occurred during FP lazy state preservation")
if( int(mmfsr,16) & 0x10 ):
if int(mmfsr, 16) & 0x10:
print("\t\tA derived MemManage fault occurred on exception entry")
if( int(mmfsr,16) & 0x8 ):
if int(mmfsr, 16) & 0x8:
print("\t\tA derived MemManage fault occurred on exception return")
if( int(mmfsr,16) & 0x2 ):
if( int(mmfsr,16) & 0x80 ):
if int(mmfsr, 16) & 0x2:
if int(mmfsr, 16) & 0x80:
print("\t\tData access violation. Faulting address: %s"%(str(mmfar)))
else:
print("\t\tData access violation. WARNING: Fault address in MMFAR is NOT valid")
if( int(mmfsr,16) & 0x1 ):
if int(mmfsr, 16) & 0x1:
print("\t\tMPU or Execute Never (XN) default memory map access violation on an instruction fetch has occurred")
def print_BFSR_info(bfsr,bfar):
if(bfsr != 0):
if( int(bfsr,16) & 0x20 ):
def print_BFSR_info(bfsr, bfar):
if int(bfsr, 16) & 0x20:
print("\t\tA bus fault occurred during FP lazy state preservation")
if( int(bfsr,16) & 0x10 ):
if int(bfsr, 16) & 0x10:
print("\t\tA derived bus fault has occurred on exception entry")
if( int(bfsr,16) & 0x8 ):
if int(bfsr, 16) & 0x8:
print("\t\tA derived bus fault has occurred on exception return")
if( int(bfsr,16) & 0x4 ):
if int(bfsr, 16) & 0x4:
print("\t\tImprecise data access error has occurred")
if( int(bfsr,16) & 0x2 ):
if( int(bfsr,16) & 0x80 ):
if int(bfsr, 16) & 0x2:
if int(bfsr,16) & 0x80:
print("\t\tA precise data access error has occurred. Faulting address: %s"%(str(bfar)))
else:
print("\t\tA precise data access error has occurred. WARNING: Fault address in BFAR is NOT valid")
if( int(bfsr,16) & 0x1 ):
if int(bfsr, 16) & 0x1:
print("\t\tA bus fault on an instruction prefetch has occurred")
def print_UFSR_info(ufsr):
if(ufsr != 0):
if( int(ufsr,16) & 0x200 ):
if int(ufsr, 16) & 0x200:
print("\t\tDivide by zero error has occurred")
if( int(ufsr,16) & 0x100 ):
if int(ufsr, 16) & 0x100:
print("\t\tUnaligned access error has occurred")
if( int(ufsr,16) & 0x8 ):
if int(ufsr, 16) & 0x8:
print("\t\tA coprocessor access error has occurred. This shows that the coprocessor is disabled or not present")
if( int(ufsr,16) & 0x4 ):
if int(ufsr, 16) & 0x4:
print("\t\tAn integrity check error has occurred on EXC_RETURN")
if( int(ufsr,16) & 0x2 ):
if int(ufsr, 16) & 0x2:
print("\t\tInstruction executed with invalid EPSR.T or EPSR.IT field( This may be caused by Thumb bit not being set in branching instruction )")
if( int(ufsr,16) & 0x1 ):
if int(ufsr, 16) & 0x1:
print("\t\tThe processor has attempted to execute an undefined instruction")
def print_CPUID_info(cpuid):
if( ( ( int(cpuid,16) & 0xF0000 ) >> 16 ) == 0xC ):
if (int(cpuid, 16) & 0xF0000) == 0xC0000:
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 )))
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
_, register_val = line.split(":")
return register_val.strip()
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
def main(crash_log, elfhelper):
mmfar_val = 0
bfar_val = 0
lines = iter(crash_log.readlines())
lines = crash_log.readlines()
cnt = 0
for eachline in lines:
if "++ MbedOS Fault Handler ++" in eachline:
break
@ -134,51 +125,51 @@ def main(crash_log,elfhelper):
return
for eachline in lines:
if("-- MbedOS Fault Handler --" in eachline):
if "-- MbedOS Fault Handler --" in eachline:
break
elif(eachline.startswith("PC")):
elif eachline.startswith("PC"):
pc_val = parse_line_for_register(eachline)
pc_name = elfhelper.function_name_for_addr(int(pc_val,16))
pc_name = elfhelper.function_name_for_addr(int(pc_val, 16))
elif(eachline.startswith("LR")):
elif eachline.startswith("LR"):
lr_val = parse_line_for_register(eachline)
lr_name = elfhelper.function_name_for_addr(int(lr_val,16))
lr_name = elfhelper.function_name_for_addr(int(lr_val, 16))
elif(eachline.startswith("SP")):
elif eachline.startswith("SP"):
sp_val = parse_line_for_register(eachline)
elif(eachline.startswith("HFSR")):
elif eachline.startswith("HFSR"):
hfsr_val = parse_line_for_register(eachline)
elif(eachline.startswith("MMFSR")):
elif eachline.startswith("MMFSR"):
mmfsr_val = parse_line_for_register(eachline)
elif(eachline.startswith("BFSR")):
elif eachline.startswith("BFSR"):
bfsr_val = parse_line_for_register(eachline)
elif(eachline.startswith("UFSR")):
elif eachline.startswith("UFSR"):
ufsr_val = parse_line_for_register(eachline)
elif(eachline.startswith("CPUID")):
elif eachline.startswith("CPUID"):
cpuid_val = parse_line_for_register(eachline)
elif(eachline.startswith("MMFAR")):
elif eachline.startswith("MMFAR"):
mmfar_val = parse_line_for_register(eachline)
elif(eachline.startswith("BFAR")):
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("\nCrash Info:")
print("\tCrash location = %s [0x%s] (based on PC value)" % (pc_name.strip(), str(pc_val)))
print("\tCaller location = %s [0x%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 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_MMFSR_info(mmfsr_val, mmfar_val)
print_BFSR_info(bfsr_val, bfar_val)
print_UFSR_info(ufsr_val)
@ -187,35 +178,23 @@ if __name__ == '__main__':
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=argparse.FileType('rb', 0), required=True,
help='path to input file')
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=argparse.FileType('rb', 0), required=True,
help='path to map file')
parser.add_argument(metavar='CRASH LOG', type=argparse.FileType('rb', 0),
dest='crashlog',help='path to crash log file')
parser.add_argument(metavar='ELF FILE', type=argparse.FileType('rb', 0),
dest='elffile',help='path to elf file')
parser.add_argument(metavar='MAP FILE', type=argparse.FileType('rb', 0),
dest='mapfile',help='path to map file')
# get and validate arguments
args = parser.parse_args()
elf_file = args.elfpath
map_file = args.mappath
input_crash_log = args.input
print("Inputs:")
print("\tCrash Log: %s"%(input_crash_log.name))
print("\tElf Path: %s"%(elf_file.name))
print("\tMap Path: %s"%(map_file.name))
elfhelper = ElfHelper(elf_file,map_file)
elfhelper = ElfHelper(args.elffile, args.mapfile)
# parse input and write to output
main(input_crash_log,elfhelper)
main(args.crashlog, elfhelper)
#close all files
elf_file.close()
map_file.close()
input_crash_log.close()
args.elffile.close()
args.mapfile.close()
args.crashlog.close()