Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
crash_log_parser.py
00001 #!/usr/bin/env python 00002 """ 00003 mbed SDK 00004 Copyright (c) 2017-2019 ARM Limited 00005 00006 Licensed under the Apache License, Version 2.0 (the "License"); 00007 you may not use this file except in compliance with the License. 00008 You may obtain a copy of the License at 00009 00010 http://www.apache.org/licenses/LICENSE-2.0 00011 00012 Unless required by applicable law or agreed to in writing, software 00013 distributed under the License is distributed on an "AS IS" BASIS, 00014 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 See the License for the specific language governing permissions and 00016 limitations under the License. 00017 00018 LIBRARIES BUILD 00019 """ 00020 00021 from __future__ import print_function 00022 from os import path 00023 import re 00024 import bisect 00025 from subprocess import check_output 00026 import sys 00027 00028 #arm-none-eabi-nm -nl <elf file> 00029 _NM_EXEC = "arm-none-eabi-nm" 00030 _OPT = "-nlC" 00031 _PTN = re.compile("([0-9a-f]*) ([Tt]) ([^\t\n]*)(?:\t(.*):([0-9]*))?") 00032 00033 class ElfHelper(object): 00034 def __init__(self, elf_file, map_file): 00035 00036 op = check_output([_NM_EXEC, _OPT, elf_file.name]) 00037 self.maplines = map_file.readlines() 00038 self.matches = _PTN.findall(op) 00039 self.addrs = [int(x[0], 16) for x in self.matches] 00040 00041 def function_addrs(self): 00042 return self.addrs 00043 00044 def function_name_for_addr(self, addr): 00045 i = bisect.bisect_right(self.addrs, addr) 00046 funcname = self.matches[i-1][2] 00047 return funcname 00048 00049 def print_HFSR_info(hfsr): 00050 if int(hfsr, 16) & 0x80000000: 00051 print("\t\tDebug Event Occurred") 00052 if int(hfsr, 16) & 0x40000000: 00053 print("\t\tForced exception, a fault with configurable priority has been escalated to HardFault") 00054 if int(hfsr, 16) & 0x2: 00055 print("\t\tVector table read fault has occurred") 00056 00057 def print_MMFSR_info(mmfsr, mmfar): 00058 if int(mmfsr, 16) & 0x20: 00059 print("\t\tA MemManage fault occurred during FP lazy state preservation") 00060 if int(mmfsr, 16) & 0x10: 00061 print("\t\tA derived MemManage fault occurred on exception entry") 00062 if int(mmfsr, 16) & 0x8: 00063 print("\t\tA derived MemManage fault occurred on exception return") 00064 if int(mmfsr, 16) & 0x2: 00065 if int(mmfsr, 16) & 0x80: 00066 print("\t\tData access violation. Faulting address: %s"%(str(mmfar))) 00067 else: 00068 print("\t\tData access violation. WARNING: Fault address in MMFAR is NOT valid") 00069 if int(mmfsr, 16) & 0x1: 00070 print("\t\tMPU or Execute Never (XN) default memory map access violation on an instruction fetch has occurred") 00071 00072 def print_BFSR_info(bfsr, bfar): 00073 if int(bfsr, 16) & 0x20: 00074 print("\t\tA bus fault occurred during FP lazy state preservation") 00075 if int(bfsr, 16) & 0x10: 00076 print("\t\tA derived bus fault has occurred on exception entry") 00077 if int(bfsr, 16) & 0x8: 00078 print("\t\tA derived bus fault has occurred on exception return") 00079 if int(bfsr, 16) & 0x4: 00080 print("\t\tImprecise data access error has occurred") 00081 if int(bfsr, 16) & 0x2: 00082 if int(bfsr,16) & 0x80: 00083 print("\t\tA precise data access error has occurred. Faulting address: %s"%(str(bfar))) 00084 else: 00085 print("\t\tA precise data access error has occurred. WARNING: Fault address in BFAR is NOT valid") 00086 if int(bfsr, 16) & 0x1: 00087 print("\t\tA bus fault on an instruction prefetch has occurred") 00088 00089 def print_UFSR_info(ufsr): 00090 if int(ufsr, 16) & 0x200: 00091 print("\t\tDivide by zero error has occurred") 00092 if int(ufsr, 16) & 0x100: 00093 print("\t\tUnaligned access error has occurred") 00094 if int(ufsr, 16) & 0x8: 00095 print("\t\tA coprocessor access error has occurred. This shows that the coprocessor is disabled or not present") 00096 if int(ufsr, 16) & 0x4: 00097 print("\t\tAn integrity check error has occurred on EXC_RETURN") 00098 if int(ufsr, 16) & 0x2: 00099 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 )") 00100 if int(ufsr, 16) & 0x1: 00101 print("\t\tThe processor has attempted to execute an undefined instruction") 00102 00103 def print_CPUID_info(cpuid): 00104 if (int(cpuid, 16) & 0xF0000) == 0xC0000: 00105 print("\t\tProcessor Arch: ARM-V6M") 00106 else: 00107 print("\t\tProcessor Arch: ARM-V7M or above") 00108 00109 print("\t\tProcessor Variant: %X" % ((int(cpuid,16) & 0xFFF0 ) >> 4)) 00110 00111 def parse_line_for_register(line): 00112 _, register_val = line.split(":") 00113 return register_val.strip() 00114 00115 def main(crash_log, elfhelper): 00116 mmfar_val = 0 00117 bfar_val = 0 00118 lines = iter(crash_log.readlines()) 00119 00120 for eachline in lines: 00121 if "++ MbedOS Fault Handler ++" in eachline: 00122 break 00123 else: 00124 print("ERROR: Unable to find \"MbedOS Fault Handler\" header") 00125 return 00126 00127 for eachline in lines: 00128 if "-- MbedOS Fault Handler --" in eachline: 00129 break 00130 00131 elif eachline.startswith("PC"): 00132 pc_val = parse_line_for_register(eachline) 00133 if elfhelper: 00134 pc_name = elfhelper.function_name_for_addr(int(pc_val, 16)) 00135 else: 00136 pc_name = "<unknown-symbol>" 00137 00138 elif eachline.startswith("LR"): 00139 lr_val = parse_line_for_register(eachline) 00140 if elfhelper: 00141 lr_name = elfhelper.function_name_for_addr(int(lr_val, 16)) 00142 else: 00143 lr_name = "<unknown-symbol>" 00144 00145 elif eachline.startswith("SP"): 00146 sp_val = parse_line_for_register(eachline) 00147 00148 elif eachline.startswith("HFSR"): 00149 hfsr_val = parse_line_for_register(eachline) 00150 00151 elif eachline.startswith("MMFSR"): 00152 mmfsr_val = parse_line_for_register(eachline) 00153 00154 elif eachline.startswith("BFSR"): 00155 bfsr_val = parse_line_for_register(eachline) 00156 00157 elif eachline.startswith("UFSR"): 00158 ufsr_val = parse_line_for_register(eachline) 00159 00160 elif eachline.startswith("CPUID"): 00161 cpuid_val = parse_line_for_register(eachline) 00162 00163 elif eachline.startswith("MMFAR"): 00164 mmfar_val = parse_line_for_register(eachline) 00165 00166 elif eachline.startswith("BFAR"): 00167 bfar_val = parse_line_for_register(eachline) 00168 00169 print("\nCrash Info:") 00170 print("\tCrash location = %s [0x%s] (based on PC value)" % (pc_name.strip(), str(pc_val))) 00171 print("\tCaller location = %s [0x%s] (based on LR value)" % (lr_name.strip(), str(lr_val))) 00172 print("\tStack Pointer at the time of crash = [%s]" % (str(sp_val))) 00173 00174 print("\tTarget and Fault Info:") 00175 print_CPUID_info(cpuid_val) 00176 print_HFSR_info(hfsr_val) 00177 print_MMFSR_info(mmfsr_val, mmfar_val) 00178 print_BFSR_info(bfsr_val, bfar_val) 00179 print_UFSR_info(ufsr_val) 00180 00181 00182 if __name__ == '__main__': 00183 import argparse 00184 00185 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') 00186 # specify arguments 00187 parser.add_argument(metavar='CRASH LOG', type=argparse.FileType('rb', 0), 00188 dest='crashlog',help='path to crash log file') 00189 parser.add_argument(metavar='ELF FILE', type=argparse.FileType('rb', 0), 00190 nargs='?',const=None,dest='elffile',help='path to elf file') 00191 parser.add_argument(metavar='MAP FILE', type=argparse.FileType('rb', 0), 00192 nargs='?',const=None,dest='mapfile',help='path to map file') 00193 00194 # get and validate arguments 00195 args = parser.parse_args() 00196 00197 # if both the ELF and MAP files are present, the addresses can be converted to symbol names 00198 if args.elffile and args.mapfile: 00199 elfhelper = ElfHelper(args.elffile, args.mapfile) 00200 else: 00201 print("ELF or MAP file missing, logging raw values.") 00202 elfhelper = None 00203 00204 # parse input and write to output 00205 main(args.crashlog, elfhelper) 00206 00207 #close all files 00208 if args.elffile: 00209 args.elffile.close() 00210 if args.mapfile: 00211 args.mapfile.close() 00212 args.crashlog.close() 00213
Generated on Tue Jul 12 2022 12:43:43 by
 1.7.2
 1.7.2