1#!/usr/bin/env python 2# coding:utf-8 3# Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import sys,string,re,os 17from ctypes import * 18from parse_basic import * 19from auto_class import * 20from config import * 21 22OS_TASK_STATUS_UNUSED = 0x0001 23OS_TASK_STATUS_SUSPEND = 0x0002 24OS_TASK_STATUS_READY = 0x0004 25OS_TASK_STATUS_PEND = 0x0008 26OS_TASK_STATUS_RUNNING = 0x0010 27OS_TASK_STATUS_DELAY = 0x0020 28OS_TASK_STATUS_TIMEOUT = 0x0040 29OS_TASK_STATUS_PEND_TIME = 0x0080 30OS_TASK_FLAG_DETACHED = 0x0001 31OS_TASK_FLAG_SYSTEM = 0x0002 32OS_SWTMR_STATUS_UNUSED = 0 33OS_SWTMR_STATUS_DELETING =1 34OS_SWTMR_STATUS_CREATED=2 35OS_SWTMR_STATUS_TICKING=3 36#ctypes.addressof(parameter) - ctypes.addressof(parent_structure) 37 38 39def _los_List_get_all_node(list_addr): 40 node_list=[] 41 node=parse_memory_2_class(list_addr,LOS_DL_LIST,sizeof(LOS_DL_LIST)) 42 if node: 43 while node.pstNext!=list_addr: 44 node_list.append(node.pstNext) 45 node = parse_memory_2_class(node.pstNext,LOS_DL_LIST,sizeof(LOS_DL_LIST)) 46 return (DEFINE_SUCCESS,node_list) 47 48def _addr_in_2_function_name(addr): 49 name=parse_addr_in_2_function_name(addr) 50 if name==None: 51 return hex(addr) 52 else: 53 return name 54 55class _PhaseLiteosCtrl: 56 def __init__(self): 57 self.core=None 58 self.info_fd = sys.__stdout__ 59 self.task_cnt=None 60 self.tcb_array = [] 61 self.ext_task_list=[] 62 63 self.heap_start = None 64 self.heap_end = None 65 self.heap_head = None 66 self.queue_cnt = LOSCFG_BASE_IPC_QUEUE_LIMIT 67 self.queue_array=[] 68 self.queue_ext_info=[] 69 self.timer_cnt = LOSCFG_BASE_CORE_SWTMR_LIMIT 70 self.timer_array=[] 71 self.timer_ext_info=[] 72 self.sem_cnt=LOSCFG_BASE_IPC_SEM_LIMIT 73 self.sem_array=[] 74 self.sem_ext_info=[] 75 76 self.excInfo=None 77 78 self.isr_ext_info=None 79 self.version=None 80 81 class _ExtPercpu: 82 def __init__(self): 83 self.handle_addr = None 84 self.per_cpu=None 85 self.g_tickCount=None 86 self.g_sysClock=None 87 self.g_tickPerSecond=None 88 self.g_cycle2NsScale=None 89 self.task_wait_addr=[] 90 self.timer_wait_addr=[] 91 self.g_intCount=None 92 93 class _ExtTaskInfo: 94 def __init__(self): 95 self.handle_addr=None 96 self.pend_addr=None 97 self.name='unknown' 98 self.buttom=0 99 self.peek_used=0 100 self.over=0 101 self.status_str=None 102 self.enter_name = 'unknown' 103 self.task_context = None 104 self.take_sem = None 105 106 class _ExtTimerInfo: 107 def __init__(self): 108 self.handle_addr=None 109 self.func_name=None 110 111 class _ExtSemInfo: 112 def __init__(self): 113 self.handle_addr=None 114 self.pend_task_list=[] 115 116 class _ExtQueueInfo: 117 def __init__(self): 118 self.handle_addr=None 119 self.pend_read_task_list = [] 120 self.pend_write_task_list =[] 121 122 class ExtIsrInfo: 123 def __init__(self): 124 self.isr_cnt = LOSCFG_PLATFORM_HWI_LIMIT 125 self.g_hwiForm=None 126 127 def make_isr_info(self): 128 self.isr_ext_info = self.ExtIsrInfo() 129 addr = parse_get_symbol_addr('g_hwiForm') 130 if self.version == 207: 131 self.isr_ext_info.g_hwiForm = parse_memory_2_class(addr,HwiHandleInfo*self.isr_ext_info.isr_cnt,sizeof(HwiHandleInfo*self.isr_ext_info.isr_cnt)) 132 elif self.version == 208: 133 self.isr_ext_info.g_hwiForm = parse_memory_2_class(addr,HwiHandleInfo*self.isr_ext_info.isr_cnt,sizeof(HwiHandleInfo*self.isr_ext_info.isr_cnt)) 134 135 def print_isr_info(self): 136 print("\r\n--------------------content of 中断信息:--------------------",file=self.info_fd) 137 if self.version == 207: 138 for hwi in self.isr_ext_info.g_hwiForm: 139 if hwi.hook!=0 or hwi.respCount!=0: 140 print("%s[0x%x][call_cnt=%d]"%(_addr_in_2_function_name(hwi.hook),hwi.hook,hwi.respCount),file=self.info_fd) 141 elif self.version == 208: 142 for hwi in self.isr_ext_info.g_hwiForm: 143 if hwi.hook!=0 or hwi.respCount!=0: 144 print("%s[0x%x][call_cnt=%d]"%(_addr_in_2_function_name(hwi.hook),hwi.hook,hwi.respCount),file=self.info_fd) 145 146 def make_per_cpu_info(self): 147 self.core=self._ExtPercpu() 148 self.core.handle_addr = parse_get_symbol_addr('g_percpu') 149 self.core.per_cpu = parse_memory_2_class(self.core.handle_addr,Percpu,sizeof(Percpu)) 150 151 addr = parse_get_symbol_addr('g_tickCount') 152 if addr: 153 obj=parse_memory_2_class(addr,c_ulonglong,sizeof(c_ulonglong)) 154 self.core.g_tickCount=obj.value 155 156 addr = parse_get_symbol_addr('g_sysClock') 157 if addr: 158 obj=parse_memory_2_class(addr,c_uint,sizeof(c_uint)) 159 self.core.g_sysClock=obj.value 160 161 addr = parse_get_symbol_addr('g_intCount') 162 if addr: 163 obj=parse_memory_2_class(addr,c_uint,sizeof(c_uint)) 164 self.core.g_intCount=obj.value 165 166 addr = parse_get_symbol_addr('g_tickPerSecond') 167 if addr: 168 obj=parse_memory_2_class(addr,c_uint,sizeof(c_uint)) 169 self.core.g_tickPerSecond=obj.value 170 171 addr = parse_get_symbol_addr('g_cycle2NsScale') 172 if addr: 173 obj=parse_memory_2_class(addr,c_double,sizeof(c_double)) 174 self.core.g_cycle2NsScale=obj.value 175 (ret,self.core.task_wait_addr) = _los_List_get_all_node(self.core.per_cpu.taskSortLink.sortLink) 176 177 (ret,self.core.timer_wait_addr) = _los_List_get_all_node(self.core.per_cpu.swtmrSortLink.sortLink) 178 179 def print_per_cpu_info(self): 180 print("\r\n--------------------content of 调度信息汇总:--------------------",file=self.info_fd) 181 print("说明:taskLockCnt锁任务嵌套次数",file=self.info_fd) 182 if self.core.g_cycle2NsScale: 183 print("g_tickCount=%ull,g_sysClock=%u,g_tickPerSecond=%u,g_cycle2NsScale=%f"%(self.core.g_tickCount,self.core.g_sysClock,self.core.g_tickPerSecond,self.core.g_cycle2NsScale),file=self.info_fd) 184 else: 185 print("g_tickCount=%ull,g_sysClock=%u,g_tickPerSecond=%u"%(self.core.g_tickCount,self.core.g_sysClock,self.core.g_tickPerSecond),file=self.info_fd) 186 187 uapi_print_ctypes_obj('schedule',self.core.per_cpu,self.info_fd) 188 189 delay_tick=0 190 for x in self.core.task_wait_addr: 191 x = x-ctype_member_offset('sortList.sortLinkNode',LosTaskCB) 192 i=0 193 while i< self.task_cnt: 194 tcb=self.tcb_array[i] 195 ext_info=self.ext_task_list[i] 196 if ext_info.handle_addr==x: 197 delay_tick=delay_tick+tcb.sortList.idxRollNum 198 print("任务等待剩余时间:%s[%d][剩余时间 delay=%d tick][idxRollNum=%d]"%(ext_info.name,tcb.taskId,delay_tick,tcb.sortList.idxRollNum),file=self.info_fd) 199 i=i+1 200 201 delay_tick=0 202 for x in self.core.timer_wait_addr: 203 x = x-ctype_member_offset('sortList.sortLinkNode',LosSwtmrCB) 204 i=0 205 while i< self.timer_cnt: 206 timer=self.timer_array[i] 207 ext_info=self.timer_ext_info[i] 208 if ext_info.handle_addr==x: 209 delay_tick=delay_tick+timer.sortList.idxRollNum 210 print("定时器到期剩余时间:%s[%d][剩余时间=%d tick][idxRollNum=%d]"%(ext_info.func_name,timer.timerId,delay_tick,timer.sortList.idxRollNum),file=self.info_fd) 211 i=i+1 212 213 def make_task_info(self): 214 addr = parse_get_symbol_addr('g_taskMaxNum') 215 obj=parse_memory_2_class(addr,c_uint,4) 216 self.task_cnt = obj.value 217 218 addr = parse_get_symbol_addr('g_osTaskCBArray') 219 obj=parse_memory_2_class(addr,c_uint,4) 220 addr=obj.value 221 i=0 222 while i < self.task_cnt: 223 ext_info = self._ExtTaskInfo() 224 obj=parse_memory_2_class(addr,LosTaskCB,sizeof(LosTaskCB)) 225 self.tcb_array.append(obj) 226 self.ext_task_list.append(ext_info) 227 ext_info.handle_addr=addr 228 ext_info.pend_addr = ext_info.handle_addr+ctype_member_offset('pendList',LosTaskCB) 229 addr=addr+sizeof(LosTaskCB) 230 i=i+1 231 self._make_task_extra_info() 232 233 def _task_status_2_string(self,status): 234 str='' 235 if (status&OS_TASK_STATUS_UNUSED): 236 str=str+"unused," 237 if (status&OS_TASK_STATUS_RUNNING): 238 str=str+'runing,' 239 if (status&OS_TASK_STATUS_READY): 240 str=str+'ready,' 241 if (status&OS_TASK_STATUS_SUSPEND): 242 str=str+'suspend,' 243 if (status&OS_TASK_STATUS_PEND): 244 str=str+'pend,' 245 if (status&OS_TASK_STATUS_DELAY): 246 str=str+'delay,' 247 if (status&OS_TASK_STATUS_TIMEOUT): 248 str=str+'timeout,' 249 if (status&OS_TASK_STATUS_PEND_TIME): 250 str=str+'pendtime,' 251 return str 252 253 def _make_task_extra_info(self): 254 i=0 255 while i < self.task_cnt: 256 tcb = self.tcb_array[i] 257 ext_info=self.ext_task_list[i] 258 if tcb.taskStatus & OS_TASK_STATUS_UNUSED: #未使用任务返回 259 i=i+1 260 continue; 261 262 ext_info.buttom = tcb.topOfStack+tcb.stackSize #计算栈buttom 263 ext_info.status_str = self._task_status_2_string(tcb.taskStatus) 264 if tcb.taskSem!=0: 265 ext_info.take_sem = parse_memory_2_class(tcb.taskSem,LosSemCB,sizeof(LosSemCB)) 266 267 #生成taskname 268 addr=tcb.taskName 269 str = parse_memory_2_string(addr,32) 270 if str!=None: 271 ext_info.name=str 272 273 #判断栈是否溢出 274 obj = parse_memory_2_class(tcb.topOfStack,c_uint,sizeof(c_uint)) 275 if obj.value==0xCCCCCCCC: 276 ext_info.over=0 277 else: 278 ext_info.over=1 279 280 #计算栈峰值 281 addr = tcb.topOfStack+4 282 while addr < ext_info.buttom: 283 obj = parse_memory_2_class(addr,c_uint,sizeof(c_uint)) 284 if obj.value != 0xCACACACA: 285 break 286 addr+=4 287 ext_info.peek_used = ext_info.buttom-addr 288 289 enter_name=parse_addr_2_function_name(tcb.taskEntry) 290 if enter_name!=None: 291 ext_info.enter_name = enter_name 292 if self.version == 207: 293 ext_info.task_context=parse_memory_2_class(tcb.stackPointer,TaskContext,sizeof(TaskContext)) 294 elif self.version == 208: 295 ext_info.task_context=parse_memory_2_class(tcb.stackPointer,TaskContext,sizeof(TaskContext)) 296 else: 297 ext_info.task_context=parse_memory_2_class(tcb.stackPointer,td_u32,sizeof(td_u32)) 298 i=i+1 299 300 def print_task_short_info(self): 301 print("\r\n--------------------content of 任务信息摘要:--------------------",file=self.info_fd) 302 print('%4s|%20s|%4s|%10s|%10s|%s|%10s|%10s|%10s|%4s|%15s|'%('id','task_name','pri','stackSize','topOfStack','ButtomOfStack','sp','cur_used','peak_used','ovf','status'),file=self.info_fd) 303 i=0 304 while i < self.task_cnt: 305 tcb = self.tcb_array[i] 306 ext_info = self.ext_task_list[i] 307 if not tcb.taskStatus & OS_TASK_STATUS_UNUSED: 308 print('%4d|%20s|%4d|0x%08x|0x%08x|0x%08x |0x%08x|0x%08x|0x%08x|%4d|%15s|' 309 %(i,ext_info.name,tcb.priority,tcb.stackSize,tcb.topOfStack,ext_info.buttom,tcb.stackPointer,0,ext_info.peek_used,ext_info.over,ext_info.status_str),file=self.info_fd) 310 i=i+1 311 312 def print_task_detail_info(self): 313 print("\r\n--------------------content of 任务详细信息:--------------------",file=self.info_fd) 314 print("说明:tcb任务控制块信息,context:任务上下文的寄存器信息,backtrace 栈回溯",file=self.info_fd) 315 i=0 316 while i < self.task_cnt: 317 print('',file=self.info_fd) 318 tcb = self.tcb_array[i] 319 uapi_print_ctypes_obj('tcb',tcb,self.info_fd) 320 ext_info = self.ext_task_list[i] 321 i=i+1 322 if tcb.taskStatus & OS_TASK_STATUS_UNUSED: 323 continue 324 #打印寄存器信息 325 print("[TASK]%s 寄存器:"%(ext_info.name),file=self.info_fd) 326 uapi_print_ctypes_obj('context',ext_info.task_context,self.info_fd) 327 328 #打印back_trace 329 print("[TASK]%s 栈回溯:"%(ext_info.name),file=self.info_fd) 330 if self.version == 207: 331 sp = tcb.stackPointer+sizeof(TaskContext) 332 elif self.version == 208: 333 sp = tcb.stackPointer+sizeof(TaskContext) 334 else: 335 sp = tcb.stackPointer 336 self.stack_back_trace(sp,tcb.topOfStack + tcb.stackSize) 337 print("[TASK]%s 其它状态:"%(ext_info.name),file=self.info_fd) 338 if ext_info.take_sem: 339 print("[waitting_sem][id=0x%08x]"%(ext_info.take_sem.semId),file=self.info_fd) 340 341 def make_heap_info(self): 342 addr = parse_get_symbol_addr('m_aucSysMem0') 343 obj=parse_memory_2_class(addr,c_uint,4) 344 self.heap_start=obj.value 345 if self.version == 207: 346 self.heap_head=parse_memory_2_class(self.heap_start,LosMemPoolInfo,sizeof(LosMemPoolInfo)) 347 if self.heap_head: 348 self.heap_end = self.heap_start + self.heap_head.size 349 elif self.version == 208: 350 self.heap_head=parse_memory_2_class(self.heap_start,LosMemPoolInfo,sizeof(LosMemPoolInfo)) 351 if self.heap_head: 352 self.heap_end = self.heap_start + self.heap_head.size 353 354 355 def print_heap_info(self): 356 print("--------------------content of 内存堆信息:--------------------",file=self.info_fd) 357 self.print_heap_head_info() 358 self.print_heap_from_head() 359 self.print_heap_from_tail() 360 361 def print_heap_head_info(self): 362 pass 363 364 def print_heap_from_head(self): 365 print("从头遍历内存池:",file=self.info_fd) 366 print("说明:node内存节点地址,usr用户空间地址(申请对齐内存场景不准),size内存大小,used是否占用",file=self.info_fd) 367 if self.heap_head: 368 addr = self.heap_head.head 369 while addr >= self.heap_start and addr <= self.heap_end: 370 node = parse_memory_2_class(addr,LosHeapNode,sizeof(LosHeapNode)) 371 if(node.size==0): 372 break; 373 str="[node=0x%x][usr=0x%x][prev=0x%x][size=0x%x][used=%d]"%(addr,addr+8,node.prev,node.size,node.used) 374 if hasattr(LosHeapNode,'lr'): 375 i=0 376 while i< sizeof(node.lr)/sizeof(c_uint): 377 str="%s[%s][0x%x]"%(str,_addr_in_2_function_name(node.lr[i]),node.lr[i]) 378 i=i+1 379 print(str,file=self.info_fd) 380 addr=addr+sizeof(LosHeapNode)+node.size 381 382 def print_heap_from_tail(self): 383 print("从尾遍历内存池:",file=self.info_fd) 384 print("说明:node内存节点地址,usr用户空间地址(申请对齐内存场景不准),size内存大小,used是否占用",file=self.info_fd) 385 if self.heap_head: 386 addr = self.heap_head.tail 387 while addr >= self.heap_start and addr <= self.heap_end: 388 node = parse_memory_2_class(addr,LosHeapNode,sizeof(LosHeapNode)) 389 str="[node][addr=0x%x][usr=0x%x][prev=0x%x][size=0x%x][used=%d]"%(addr,addr+8,node.prev,node.size,node.used) 390 print(str,file=self.info_fd) 391 if addr==self.heap_head.head: 392 break 393 addr=node.prev 394 395 def make_queue_info(self): 396 addr = parse_get_u32_symbol_val('g_osAllQueue') 397 i=0 398 while i< self.queue_cnt: 399 ext_info=self._ExtQueueInfo() 400 obj=parse_memory_2_class(addr,LosQueueCB,sizeof(LosQueueCB)) 401 ext_info.handle_addr=addr 402 self.queue_array.append(obj) 403 self.queue_ext_info.append(ext_info) 404 addr=addr+sizeof(LosQueueCB) 405 i=i+1 406 self._make_queue_ext_info() 407 408 def _make_queue_ext_info(self): 409 i=0 410 while i< self.queue_cnt: 411 queue=self.queue_array[i] 412 ext_info=self.queue_ext_info[i] 413 if queue and queue.queueState==1: #used 414 if self.version == 207: 415 (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB)) 416 elif self.version == 208: 417 (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB)) 418 else: 419 (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB) + 4) 420 for node_addr in addr_list: 421 ext_info.pend_read_task_list.append(node_addr) 422 if self.version == 207: 423 (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB)+sizeof(LOS_DL_LIST)) 424 elif self.version == 208: 425 (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB)+sizeof(LOS_DL_LIST)) 426 else: 427 (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB) + 4 + sizeof(LOS_DL_LIST)) 428 for node_addr in addr_list: 429 ext_info.pend_write_task_list.append(node_addr) 430 i=i+1 431 432 def print_queue_info(self): 433 print("\r\n--------------------content of 消息队列信息:--------------------",file=self.info_fd) 434 print("说明:queueHandle队列的内存空间,queueLen队列长度,queueSize单个节点大小,queueId队列id,readWriteableCnt[0]当前队列中有几个数据,readWriteableCnt[1]当前队列中有几个剩余空间",file=self.info_fd) 435 print("",file=self.info_fd) 436 i=0 437 while i< self.queue_cnt: 438 queue=self.queue_array[i] 439 ext_info=self.queue_ext_info[i] 440 if queue.queueState==1: 441 uapi_print_ctypes_obj('queue',queue,self.info_fd) 442 list=self.get_pending_task(ext_info.pend_read_task_list) 443 print("等待读该消息队列的任务ID:",list,file=self.info_fd) 444 list=self.get_pending_task(ext_info.pend_write_task_list) 445 print("等待写该消息队列的任务ID:",list,file=self.info_fd) 446 print("",file=self.info_fd) 447 i=i+1 448 449 def _make_timer_ext_info(self): 450 i=0 451 while i< self.timer_cnt: 452 timer=self.timer_array[i] 453 ext_info=self.timer_ext_info[i] 454 if timer.state==OS_SWTMR_STATUS_UNUSED or timer.state==OS_SWTMR_STATUS_DELETING: 455 i=i+1 456 continue 457 ext_info.func_name = parse_addr_2_function_name(timer.handler) 458 i=i+1 459 460 def make_timer_info(self): 461 addr = parse_get_u32_symbol_val('g_osSwtmrCBArray') 462 i=0 463 while i< self.timer_cnt: 464 obj=parse_memory_2_class(addr,LosSwtmrCB,sizeof(LosSwtmrCB)) 465 ext_info=self._ExtTimerInfo() 466 self.timer_ext_info.append(ext_info) 467 self.timer_array.append(obj) 468 ext_info.handle_addr=addr 469 470 addr=addr+sizeof(LosSwtmrCB) 471 i=i+1 472 self._make_timer_ext_info() 473 474 def print_timer_info(self): 475 print("--------------------content of 定时器信息:--------------------",file=self.info_fd) 476 print("说明:timer_id定时器id,handler回调函数的地址(已解析),state(0:未使用 1:删除 2:创建 3:执行中),mode(1:周期 2:单次)",file=self.info_fd) 477 print("\t overrun周期性定时器执行次数,arg用户参数,inProcess到期已添加到待执行队列",file=self.info_fd) 478 print('',file=self.info_fd) 479 i=0 480 while i< self.timer_cnt: 481 timer=self.timer_array[i] 482 ext_info=self.timer_ext_info[i] 483 if timer.state==OS_SWTMR_STATUS_UNUSED or timer.state==OS_SWTMR_STATUS_DELETING: 484 i=i+1 485 continue 486 print("timer_id=%d %s[0x%x]"%(timer.timerId,ext_info.func_name,timer.handler),file=self.info_fd) 487 uapi_print_ctypes_obj('timer',timer,self.info_fd) 488 print('',file=self.info_fd) 489 i=i+1 490 491 def _make_sem_extra_info(self): 492 i=0 493 while i< self.sem_cnt: 494 sem=self.sem_array[i] 495 ext_info=self.sem_ext_info[i] 496 if sem.semStat==1: #used 497 (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('semList',LosSemCB)) 498 for node_addr in addr_list: 499 ext_info.pend_task_list.append(node_addr) 500 i=i+1 501 502 def make_sem_info(self): 503 addr = parse_get_u32_symbol_val('g_osAllSem') 504 i=0 505 while i< self.sem_cnt: 506 ext_info=self._ExtSemInfo() 507 obj=parse_memory_2_class(addr,LosSemCB,sizeof(LosSemCB)) 508 ext_info.handle_addr=addr 509 self.sem_array.append(obj) 510 self.sem_ext_info.append(ext_info) 511 addr=addr+sizeof(LosSemCB) 512 i=i+1 513 self._make_sem_extra_info() 514 515 def get_pending_task(self,addr_list): 516 list=[] 517 for addr in addr_list: 518 i=0 519 while i < self.task_cnt: 520 ext_task = self.ext_task_list[i] 521 tcb = self.tcb_array[i] 522 if addr== ext_task.pend_addr: 523 list.append(tcb.taskId) 524 i=i+1 525 return list 526 527 def print_sem_info(self): 528 print("--------------------content of 信号量:--------------------",file=self.info_fd) 529 print("说明:semType(0:计数信号量 1:互斥信号量),semCount剩余信号量个数",file=self.info_fd) 530 print("",file=self.info_fd) 531 i=0 532 while i< self.sem_cnt: 533 sem=self.sem_array[i] 534 ext_info=self.sem_ext_info[i] 535 if sem.semStat: 536 uapi_print_ctypes_obj('sem',sem,self.info_fd) 537 list=self.get_pending_task(ext_info.pend_task_list) 538 print("等待该信号量的任务ID:",list,file=self.info_fd) 539 print('',file=self.info_fd) 540 i=i+1 541 542 def make_crash_info(self): 543 addr = parse_get_symbol_addr('g_excInfo') 544 self.excInfo = parse_memory_2_class(addr,ExcInfo,sizeof(ExcInfo)) 545 546 def print_crash_info(self): 547 print("--------------------content of 死机信息:--------------------",file=self.info_fd) 548 uapi_print_ctypes_obj('g_excInfo',self.excInfo,self.info_fd) 549 if self.excInfo.context!=0: 550 obj=parse_memory_2_class(self.excInfo.context,ExcContext,sizeof(ExcContext)) 551 uapi_print_ctypes_obj('context',obj,self.info_fd) 552 if self.version == 207: 553 self.stack_back_trace(obj.taskContext.sp+sizeof(TaskContext),obj.taskContext.sp+0x1000) 554 elif self.version == 208: 555 self.stack_back_trace(obj.taskContext.sp+sizeof(TaskContext),obj.taskContext.sp+0x1000) 556 else: 557 self.stack_back_trace(obj.SP, obj.SP + 0x1000) 558 559 560 561 def stack_back_trace(self,start_addr,end_addr): 562 sp=start_addr 563 while sp < end_addr: 564 obj=parse_memory_2_class(sp,c_uint,sizeof(c_uint)) 565 if obj: 566 name = parse_addr_in_2_function_name(obj.value-4) 567 if name: 568 print("[BACK Trace][addr=0x%08x][val=0x%08x]%s"%(sp,obj.value,name),file=self.info_fd) 569 else: 570 pass 571 #print("[BACK Trace][addr=0x%08x][val=0x%08x]"%(sp,obj.value),file=self.info_fd) 572 573 sp=sp+4 574 575_g_parse_liteos_ctrl=_PhaseLiteosCtrl() 576def make_liteos_info(): 577 try: 578 _g_parse_liteos_ctrl.make_per_cpu_info() 579 except: 580 print("[EXCEPTION]make_per_cpu_info fail.") 581 try: 582 _g_parse_liteos_ctrl.make_task_info() 583 except: 584 print("[EXCEPTION]make_task_info fail.") 585 if _g_parse_liteos_ctrl.version != 208: 586 try: 587 _g_parse_liteos_ctrl.make_queue_info() 588 except: 589 print("[EXCEPTION]make_queue_info fail.") 590 try: 591 _g_parse_liteos_ctrl.make_heap_info() 592 except: 593 print("[EXCEPTION]make_heap_info fail.") 594 try: 595 _g_parse_liteos_ctrl.make_timer_info() 596 except: 597 print("[EXCEPTION]make_timer_info fail.") 598 try: 599 _g_parse_liteos_ctrl.make_sem_info() 600 except: 601 print("[EXCEPTION]make_sem_info fail.") 602 try: 603 _g_parse_liteos_ctrl.make_crash_info() 604 except: 605 print("[EXCEPTION]make_crash_info fail.") 606 try: 607 _g_parse_liteos_ctrl.make_isr_info() 608 except: 609 print("[EXCEPTION]make_isr_info fail.") 610 611def print_liteos_info(): 612 try: 613 _g_parse_liteos_ctrl.print_isr_info() 614 except: 615 print("[EXCEPTION]print_isr_info fail.") 616 try: 617 _g_parse_liteos_ctrl.print_per_cpu_info() 618 except: 619 print("[EXCEPTION]print_per_cpu_info fail.") 620 if _g_parse_liteos_ctrl.version != 208: 621 try: 622 _g_parse_liteos_ctrl.print_queue_info() 623 except: 624 print("[EXCEPTION]print_queue_info fail.") 625 try: 626 _g_parse_liteos_ctrl.print_timer_info() 627 except: 628 print("[EXCEPTION]print_timer_info fail.") 629 try: 630 _g_parse_liteos_ctrl.print_heap_info() 631 except: 632 print("[EXCEPTION]print_heap_info fail.") 633 try: 634 _g_parse_liteos_ctrl.print_sem_info() 635 except: 636 print("[EXCEPTION]print_sem_info fail.") 637 try: 638 _g_parse_liteos_ctrl.print_task_short_info() 639 except: 640 print("[EXCEPTION]print_task_short_info fail.") 641 try: 642 _g_parse_liteos_ctrl.print_task_detail_info() 643 except: 644 print("[EXCEPTION]print_task_detail_info fail.") 645 try: 646 _g_parse_liteos_ctrl.print_crash_info() 647 except: 648 print("[EXCEPTION]print_crash_info fail.") 649 650def parse_liteos206_info(log_fp): 651 _g_parse_liteos_ctrl.info_fd = log_fp 652 _g_parse_liteos_ctrl.version = 206 653 make_liteos_info() 654 print_liteos_info() 655 656def parse_liteos207_info(log_fp): 657 _g_parse_liteos_ctrl.info_fd = log_fp 658 _g_parse_liteos_ctrl.version = 207 659 make_liteos_info() 660 print_liteos_info() 661 662def parse_liteos208_info(log_fp): 663 _g_parse_liteos_ctrl.info_fd = log_fp 664 _g_parse_liteos_ctrl.version = 208 665 make_liteos_info() 666 print_liteos_info() 667 668''' 669context.mstatus(mcause)=0x80207800 670context.mepc=0x12530 671context.tp=0xcacacaca 672context.sp=0xcacacaca 673context.s11=0x4040404--未压栈(中断场景) 674context.s10=0x5050505--未压栈 675context.s9=0x6060606--未压栈 676context.s8=0x7070707--未压栈 677context.s7=0x8080808--未压栈 678context.s6=0x9090909--未压栈 679context.s5=0x80206088--未压栈 680context.s4=0x20008000--未压栈 681context.s3=0x80206080--未压栈 682context.s2=0x200079dc--未压栈 683context.s1=0x0--未压栈 684context.s0=0x20007a74--未压栈 685 686context.t6=0x4040404 687context.t5=0x5050505 688context.t4=0x6060606 689context.t3=0x7070707 690context.a7=0x8080808 691context.a6=0x9090909 692context.a5=0xa0a0a0a 693context.a4=0xb0b0b0b 694context.a3=0xc0c0c0c 695context.a2=0xd0d0d0d 696context.a1=0xe0e0e0e 697context.a0=0xf0f0f0f 698context.t2=0x10101010 699context.t1=0x11111111 700context.t0=0x12121212 701context.ra=0x13131313 702 703context.fs11=0x20202020--(进中断)未压栈 704context.fs10=0x21212121--未压栈 705context.fs9=0x22222222--未压栈 706context.fs8=0x23232323--未压栈 707context.fs7=0x24242424--未压栈 708context.fs6=0x25252525--未压栈 709context.fs5=0x26262626--未压栈 710context.fs4=0x27272727--未压栈 711context.fs3=0x28282828--未压栈 712context.fs2=0x29292929--未压栈 713context.fs1=0x2a2a2a2a--未压栈 714context.fs0=0x2b2b2b2b--未压栈 715 716context.ft11=0x20202020 717context.ft10=0x21212121 718context.ft9=0x22222222 719context.ft8=0x23232323 720context.fa7=0x24242424 721context.fa6=0x25252525 722context.fa5=0x26262626 723context.fa4=0x27272727 724context.fa3=0x28282828 725context.fa2=0x80206088 726context.fa1=0x20008000 727context.fa0=0x80206080 728context.ft7=0x20009000 729context.ft6=0x20007ad4 730context.ft5=0x20007ad4 731context.ft4=0x11f5a 732context.ft3=0x32 733context.ft2=0x20007ad4 734context.ft1=0x20007a70 735context.ft0=0x117a2 736context.fcsr=0x0 737context.reserved[0]=0x0 738context.reserved[1]=0x20007a74 739context.reserved[2]=0x12530 740 741 742typedef struct { 743 uint32_t ccause; 744 uint32_t mcause; 745 uint32_t mtval; 746 uint32_t gp; 747 TaskContext taskContext; 748} ExcContext; 749 750typedef struct { 751 uint16_t phase; /**< Exception occurrence phase: 0 indicates that the exception occurs during 752 * initialization, 1 indicates that the exception occurs during task, 2 753 * indicates that the exception occurs during interrupt, and 3 indicates that 754 * the exception occurs during exception. 755 */ 756 uint16_t type; /**< Type of exception, refer to no. 1-19 listed above for exceptions */ 757 uint32_t faultAddr; /**< A precise address access error indicates the error access address where 758 * the exception occurred. 759 */ 760 uint32_t thrdPid; /**< An exception occurs in the interrupt, indicating the interrupt number. An 761 * exception occurs in the task, indicating the task id, or 0xffffffff if it 762 * occurs during initialization 763 */ 764 uint16_t nestCnt; /**< The number of nested exceptions, currently only support the first time the 765 * exception into the implementation of the registered hook function 766 */ 767 uint16_t reserved; /**< Reserved */ 768 ExcContext *context; /**< The hardware context at which an exception to an automatic stack floating point 769 * register occurs 770 */ 771} ExcInfo; 772''' 773