1 2# Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# Licensed under the Apache License, Version 2.0 (the "License"); 15# you may not use this file except in compliance with the License. 16# You may obtain a copy of the License at 17# 18# http://www.apache.org/licenses/LICENSE-2.0 19# 20# Unless required by applicable law or agreed to in writing, software 21# distributed under the License is distributed on an "AS IS" BASIS, 22# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23# See the License for the specific language governing permissions and 24# limitations under the License. 25import struct 26import sys 27import os 28 29path = sys.argv[1:] 30 31bin_path = "./crashinfo.bin" 32format_path = "./crashinfo.txt" 33if len(path) >= 1: 34 for i in path: 35 if i.endswith("bin") and os.path.isfile(i): 36 bin_path = i 37 elif i.endswith("txt"): 38 format_path = i 39 else: 40 print("invalid parameter: ", i) 41txt_path = "./crashinfo_bin.txt" 42ret = [] 43 44def exc_info_get_phase(phase): 45 str = { 46 0 : "Init", 47 1 : "Task", 48 2 : "Irq", 49 3 : "Exc" 50 } 51 return str.get(phase, None) 52 53def task_info_get_status(status): 54 if status & 0x10 == 0x10: 55 return "Running" 56 elif status & 0x4 == 0x4: 57 return "Ready" 58 elif status & 0x20 == 0x20: 59 return "Delay" 60 elif status & 0x82 == 0x82: 61 return "SuspendTime" 62 elif status & 0x88 == 0x88: 63 return "PendTime" 64 elif status & 0x8 == 0x8: 65 return "Pend" 66 elif status & 0x2 == 0x2: 67 return "Suspend" 68 elif status & 0x100 == 0x100: 69 return "Zombie" 70 else: 71 return "Invalid" 72 73if __name__ == "__main__": 74 with open(bin_path, 'rb') as file: 75 data = file.read() 76 for byte in data: 77 ret.append(f"{byte:02x}") 78 79 with open(txt_path,'w') as file: 80 line_index = 0 81 for byte in ret: 82 file.write(byte) 83 line_index += 1 84 if line_index >= 16 : 85 file.write('\n') 86 line_index = 0 87 else: 88 file.write(' ') 89 90 file = open(bin_path, "rb") 91 with open(format_path,'w') as write_file: 92 flag = struct.unpack('<I', file.read(4))[0] 93 write_file.write(f"{hex(flag)}" + '\n') 94 group_cnt = struct.unpack('<I', file.read(4))[0] 95 96 # GROUP SIZE INFO 97 group_size = [] 98 for i in range(group_cnt): 99 group_single_size = struct.unpack('<I', file.read(4))[0] 100 group_size.append(group_single_size) 101 file.seek(4,1) 102 # TASK NAME 103 write_file.write('task_name:') 104 for i in range(group_size[0] - 1): 105 char = struct.unpack('<c', file.read(1))[0] 106 write_file.write(str(char)[2]) 107 write_file.write('\n') 108 file.seek(1,1) 109 # EXC INFO 110 write_file.write('==== EXC INFO ====\n') 111 exc_info_phase = struct.unpack('<H', file.read(2))[0] 112 write_file.write('phase:' + exc_info_get_phase(exc_info_phase) + '\n') 113 exc_info_type = struct.unpack('<H', file.read(2))[0] 114 write_file.write('type:' + f"{hex(exc_info_type)}" + '\n') 115 exc_info_faultAddr = struct.unpack('I', file.read(4))[0] 116 write_file.write('faultAddr:' + f"{hex(exc_info_faultAddr)}" + '\n') 117 exc_info_thrdPid = struct.unpack('<I', file.read(4)[0:4])[0] 118 write_file.write('thrdPid:' + f"{hex(exc_info_thrdPid)}" + '\n') 119 exc_info_nestCnt = struct.unpack('<H', file.read(2))[0] 120 write_file.write('nestCnt:' + f"{hex(exc_info_nestCnt)}" + '\n') 121 exc_info_reserved = struct.unpack('<H', file.read(2))[0] 122 write_file.write('reserved:' + f"{hex(exc_info_reserved)}" + '\n') 123 exc_info_context = struct.unpack('<I', file.read(4))[0] 124 write_file.write('context:' + f"{hex(exc_info_context)}" + '\n') 125 126 # EXC CONTEXT 127 write_file.write('==== EXC CONTEXT INFO ====\n') 128 exc_context_ccause = struct.unpack('<I', file.read(4))[0] 129 write_file.write('ccause:' + f"{hex(exc_context_ccause)}" + '\n') 130 exc_context_mcause = struct.unpack('<I', file.read(4))[0] 131 write_file.write('mcause:' + f"{hex(exc_context_mcause)}" + '\n') 132 exc_context_mtval = struct.unpack('<I', file.read(4))[0] 133 write_file.write('mtval:' + f"{hex(exc_context_mtval)}" + '\n') 134 exc_context_gp = struct.unpack('<I', file.read(4))[0] 135 write_file.write('gp:' + f"{hex(exc_context_gp)}" + '\n') 136 # EXC TASK CONTEXT 137 exc_task_context_mstatus = struct.unpack('<I', file.read(4))[0] 138 exc_task_context_mepc = struct.unpack('<I', file.read(4))[0] 139 exc_task_context_tp = struct.unpack('<I', file.read(4))[0] 140 exc_task_context_sp = struct.unpack('<I', file.read(4))[0] 141 exc_task_context_s11 = struct.unpack('<I', file.read(4))[0] 142 exc_task_context_s10 = struct.unpack('<I', file.read(4))[0] 143 exc_task_context_s9 = struct.unpack('<I', file.read(4))[0] 144 exc_task_context_s8 = struct.unpack('<I', file.read(4))[0] 145 exc_task_context_s7 = struct.unpack('<I', file.read(4))[0] 146 exc_task_context_s6 = struct.unpack('<I', file.read(4))[0] 147 exc_task_context_s5 = struct.unpack('<I', file.read(4))[0] 148 exc_task_context_s4 = struct.unpack('<I', file.read(4))[0] 149 exc_task_context_s3 = struct.unpack('<I', file.read(4))[0] 150 exc_task_context_s2 = struct.unpack('<I', file.read(4))[0] 151 exc_task_context_s1 = struct.unpack('<I', file.read(4))[0] 152 exc_task_context_s0 = struct.unpack('<I', file.read(4))[0] 153 exc_task_context_t6 = struct.unpack('<I', file.read(4))[0] 154 exc_task_context_t5 = struct.unpack('<I', file.read(4))[0] 155 exc_task_context_t4 = struct.unpack('<I', file.read(4))[0] 156 exc_task_context_t3 = struct.unpack('<I', file.read(4))[0] 157 exc_task_context_a7 = struct.unpack('<I', file.read(4))[0] 158 exc_task_context_a6 = struct.unpack('<I', file.read(4))[0] 159 exc_task_context_a5 = struct.unpack('<I', file.read(4))[0] 160 exc_task_context_a4 = struct.unpack('<I', file.read(4))[0] 161 exc_task_context_a3 = struct.unpack('<I', file.read(4))[0] 162 exc_task_context_a2 = struct.unpack('<I', file.read(4))[0] 163 exc_task_context_a1 = struct.unpack('<I', file.read(4))[0] 164 exc_task_context_a0 = struct.unpack('<I', file.read(4))[0] 165 exc_task_context_t2 = struct.unpack('<I', file.read(4))[0] 166 exc_task_context_t1 = struct.unpack('<I', file.read(4))[0] 167 exc_task_context_t0 = struct.unpack('<I', file.read(4))[0] 168 exc_task_context_ra = struct.unpack('<I', file.read(4))[0] 169 write_file.write('mstatus:' + f"{hex(exc_task_context_mstatus)}" + '\n') 170 write_file.write('mepc:' + f"{hex(exc_task_context_mepc)}" + '\n') 171 write_file.write('ra:' + f"{hex(exc_task_context_ra)}" + '\n') 172 write_file.write('sp:' + f"{hex(exc_task_context_sp)}" + '\n') 173 write_file.write('tp:' + f"{hex(exc_task_context_tp)}" + '\n') 174 write_file.write('t0:' + f"{hex(exc_task_context_t0)}" + '\n') 175 write_file.write('t1:' + f"{hex(exc_task_context_t1)}" + '\n') 176 write_file.write('t2:' + f"{hex(exc_task_context_t2)}" + '\n') 177 write_file.write('s0:' + f"{hex(exc_task_context_s0)}" + '\n') 178 write_file.write('s1:' + f"{hex(exc_task_context_s1)}" + '\n') 179 write_file.write('a0:' + f"{hex(exc_task_context_a0)}" + '\n') 180 write_file.write('a1:' + f"{hex(exc_task_context_a1)}" + '\n') 181 write_file.write('a2:' + f"{hex(exc_task_context_a2)}" + '\n') 182 write_file.write('a3:' + f"{hex(exc_task_context_a3)}" + '\n') 183 write_file.write('a4:' + f"{hex(exc_task_context_a4)}" + '\n') 184 write_file.write('a5:' + f"{hex(exc_task_context_a5)}" + '\n') 185 write_file.write('a6:' + f"{hex(exc_task_context_a6)}" + '\n') 186 write_file.write('a7:' + f"{hex(exc_task_context_a7)}" + '\n') 187 write_file.write('s2:' + f"{hex(exc_task_context_s2)}" + '\n') 188 write_file.write('s3:' + f"{hex(exc_task_context_s3)}" + '\n') 189 write_file.write('s4:' + f"{hex(exc_task_context_s4)}" + '\n') 190 write_file.write('s5:' + f"{hex(exc_task_context_s5)}" + '\n') 191 write_file.write('s6:' + f"{hex(exc_task_context_s6)}" + '\n') 192 write_file.write('s7:' + f"{hex(exc_task_context_s7)}" + '\n') 193 write_file.write('s8:' + f"{hex(exc_task_context_s8)}" + '\n') 194 write_file.write('s9:' + f"{hex(exc_task_context_s9)}" + '\n') 195 write_file.write('s10:' + f"{hex(exc_task_context_s10)}" + '\n') 196 write_file.write('s11:' + f"{hex(exc_task_context_s11)}" + '\n') 197 write_file.write('t3:' + f"{hex(exc_task_context_t3)}" + '\n') 198 write_file.write('t4:' + f"{hex(exc_task_context_t4)}" + '\n') 199 write_file.write('t5:' + f"{hex(exc_task_context_t5)}" + '\n') 200 write_file.write('t6:' + f"{hex(exc_task_context_t6)}" + '\n') 201 202 # BACKTRACE INFO 203 write_file.write('==== BACKTRACE INFO ====\n') 204 backtrace_count = struct.unpack('<I', file.read(4))[0] 205 write_file.write('backtrace count:' + f"{str(backtrace_count)}" + '\n') 206 for i in range(backtrace_count): 207 backtrace_sp = struct.unpack('<I', file.read(4))[0] 208 backtrace_sp_content = struct.unpack('<I', file.read(4))[0] 209 write_file.write('sp addr : ' + f"{hex(backtrace_sp)}" + ' , sp content : ' + f"{hex(backtrace_sp_content)}" + '\n') 210 move_size = 80 - backtrace_count * 8 211 file.seek(move_size,1) 212 task_num = struct.unpack('<I', file.read(4))[0] 213 # TASK INFO 214 write_file.write('==== TASK INFO ====\n') 215 write_file.write('Name TaskEntryAddr TID Priority Status StackSize ' + 216 'WaterLine StackPoint TopOfStack SemID EventMask\n') 217 write_file.write('---- ------------- --- -------- ------ --------- ' + 218 '--------- ---------- ---------- ----- ---------\n') 219 ## WATERLINE INFO 220 waterline_group = [] 221 for i in range(group_size[4] // 4): 222 waterline = struct.unpack('<I', file.read(4))[0] 223 waterline_group.append(waterline) 224 ## TASK INFO 225 task_info_size = group_size[7] if group_size[7] > 0 else 96 226 task_info_cnt = struct.unpack('<I', file.read(4))[0] 227 task_info_total_size = group_size[6] // task_info_size 228 ## TASK NAME INFO 229 task_semId_arr = [] 230 task_name_arr = [] 231 for i in range(task_info_cnt): 232 task_semId = struct.unpack('<I', file.read(4))[0] 233 task_semId_arr.append(task_semId) 234 task_name_len = struct.unpack('<I', file.read(4))[0] 235 task_name = [] 236 for i in range(task_name_len): 237 char = struct.unpack('<c', file.read(1))[0] 238 task_name.append(str(char)[2]) 239 struct.unpack('<c', file.read(1))[0] 240 task_name_arr.append(task_name) 241 242 task_info_addr = file.tell() 243 task_info_index = 0 244 for i in range(task_num): 245 if task_info_index >= len(task_name_arr): 246 break 247 file.seek(task_info_addr + i * task_info_size, 0) 248 task_info_stackPointer = struct.unpack('<I', file.read(4))[0] 249 task_info_taskStatus = struct.unpack('<H', file.read(2))[0] 250 if task_info_get_status(task_info_taskStatus) == "Invalid" : 251 continue 252 task_info_priority = struct.unpack('<H', file.read(2))[0] 253 task_info_flag = struct.unpack('<I', file.read(4))[0] 254 task_info_stackSize = struct.unpack('<I', file.read(4))[0] 255 task_info_topOfStack = struct.unpack('<I', file.read(4))[0] 256 task_info_taskId = struct.unpack('<I', file.read(4))[0] 257 task_info_taskEntry = struct.unpack('<I', file.read(4))[0] 258 task_info_taskSemCb = struct.unpack('<I', file.read(4))[0] 259 task_info_param1 = struct.unpack('<I', file.read(4))[0] 260 task_info_param2 = struct.unpack('<I', file.read(4))[0] 261 task_info_param3 = struct.unpack('<I', file.read(4))[0] 262 task_info_param4 = struct.unpack('<I', file.read(4))[0] 263 task_info_param5 = struct.unpack('<I', file.read(4))[0] 264 task_info_param6 = struct.unpack('<I', file.read(4))[0] 265 task_info_param7 = struct.unpack('<I', file.read(4))[0] 266 task_info_param8 = struct.unpack('<I', file.read(4))[0] 267 task_info_param9 = struct.unpack('<I', file.read(4))[0] 268 task_info_param10 = struct.unpack('<I', file.read(4))[0] 269 task_info_param11 = struct.unpack('<I', file.read(4))[0] 270 task_info_eventmask = struct.unpack('<I', file.read(4))[0] 271 272 write_file.write(''.join(task_name_arr[task_info_index]).ljust(18)) 273 write_file.write(f"{hex(task_info_taskEntry)}".ljust(20)) 274 write_file.write(f"{hex(task_info_taskId)}".ljust(7)) 275 write_file.write(f"{str(task_info_priority)}".ljust(11)) 276 write_file.write(task_info_get_status(task_info_taskStatus).ljust(13)) 277 write_file.write(f"{hex(task_info_stackSize)}".ljust(13)) 278 write_file.write(f"{hex(waterline_group[i])}".ljust(15)) 279 write_file.write(f"{hex(task_info_stackPointer)}".ljust(13)) 280 write_file.write(f"{hex(task_info_topOfStack)}".ljust(13)) 281 282 write_file.write(f"{hex(task_semId_arr[task_info_index])}".ljust(13)) 283 write_file.write(f'{hex(task_info_eventmask)}' + '\n') 284 task_info_index += 1 285 line_index = 0 286 print('crash info resolve done')