2525from subprocess import check_output
2626import sys
2727
28- #arm-none-eabi-nm -nl <elf file>
28+ # arm-none-eabi-nm -nl <elf file>
2929_NM_EXEC = "arm-none-eabi-nm"
3030_OPT = "-nlC"
3131_PTN = re .compile ("([0-9a-f]*) ([Tt]) ([^\t \n ]*)(?:\t (.*):([0-9]*))?" )
3232
33+
3334class ElfHelper (object ):
3435 def __init__ (self , elf_file , map_file ):
35-
36- op = check_output ([_NM_EXEC , _OPT , elf_file .name ]).decode ('utf-8' )
36+ op = check_output ([_NM_EXEC , _OPT , elf_file .name ]).decode ("utf-8" )
3737 self .maplines = map_file .readlines ()
3838 self .matches = _PTN .findall (op )
3939 self .addrs = [int (x [0 ], 16 ) for x in self .matches ]
40-
40+
4141 def function_addrs (self ):
4242 return self .addrs
43-
43+
4444 def function_name_for_addr (self , addr ):
4545 i = bisect .bisect_right (self .addrs , addr )
46- funcname = self .matches [i - 1 ][2 ]
46+ funcname = self .matches [i - 1 ][2 ]
4747 return funcname
4848
49+
4950def print_HFSR_info (hfsr ):
5051 if int (hfsr , 16 ) & 0x80000000 :
5152 print ("\t \t Debug Event Occurred" )
5253 if int (hfsr , 16 ) & 0x40000000 :
53- print ("\t \t Forced exception, a fault with configurable priority has been escalated to HardFault" )
54+ print ("\t \t Forced exception, a fault with configurable priority has been escalated to HardFault" )
5455 if int (hfsr , 16 ) & 0x2 :
55- print ("\t \t Vector table read fault has occurred" )
56+ print ("\t \t Vector table read fault has occurred" )
5657
57- def print_MMFSR_info (mmfsr , mmfar ):
58+
59+ def print_MMFSR_info (mmfsr , mmfar ):
5860 if int (mmfsr , 16 ) & 0x20 :
5961 print ("\t \t A MemManage fault occurred during FP lazy state preservation" )
6062 if int (mmfsr , 16 ) & 0x10 :
61- print ("\t \t A derived MemManage fault occurred on exception entry" )
63+ print ("\t \t A derived MemManage fault occurred on exception entry" )
6264 if int (mmfsr , 16 ) & 0x8 :
63- print ("\t \t A derived MemManage fault occurred on exception return" )
65+ print ("\t \t A derived MemManage fault occurred on exception return" )
6466 if int (mmfsr , 16 ) & 0x2 :
6567 if int (mmfsr , 16 ) & 0x80 :
66- print ("\t \t Data access violation. Faulting address: %s" % (str (mmfar )))
67- else :
68- print ("\t \t Data access violation. WARNING: Fault address in MMFAR is NOT valid" )
68+ print ("\t \t Data access violation. Faulting address: %s" % (str (mmfar )))
69+ else :
70+ print ("\t \t Data access violation. WARNING: Fault address in MMFAR is NOT valid" )
6971 if int (mmfsr , 16 ) & 0x1 :
70- print ("\t \t MPU or Execute Never (XN) default memory map access violation on an instruction fetch has occurred" )
71-
72+ print ("\t \t MPU or Execute Never (XN) default memory map access violation on an instruction fetch has occurred" )
73+
74+
7275def print_BFSR_info (bfsr , bfar ):
7376 if int (bfsr , 16 ) & 0x20 :
7477 print ("\t \t A bus fault occurred during FP lazy state preservation" )
7578 if int (bfsr , 16 ) & 0x10 :
76- print ("\t \t A derived bus fault has occurred on exception entry" )
79+ print ("\t \t A derived bus fault has occurred on exception entry" )
7780 if int (bfsr , 16 ) & 0x8 :
78- print ("\t \t A derived bus fault has occurred on exception return" )
81+ print ("\t \t A derived bus fault has occurred on exception return" )
7982 if int (bfsr , 16 ) & 0x4 :
80- print ("\t \t Imprecise data access error has occurred" )
83+ print ("\t \t Imprecise data access error has occurred" )
8184 if int (bfsr , 16 ) & 0x2 :
82- if int (bfsr ,16 ) & 0x80 :
83- print ("\t \t A precise data access error has occurred. Faulting address: %s" % (str (bfar )))
84- else :
85- print ("\t \t A precise data access error has occurred. WARNING: Fault address in BFAR is NOT valid" )
85+ if int (bfsr , 16 ) & 0x80 :
86+ print ("\t \t A precise data access error has occurred. Faulting address: %s" % (str (bfar )))
87+ else :
88+ print ("\t \t A precise data access error has occurred. WARNING: Fault address in BFAR is NOT valid" )
8689 if int (bfsr , 16 ) & 0x1 :
87- print ("\t \t A bus fault on an instruction prefetch has occurred" )
90+ print ("\t \t A bus fault on an instruction prefetch has occurred" )
91+
8892
89- def print_UFSR_info (ufsr ):
93+ def print_UFSR_info (ufsr ):
9094 if int (ufsr , 16 ) & 0x200 :
9195 print ("\t \t Divide by zero error has occurred" )
9296 if int (ufsr , 16 ) & 0x100 :
@@ -96,100 +100,120 @@ def print_UFSR_info(ufsr):
96100 if int (ufsr , 16 ) & 0x4 :
97101 print ("\t \t An integrity check error has occurred on EXC_RETURN" )
98102 if int (ufsr , 16 ) & 0x2 :
99- print ("\t \t Instruction executed with invalid EPSR.T or EPSR.IT field( This may be caused by Thumb bit not being set in branching instruction )" )
103+ print (
104+ "\t \t Instruction executed with invalid EPSR.T or EPSR.IT field( This may be caused by Thumb bit not being set in branching instruction )"
105+ )
100106 if int (ufsr , 16 ) & 0x1 :
101- print ("\t \t The processor has attempted to execute an undefined instruction" )
102-
103- def print_CPUID_info (cpuid ):
107+ print ("\t \t The processor has attempted to execute an undefined instruction" )
108+
109+
110+ def print_CPUID_info (cpuid ):
104111 if (int (cpuid , 16 ) & 0xF0000 ) == 0xC0000 :
105112 print ("\t \t Processor Arch: ARM-V6M" )
106- else :
113+ else :
107114 print ("\t \t Processor Arch: ARM-V7M or above" )
108-
109- print ("\t \t Processor Variant: %X" % ((int (cpuid ,16 ) & 0xFFF0 ) >> 4 ))
115+
116+ print ("\t \t Processor Variant: %X" % ((int (cpuid , 16 ) & 0xFFF0 ) >> 4 ))
117+
110118
111119def parse_line_for_register (line ):
112120 _ , register_val = line .split (":" )
113- return register_val .strip ()
121+ return register_val .strip ()
122+
114123
115124def main (crash_log , elfhelper ):
116125 mmfar_val = 0
117126 bfar_val = 0
118- lines = iter (crash_log .read ().decode (' utf-8' ).splitlines ())
127+ lines = iter (crash_log .read ().decode (" utf-8" ).splitlines ())
119128
120129 for eachline in lines :
121130 if "++ MbedOS Fault Handler ++" in eachline :
122131 break
123132 else :
124- print (" ERROR: Unable to find \ " MbedOS Fault Handler\ " header" )
133+ print (' ERROR: Unable to find "MbedOS Fault Handler" header' )
125134 return
126-
135+
127136 for eachline in lines :
128137 if "-- MbedOS Fault Handler --" in eachline :
129138 break
130-
139+
131140 elif eachline .startswith ("PC" ):
132141 pc_val = parse_line_for_register (eachline )
133142 if elfhelper :
134143 pc_name = elfhelper .function_name_for_addr (int (pc_val , 16 ))
135144 else :
136145 pc_name = "<unknown-symbol>"
137-
146+
138147 elif eachline .startswith ("LR" ):
139148 lr_val = parse_line_for_register (eachline )
140149 if elfhelper :
141150 lr_name = elfhelper .function_name_for_addr (int (lr_val , 16 ))
142151 else :
143152 lr_name = "<unknown-symbol>"
144-
153+
145154 elif eachline .startswith ("SP" ):
146155 sp_val = parse_line_for_register (eachline )
147-
156+
148157 elif eachline .startswith ("HFSR" ):
149158 hfsr_val = parse_line_for_register (eachline )
150-
159+
151160 elif eachline .startswith ("MMFSR" ):
152161 mmfsr_val = parse_line_for_register (eachline )
153-
162+
154163 elif eachline .startswith ("BFSR" ):
155164 bfsr_val = parse_line_for_register (eachline )
156-
165+
157166 elif eachline .startswith ("UFSR" ):
158167 ufsr_val = parse_line_for_register (eachline )
159-
168+
160169 elif eachline .startswith ("CPUID" ):
161170 cpuid_val = parse_line_for_register (eachline )
162-
171+
163172 elif eachline .startswith ("MMFAR" ):
164173 mmfar_val = parse_line_for_register (eachline )
165-
174+
166175 elif eachline .startswith ("BFAR" ):
167- bfar_val = parse_line_for_register (eachline )
168-
169- print ("\n Crash Info:" )
176+ bfar_val = parse_line_for_register (eachline )
177+
178+ print ("\n Crash Info:" )
170179 print ("\t Crash location = %s [0x%s] (based on PC value)" % (pc_name .strip (), str (pc_val )))
171- print ("\t Caller location = %s [0x%s] (based on LR value)" % (lr_name .strip (), str (lr_val )))
180+ print ("\t Caller location = %s [0x%s] (based on LR value)" % (lr_name .strip (), str (lr_val )))
172181 print ("\t Stack Pointer at the time of crash = [%s]" % (str (sp_val )))
173-
182+
174183 print ("\t Target and Fault Info:" )
175184 print_CPUID_info (cpuid_val )
176185 print_HFSR_info (hfsr_val )
177186 print_MMFSR_info (mmfsr_val , mmfar_val )
178187 print_BFSR_info (bfsr_val , bfar_val )
179188 print_UFSR_info (ufsr_val )
180-
181-
182- if __name__ == ' __main__' :
189+
190+
191+ if __name__ == " __main__" :
183192 import argparse
184-
185- 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' )
193+
194+ parser = argparse .ArgumentParser (
195+ description = "Analyse mbed-os crash log. This tool requires arm-gcc binary utilities to be available in current path as it uses 'nm' command"
196+ )
186197 # specify arguments
187- parser .add_argument (metavar = 'CRASH LOG' , type = argparse .FileType ('rb' , 0 ),
188- dest = 'crashlog' ,help = 'path to crash log file' )
189- parser .add_argument (metavar = 'ELF FILE' , type = argparse .FileType ('rb' , 0 ),
190- nargs = '?' ,const = None ,dest = 'elffile' ,help = 'path to elf file' )
191- parser .add_argument (metavar = 'MAP FILE' , type = argparse .FileType ('rb' , 0 ),
192- nargs = '?' ,const = None ,dest = 'mapfile' ,help = 'path to map file' )
198+ parser .add_argument (
199+ metavar = "CRASH LOG" , type = argparse .FileType ("rb" , 0 ), dest = "crashlog" , help = "path to crash log file"
200+ )
201+ parser .add_argument (
202+ metavar = "ELF FILE" ,
203+ type = argparse .FileType ("rb" , 0 ),
204+ nargs = "?" ,
205+ const = None ,
206+ dest = "elffile" ,
207+ help = "path to elf file" ,
208+ )
209+ parser .add_argument (
210+ metavar = "MAP FILE" ,
211+ type = argparse .FileType ("rb" , 0 ),
212+ nargs = "?" ,
213+ const = None ,
214+ dest = "mapfile" ,
215+ help = "path to map file" ,
216+ )
193217
194218 # get and validate arguments
195219 args = parser .parse_args ()
@@ -200,14 +224,13 @@ def main(crash_log, elfhelper):
200224 else :
201225 print ("ELF or MAP file missing, logging raw values." )
202226 elfhelper = None
203-
227+
204228 # parse input and write to output
205229 main (args .crashlog , elfhelper )
206-
207- #close all files
230+
231+ # close all files
208232 if args .elffile :
209233 args .elffile .close ()
210234 if args .mapfile :
211235 args .mapfile .close ()
212236 args .crashlog .close ()
213-
0 commit comments