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 pc_name = elfhelper.function_name_for_addr(int(pc_val, 16)) 00134 00135 elif eachline.startswith("LR"): 00136 lr_val = parse_line_for_register(eachline) 00137 lr_name = elfhelper.function_name_for_addr(int(lr_val, 16)) 00138 00139 elif eachline.startswith("SP"): 00140 sp_val = parse_line_for_register(eachline) 00141 00142 elif eachline.startswith("HFSR"): 00143 hfsr_val = parse_line_for_register(eachline) 00144 00145 elif eachline.startswith("MMFSR"): 00146 mmfsr_val = parse_line_for_register(eachline) 00147 00148 elif eachline.startswith("BFSR"): 00149 bfsr_val = parse_line_for_register(eachline) 00150 00151 elif eachline.startswith("UFSR"): 00152 ufsr_val = parse_line_for_register(eachline) 00153 00154 elif eachline.startswith("CPUID"): 00155 cpuid_val = parse_line_for_register(eachline) 00156 00157 elif eachline.startswith("MMFAR"): 00158 mmfar_val = parse_line_for_register(eachline) 00159 00160 elif eachline.startswith("BFAR"): 00161 bfar_val = parse_line_for_register(eachline) 00162 00163 print("\nCrash Info:") 00164 print("\tCrash location = %s [0x%s] (based on PC value)" % (pc_name.strip(), str(pc_val))) 00165 print("\tCaller location = %s [0x%s] (based on LR value)" % (lr_name.strip(), str(lr_val))) 00166 print("\tStack Pointer at the time of crash = [%s]" % (str(sp_val))) 00167 00168 print("\tTarget and Fault Info:") 00169 print_CPUID_info(cpuid_val) 00170 print_HFSR_info(hfsr_val) 00171 print_MMFSR_info(mmfsr_val, mmfar_val) 00172 print_BFSR_info(bfsr_val, bfar_val) 00173 print_UFSR_info(ufsr_val) 00174 00175 00176 if __name__ == '__main__': 00177 import argparse 00178 00179 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') 00180 # specify arguments 00181 parser.add_argument(metavar='CRASH LOG', type=argparse.FileType('rb', 0), 00182 dest='crashlog',help='path to crash log file') 00183 parser.add_argument(metavar='ELF FILE', type=argparse.FileType('rb', 0), 00184 dest='elffile',help='path to elf file') 00185 parser.add_argument(metavar='MAP FILE', type=argparse.FileType('rb', 0), 00186 dest='mapfile',help='path to map file') 00187 00188 # get and validate arguments 00189 args = parser.parse_args() 00190 00191 elfhelper = ElfHelper(args.elffile, args.mapfile) 00192 00193 # parse input and write to output 00194 main(args.crashlog, elfhelper) 00195 00196 #close all files 00197 args.elffile.close() 00198 args.mapfile.close() 00199 args.crashlog.close() 00200
Generated on Tue Jul 12 2022 14:23:32 by
