31
31
_PTN = re .compile ("([0-9a-f]*) ([Tt]) ([^\t \n ]*)(?:\t (.*):([0-9]*))?" )
32
32
33
33
class ElfHelper (object ):
34
- def __init__ (self , elf_file ,map_file ):
34
+ def __init__ (self , elf_file , map_file ):
35
35
36
36
op = check_output ([_NM_EXEC , _OPT , elf_file .name ])
37
37
self .maplines = map_file .readlines ()
38
38
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 ]
40
40
41
41
def function_addrs (self ):
42
42
return self .addrs
@@ -47,85 +47,76 @@ def function_name_for_addr(self, addr):
47
47
return funcname
48
48
49
49
def print_HFSR_info (hfsr ):
50
- if (hfsr != 0 ):
51
- if ( int (hfsr ,16 ) & 0x80000000 ):
52
- print ("\t \t Debug Event Occured" )
53
- if ( int (hfsr ,16 ) & 0x40000000 ):
54
- print ("\t \t Forced exception, a fault with configurable priority has been escalated to HardFault" )
55
- if ( int (hfsr ,16 ) & 0x2 ):
56
- print ("\t \t Vector 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 \t A MemManage fault occurred during FP lazy state preservation" )
62
- if ( int (mmfsr ,16 ) & 0x10 ):
63
- print ("\t \t A derived MemManage fault occurred on exception entry" )
64
- if ( int (mmfsr ,16 ) & 0x8 ):
65
- print ("\t \t A derived MemManage fault occurred on exception return" )
66
- if ( int (mmfsr ,16 ) & 0x2 ):
67
- if ( int (mmfsr ,16 ) & 0x80 ):
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" )
71
- if ( int (mmfsr ,16 ) & 0x1 ):
72
- print ("\t \t MPU or Execute Never (XN) default memory map access violation on an instruction fetch has occurred" )
50
+ if int (hfsr , 16 ) & 0x80000000 :
51
+ print ("\t \t Debug Event Occured" )
52
+ if int (hfsr , 16 ) & 0x40000000 :
53
+ print ("\t \t Forced exception, a fault with configurable priority has been escalated to HardFault" )
54
+ if int (hfsr , 16 ) & 0x2 :
55
+ print ("\t \t Vector table read fault has occurred" )
56
+
57
+ def print_MMFSR_info (mmfsr , mmfar ):
58
+ if int (mmfsr , 16 ) & 0x20 :
59
+ print ("\t \t A MemManage fault occurred during FP lazy state preservation" )
60
+ if int (mmfsr , 16 ) & 0x10 :
61
+ print ("\t \t A derived MemManage fault occurred on exception entry" )
62
+ if int (mmfsr , 16 ) & 0x8 :
63
+ print ("\t \t A derived MemManage fault occurred on exception return" )
64
+ if int (mmfsr , 16 ) & 0x2 :
65
+ 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" )
69
+ 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" )
73
71
74
- def print_BFSR_info (bfsr ,bfar ):
75
- if (bfsr != 0 ):
76
- if ( int (bfsr ,16 ) & 0x20 ):
77
- print ("\t \t A bus fault occurred during FP lazy state preservation" )
78
- if ( int (bfsr ,16 ) & 0x10 ):
79
- print ("\t \t A derived bus fault has occurred on exception entry" )
80
- if ( int (bfsr ,16 ) & 0x8 ):
81
- print ("\t \t A derived bus fault has occurred on exception return" )
82
- if ( int (bfsr ,16 ) & 0x4 ):
83
- print ("\t \t Imprecise data access error has occurred" )
84
- if ( int (bfsr ,16 ) & 0x2 ):
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" )
89
- if ( int (bfsr ,16 ) & 0x1 ):
90
- print ("\t \t A bus fault on an instruction prefetch has occurred" )
72
+ def print_BFSR_info (bfsr , bfar ):
73
+ if int (bfsr , 16 ) & 0x20 :
74
+ print ("\t \t A bus fault occurred during FP lazy state preservation" )
75
+ if int (bfsr , 16 ) & 0x10 :
76
+ print ("\t \t A derived bus fault has occurred on exception entry" )
77
+ if int (bfsr , 16 ) & 0x8 :
78
+ print ("\t \t A derived bus fault has occurred on exception return" )
79
+ if int (bfsr , 16 ) & 0x4 :
80
+ print ("\t \t Imprecise data access error has occurred" )
81
+ 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" )
86
+ if int (bfsr , 16 ) & 0x1 :
87
+ print ("\t \t A bus fault on an instruction prefetch has occurred" )
91
88
92
89
def print_UFSR_info (ufsr ):
93
- if (ufsr != 0 ):
94
- if ( int (ufsr ,16 ) & 0x200 ):
95
- print ("\t \t Divide by zero error has occurred" )
96
- if ( int (ufsr ,16 ) & 0x100 ):
97
- print ("\t \t Unaligned access error has occurred" )
98
- if ( int (ufsr ,16 ) & 0x8 ):
99
- print ("\t \t A coprocessor access error has occurred. This shows that the coprocessor is disabled or not present" )
100
- if ( int (ufsr ,16 ) & 0x4 ):
101
- print ("\t \t An integrity check error has occurred on EXC_RETURN" )
102
- if ( int (ufsr ,16 ) & 0x2 ):
103
- 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 )" )
104
- if ( int (ufsr ,16 ) & 0x1 ):
105
- print ("\t \t The processor has attempted to execute an undefined instruction" )
90
+ if int (ufsr , 16 ) & 0x200 :
91
+ print ("\t \t Divide by zero error has occurred" )
92
+ if int (ufsr , 16 ) & 0x100 :
93
+ print ("\t \t Unaligned access error has occurred" )
94
+ if int (ufsr , 16 ) & 0x8 :
95
+ print ("\t \t A coprocessor access error has occurred. This shows that the coprocessor is disabled or not present" )
96
+ if int (ufsr , 16 ) & 0x4 :
97
+ print ("\t \t An integrity check error has occurred on EXC_RETURN" )
98
+ 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 )" )
100
+ if int (ufsr , 16 ) & 0x1 :
101
+ print ("\t \t The processor has attempted to execute an undefined instruction" )
106
102
107
103
def print_CPUID_info (cpuid ):
108
- if ( ( ( int (cpuid ,16 ) & 0xF0000 ) >> 16 ) == 0xC ) :
104
+ if ( int (cpuid , 16 ) & 0xF0000 ) == 0xC0000 :
109
105
print ("\t \t Processor Arch: ARM-V6M" )
110
106
else :
111
107
print ("\t \t Processor Arch: ARM-V7M or above" )
112
108
113
- print ("\t \t Processor Variant: %X" % (( ( int (cpuid ,16 ) & 0xFFF0 ) >> 4 ) ))
109
+ print ("\t \t Processor Variant: %X" % (( int (cpuid ,16 ) & 0xFFF0 ) >> 4 ))
114
110
115
111
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 ()
120
114
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 ):
123
116
mmfar_val = 0
124
117
bfar_val = 0
118
+ lines = iter (crash_log .readlines ())
125
119
126
- lines = crash_log .readlines ()
127
-
128
- cnt = 0
129
120
for eachline in lines :
130
121
if "++ MbedOS Fault Handler ++" in eachline :
131
122
break
@@ -134,51 +125,51 @@ def main(crash_log,elfhelper):
134
125
return
135
126
136
127
for eachline in lines :
137
- if ( "-- MbedOS Fault Handler --" in eachline ) :
128
+ if "-- MbedOS Fault Handler --" in eachline :
138
129
break
139
130
140
- elif ( eachline .startswith ("PC" ) ):
131
+ elif eachline .startswith ("PC" ):
141
132
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 ))
143
134
144
- elif ( eachline .startswith ("LR" ) ):
135
+ elif eachline .startswith ("LR" ):
145
136
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 ))
147
138
148
- elif ( eachline .startswith ("SP" ) ):
139
+ elif eachline .startswith ("SP" ):
149
140
sp_val = parse_line_for_register (eachline )
150
141
151
- elif ( eachline .startswith ("HFSR" ) ):
142
+ elif eachline .startswith ("HFSR" ):
152
143
hfsr_val = parse_line_for_register (eachline )
153
144
154
- elif ( eachline .startswith ("MMFSR" ) ):
145
+ elif eachline .startswith ("MMFSR" ):
155
146
mmfsr_val = parse_line_for_register (eachline )
156
147
157
- elif ( eachline .startswith ("BFSR" ) ):
148
+ elif eachline .startswith ("BFSR" ):
158
149
bfsr_val = parse_line_for_register (eachline )
159
150
160
- elif ( eachline .startswith ("UFSR" ) ):
151
+ elif eachline .startswith ("UFSR" ):
161
152
ufsr_val = parse_line_for_register (eachline )
162
153
163
- elif ( eachline .startswith ("CPUID" ) ):
154
+ elif eachline .startswith ("CPUID" ):
164
155
cpuid_val = parse_line_for_register (eachline )
165
156
166
- elif ( eachline .startswith ("MMFAR" ) ):
157
+ elif eachline .startswith ("MMFAR" ):
167
158
mmfar_val = parse_line_for_register (eachline )
168
159
169
- elif ( eachline .startswith ("BFAR" ) ):
160
+ elif eachline .startswith ("BFAR" ):
170
161
bfar_val = parse_line_for_register (eachline )
171
162
172
- print ("\n \ n Crash Info:" )
173
- print ("\t Crash location = %s [%s] (based on PC value)" % (pc_name .strip (),str (pc_val )))
174
- print ("\t Caller location = %s [%s] (based on LR value)" % (lr_name .strip (),str (lr_val )))
175
- print ("\t Stack Pointer at the time of crash = [%s]" % (str (sp_val )))
163
+ print ("\n Crash Info:" )
164
+ print ("\t Crash location = %s [0x %s] (based on PC value)" % (pc_name .strip (), str (pc_val )))
165
+ print ("\t Caller location = %s [0x %s] (based on LR value)" % (lr_name .strip (), str (lr_val )))
166
+ print ("\t Stack Pointer at the time of crash = [%s]" % (str (sp_val )))
176
167
177
168
print ("\t Target and Fault Info:" )
178
169
print_CPUID_info (cpuid_val )
179
170
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 )
182
173
print_UFSR_info (ufsr_val )
183
174
184
175
@@ -187,35 +178,23 @@ def main(crash_log,elfhelper):
187
178
188
179
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' )
189
180
# 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' )
196
187
197
188
# get and validate arguments
198
189
args = parser .parse_args ()
199
190
200
- elf_file = args .elfpath
201
- map_file = args .mappath
202
- input_crash_log = args .input
203
-
204
- print ("Inputs:" )
205
- print ("\t Crash Log: %s" % (input_crash_log .name ))
206
- print ("\t Elf Path: %s" % (elf_file .name ))
207
- print ("\t Map Path: %s" % (map_file .name ))
208
-
209
- elfhelper = ElfHelper (elf_file ,map_file )
191
+ elfhelper = ElfHelper (args .elffile , args .mapfile )
210
192
211
193
# parse input and write to output
212
- main (input_crash_log , elfhelper )
194
+ main (args . crashlog , elfhelper )
213
195
214
196
#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 ()
221
200
0 commit comments