Skip to content

Commit 3340a02

Browse files
committed
Fix code style issues and update documentation
1 parent 8967b52 commit 3340a02

File tree

2 files changed

+92
-111
lines changed

2 files changed

+92
-111
lines changed

tools/debug_tools/crash_log_parser/README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ This post-processing tool can be used to parse crash log generated by Mbed-OS wh
44
## Capturing crash log
55
When an exception happens Mbed-OS will print out the crash information to STDOUT.
66
The crash information contains register context at the time exception and current threads in the system.
7-
The information printed out to STDOUT will be similar to below.
7+
The information printed out to STDOUT will be similar to below. Registers captured depends on specific
8+
Cortex-M core you are using. For example, if your target is using Cortex-M0, some registers like
9+
MMFSR, BFSR, UFSR may not be available and will not appear in the crash log.
810

911
++ MbedOS Fault Handler ++
1012

@@ -57,9 +59,9 @@ To generate more information copy and save this crash information to a text file
5759
NOTE: Make sure you copy the section with text "MbedOS Fault Handler" as the this tool looks for that header.
5860

5961
## Running the Crash Log Parser
60-
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>
62+
crash_log_parser.py <Path to Crash log> <Path to Elf/Axf file of the build> <Path to Map file of the build>
6163
For example:
62-
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
64+
crashlogparse.py crash.log C:\MyProject\BUILD\k64f\arm\mbed-os-hf-handler.elf C:\MyProject\BUILD\k64f\arm\mbed-os-hf-handler.map
6365

6466
An example output from running crash_log_parser is shown below.
6567

tools/debug_tools/crash_log_parser/crash_log_parser.py

Lines changed: 87 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@
3131
_PTN = re.compile("([0-9a-f]*) ([Tt]) ([^\t\n]*)(?:\t(.*):([0-9]*))?")
3232

3333
class ElfHelper(object):
34-
def __init__(self, elf_file,map_file):
34+
def __init__(self, elf_file, map_file):
3535

3636
op = check_output([_NM_EXEC, _OPT, elf_file.name])
3737
self.maplines = map_file.readlines()
3838
self.matches = _PTN.findall(op)
39-
self.addrs = [int(x[0],16) for x in self.matches]
39+
self.addrs = [int(x[0], 16) for x in self.matches]
4040

4141
def function_addrs(self):
4242
return self.addrs
@@ -47,85 +47,76 @@ def function_name_for_addr(self, addr):
4747
return funcname
4848

4949
def print_HFSR_info(hfsr):
50-
if(hfsr != 0):
51-
if( int(hfsr,16) & 0x80000000 ):
52-
print("\t\tDebug Event Occured")
53-
if( int(hfsr,16) & 0x40000000 ):
54-
print("\t\tForced exception, a fault with configurable priority has been escalated to HardFault")
55-
if( int(hfsr,16) & 0x2 ):
56-
print("\t\tVector table read fault has occurred")
57-
58-
def print_MMFSR_info(mmfsr,mmfar):
59-
if(mmfsr != 0):
60-
if( int(mmfsr,16) & 0x20 ):
61-
print("\t\tA MemManage fault occurred during FP lazy state preservation")
62-
if( int(mmfsr,16) & 0x10 ):
63-
print("\t\tA derived MemManage fault occurred on exception entry")
64-
if( int(mmfsr,16) & 0x8 ):
65-
print("\t\tA derived MemManage fault occurred on exception return")
66-
if( int(mmfsr,16) & 0x2 ):
67-
if( int(mmfsr,16) & 0x80 ):
68-
print("\t\tData access violation. Faulting address: %s"%(str(mmfar)))
69-
else:
70-
print("\t\tData access violation. WARNING: Fault address in MMFAR is NOT valid")
71-
if( int(mmfsr,16) & 0x1 ):
72-
print("\t\tMPU or Execute Never (XN) default memory map access violation on an instruction fetch has occurred")
50+
if int(hfsr, 16) & 0x80000000:
51+
print("\t\tDebug Event Occured")
52+
if int(hfsr, 16) & 0x40000000:
53+
print("\t\tForced exception, a fault with configurable priority has been escalated to HardFault")
54+
if int(hfsr, 16) & 0x2:
55+
print("\t\tVector table read fault has occurred")
56+
57+
def print_MMFSR_info(mmfsr, mmfar):
58+
if int(mmfsr, 16) & 0x20:
59+
print("\t\tA MemManage fault occurred during FP lazy state preservation")
60+
if int(mmfsr, 16) & 0x10:
61+
print("\t\tA derived MemManage fault occurred on exception entry")
62+
if int(mmfsr, 16) & 0x8:
63+
print("\t\tA derived MemManage fault occurred on exception return")
64+
if int(mmfsr, 16) & 0x2:
65+
if int(mmfsr, 16) & 0x80:
66+
print("\t\tData access violation. Faulting address: %s"%(str(mmfar)))
67+
else:
68+
print("\t\tData access violation. WARNING: Fault address in MMFAR is NOT valid")
69+
if int(mmfsr, 16) & 0x1:
70+
print("\t\tMPU or Execute Never (XN) default memory map access violation on an instruction fetch has occurred")
7371

74-
def print_BFSR_info(bfsr,bfar):
75-
if(bfsr != 0):
76-
if( int(bfsr,16) & 0x20 ):
77-
print("\t\tA bus fault occurred during FP lazy state preservation")
78-
if( int(bfsr,16) & 0x10 ):
79-
print("\t\tA derived bus fault has occurred on exception entry")
80-
if( int(bfsr,16) & 0x8 ):
81-
print("\t\tA derived bus fault has occurred on exception return")
82-
if( int(bfsr,16) & 0x4 ):
83-
print("\t\tImprecise data access error has occurred")
84-
if( int(bfsr,16) & 0x2 ):
85-
if( int(bfsr,16) & 0x80 ):
86-
print("\t\tA precise data access error has occurred. Faulting address: %s"%(str(bfar)))
87-
else:
88-
print("\t\tA precise data access error has occurred. WARNING: Fault address in BFAR is NOT valid")
89-
if( int(bfsr,16) & 0x1 ):
90-
print("\t\tA bus fault on an instruction prefetch has occurred")
72+
def print_BFSR_info(bfsr, bfar):
73+
if int(bfsr, 16) & 0x20:
74+
print("\t\tA bus fault occurred during FP lazy state preservation")
75+
if int(bfsr, 16) & 0x10:
76+
print("\t\tA derived bus fault has occurred on exception entry")
77+
if int(bfsr, 16) & 0x8:
78+
print("\t\tA derived bus fault has occurred on exception return")
79+
if int(bfsr, 16) & 0x4:
80+
print("\t\tImprecise data access error has occurred")
81+
if int(bfsr, 16) & 0x2:
82+
if int(bfsr,16) & 0x80:
83+
print("\t\tA precise data access error has occurred. Faulting address: %s"%(str(bfar)))
84+
else:
85+
print("\t\tA precise data access error has occurred. WARNING: Fault address in BFAR is NOT valid")
86+
if int(bfsr, 16) & 0x1:
87+
print("\t\tA bus fault on an instruction prefetch has occurred")
9188

9289
def print_UFSR_info(ufsr):
93-
if(ufsr != 0):
94-
if( int(ufsr,16) & 0x200 ):
95-
print("\t\tDivide by zero error has occurred")
96-
if( int(ufsr,16) & 0x100 ):
97-
print("\t\tUnaligned access error has occurred")
98-
if( int(ufsr,16) & 0x8 ):
99-
print("\t\tA coprocessor access error has occurred. This shows that the coprocessor is disabled or not present")
100-
if( int(ufsr,16) & 0x4 ):
101-
print("\t\tAn integrity check error has occurred on EXC_RETURN")
102-
if( int(ufsr,16) & 0x2 ):
103-
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 )")
104-
if( int(ufsr,16) & 0x1 ):
105-
print("\t\tThe processor has attempted to execute an undefined instruction")
90+
if int(ufsr, 16) & 0x200:
91+
print("\t\tDivide by zero error has occurred")
92+
if int(ufsr, 16) & 0x100:
93+
print("\t\tUnaligned access error has occurred")
94+
if int(ufsr, 16) & 0x8:
95+
print("\t\tA coprocessor access error has occurred. This shows that the coprocessor is disabled or not present")
96+
if int(ufsr, 16) & 0x4:
97+
print("\t\tAn integrity check error has occurred on EXC_RETURN")
98+
if int(ufsr, 16) & 0x2:
99+
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 )")
100+
if int(ufsr, 16) & 0x1:
101+
print("\t\tThe processor has attempted to execute an undefined instruction")
106102

107103
def print_CPUID_info(cpuid):
108-
if( ( ( int(cpuid,16) & 0xF0000 ) >> 16 ) == 0xC ):
104+
if (int(cpuid, 16) & 0xF0000) == 0xC0000:
109105
print("\t\tProcessor Arch: ARM-V6M")
110106
else:
111107
print("\t\tProcessor Arch: ARM-V7M or above")
112108

113-
print("\t\tProcessor Variant: %X"%(( ( int(cpuid,16) & 0xFFF0 ) >> 4 )))
109+
print("\t\tProcessor Variant: %X" % ((int(cpuid,16) & 0xFFF0 ) >> 4))
114110

115111
def parse_line_for_register(line):
116-
line = re.findall(r"[\w']+", line)
117-
line = [x.strip() for x in line if x != '']
118-
tag, register_val = line
119-
return register_val
112+
_, register_val = line.split(":")
113+
return register_val.strip()
120114

121-
def main(crash_log,elfhelper):
122-
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
115+
def main(crash_log, elfhelper):
123116
mmfar_val = 0
124117
bfar_val = 0
118+
lines = iter(crash_log.readlines())
125119

126-
lines = crash_log.readlines()
127-
128-
cnt = 0
129120
for eachline in lines:
130121
if "++ MbedOS Fault Handler ++" in eachline:
131122
break
@@ -134,51 +125,51 @@ def main(crash_log,elfhelper):
134125
return
135126

136127
for eachline in lines:
137-
if("-- MbedOS Fault Handler --" in eachline):
128+
if "-- MbedOS Fault Handler --" in eachline:
138129
break
139130

140-
elif(eachline.startswith("PC")):
131+
elif eachline.startswith("PC"):
141132
pc_val = parse_line_for_register(eachline)
142-
pc_name = elfhelper.function_name_for_addr(int(pc_val,16))
133+
pc_name = elfhelper.function_name_for_addr(int(pc_val, 16))
143134

144-
elif(eachline.startswith("LR")):
135+
elif eachline.startswith("LR"):
145136
lr_val = parse_line_for_register(eachline)
146-
lr_name = elfhelper.function_name_for_addr(int(lr_val,16))
137+
lr_name = elfhelper.function_name_for_addr(int(lr_val, 16))
147138

148-
elif(eachline.startswith("SP")):
139+
elif eachline.startswith("SP"):
149140
sp_val = parse_line_for_register(eachline)
150141

151-
elif(eachline.startswith("HFSR")):
142+
elif eachline.startswith("HFSR"):
152143
hfsr_val = parse_line_for_register(eachline)
153144

154-
elif(eachline.startswith("MMFSR")):
145+
elif eachline.startswith("MMFSR"):
155146
mmfsr_val = parse_line_for_register(eachline)
156147

157-
elif(eachline.startswith("BFSR")):
148+
elif eachline.startswith("BFSR"):
158149
bfsr_val = parse_line_for_register(eachline)
159150

160-
elif(eachline.startswith("UFSR")):
151+
elif eachline.startswith("UFSR"):
161152
ufsr_val = parse_line_for_register(eachline)
162153

163-
elif(eachline.startswith("CPUID")):
154+
elif eachline.startswith("CPUID"):
164155
cpuid_val = parse_line_for_register(eachline)
165156

166-
elif(eachline.startswith("MMFAR")):
157+
elif eachline.startswith("MMFAR"):
167158
mmfar_val = parse_line_for_register(eachline)
168159

169-
elif(eachline.startswith("BFAR")):
160+
elif eachline.startswith("BFAR"):
170161
bfar_val = parse_line_for_register(eachline)
171162

172-
print("\n\nCrash Info:")
173-
print("\tCrash location = %s [%s] (based on PC value)"%(pc_name.strip(),str(pc_val)))
174-
print("\tCaller location = %s [%s] (based on LR value)"%(lr_name.strip(),str(lr_val)))
175-
print("\tStack Pointer at the time of crash = [%s]"%(str(sp_val)))
163+
print("\nCrash Info:")
164+
print("\tCrash location = %s [0x%s] (based on PC value)" % (pc_name.strip(), str(pc_val)))
165+
print("\tCaller location = %s [0x%s] (based on LR value)" % (lr_name.strip(), str(lr_val)))
166+
print("\tStack Pointer at the time of crash = [%s]" % (str(sp_val)))
176167

177168
print("\tTarget and Fault Info:")
178169
print_CPUID_info(cpuid_val)
179170
print_HFSR_info(hfsr_val)
180-
print_MMFSR_info(mmfsr_val,mmfar_val)
181-
print_BFSR_info(bfsr_val,bfar_val)
171+
print_MMFSR_info(mmfsr_val, mmfar_val)
172+
print_BFSR_info(bfsr_val, bfar_val)
182173
print_UFSR_info(ufsr_val)
183174

184175

@@ -187,35 +178,23 @@ def main(crash_log,elfhelper):
187178

188179
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')
189180
# specify arguments
190-
parser.add_argument('-i','--input', metavar='<path to input file with crash log output>', type=argparse.FileType('rb', 0), required=True,
191-
help='path to input file')
192-
parser.add_argument('-e','--elfpath', metavar='<module or elf file path>', type=argparse.FileType('rb', 0), required=True,
193-
help='path to elf file')
194-
parser.add_argument('-m','--mappath', metavar='<map file path>', type=argparse.FileType('rb', 0), required=True,
195-
help='path to map file')
181+
parser.add_argument(metavar='CRASH LOG', type=argparse.FileType('rb', 0),
182+
dest='crashlog',help='path to crash log file')
183+
parser.add_argument(metavar='ELF FILE', type=argparse.FileType('rb', 0),
184+
dest='elffile',help='path to elf file')
185+
parser.add_argument(metavar='MAP FILE', type=argparse.FileType('rb', 0),
186+
dest='mapfile',help='path to map file')
196187

197188
# get and validate arguments
198189
args = parser.parse_args()
199190

200-
elf_file = args.elfpath
201-
map_file = args.mappath
202-
input_crash_log = args.input
203-
204-
print("Inputs:")
205-
print("\tCrash Log: %s"%(input_crash_log.name))
206-
print("\tElf Path: %s"%(elf_file.name))
207-
print("\tMap Path: %s"%(map_file.name))
208-
209-
elfhelper = ElfHelper(elf_file,map_file)
191+
elfhelper = ElfHelper(args.elffile, args.mapfile)
210192

211193
# parse input and write to output
212-
main(input_crash_log,elfhelper)
194+
main(args.crashlog, elfhelper)
213195

214196
#close all files
215-
elf_file.close()
216-
map_file.close()
217-
input_crash_log.close()
218-
219-
220-
197+
args.elffile.close()
198+
args.mapfile.close()
199+
args.crashlog.close()
221200

0 commit comments

Comments
 (0)