762 lines
30 KiB
Python
762 lines
30 KiB
Python
|
#!/usr/bin/env python
|
||
|
# coding:utf-8
|
||
|
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved.
|
||
|
|
||
|
import sys,string,re,os
|
||
|
from ctypes import *
|
||
|
from parse_basic import *
|
||
|
from auto_class import *
|
||
|
from config import *
|
||
|
|
||
|
OS_TASK_STATUS_UNUSED = 0x0001
|
||
|
OS_TASK_STATUS_SUSPEND = 0x0002
|
||
|
OS_TASK_STATUS_READY = 0x0004
|
||
|
OS_TASK_STATUS_PEND = 0x0008
|
||
|
OS_TASK_STATUS_RUNNING = 0x0010
|
||
|
OS_TASK_STATUS_DELAY = 0x0020
|
||
|
OS_TASK_STATUS_TIMEOUT = 0x0040
|
||
|
OS_TASK_STATUS_PEND_TIME = 0x0080
|
||
|
OS_TASK_FLAG_DETACHED = 0x0001
|
||
|
OS_TASK_FLAG_SYSTEM = 0x0002
|
||
|
OS_SWTMR_STATUS_UNUSED = 0
|
||
|
OS_SWTMR_STATUS_DELETING =1
|
||
|
OS_SWTMR_STATUS_CREATED=2
|
||
|
OS_SWTMR_STATUS_TICKING=3
|
||
|
#ctypes.addressof(parameter) - ctypes.addressof(parent_structure)
|
||
|
|
||
|
|
||
|
def _los_List_get_all_node(list_addr):
|
||
|
node_list=[]
|
||
|
node=parse_memory_2_class(list_addr,LOS_DL_LIST,sizeof(LOS_DL_LIST))
|
||
|
if node:
|
||
|
while node.pstNext!=list_addr:
|
||
|
node_list.append(node.pstNext)
|
||
|
node = parse_memory_2_class(node.pstNext,LOS_DL_LIST,sizeof(LOS_DL_LIST))
|
||
|
return (DEFINE_SUCCESS,node_list)
|
||
|
|
||
|
def _addr_in_2_function_name(addr):
|
||
|
name=parse_addr_in_2_function_name(addr)
|
||
|
if name==None:
|
||
|
return hex(addr)
|
||
|
else:
|
||
|
return name
|
||
|
|
||
|
class _PhaseLiteosCtrl:
|
||
|
def __init__(self):
|
||
|
self.core=None
|
||
|
self.info_fd = sys.__stdout__
|
||
|
self.task_cnt=None
|
||
|
self.tcb_array = []
|
||
|
self.ext_task_list=[]
|
||
|
|
||
|
self.heap_start = None
|
||
|
self.heap_end = None
|
||
|
self.heap_head = None
|
||
|
self.queue_cnt = LOSCFG_BASE_IPC_QUEUE_LIMIT
|
||
|
self.queue_array=[]
|
||
|
self.queue_ext_info=[]
|
||
|
self.timer_cnt = LOSCFG_BASE_CORE_SWTMR_LIMIT
|
||
|
self.timer_array=[]
|
||
|
self.timer_ext_info=[]
|
||
|
self.sem_cnt=LOSCFG_BASE_IPC_SEM_LIMIT
|
||
|
self.sem_array=[]
|
||
|
self.sem_ext_info=[]
|
||
|
|
||
|
self.excInfo=None
|
||
|
|
||
|
self.isr_ext_info=None
|
||
|
self.version=None
|
||
|
|
||
|
class _ExtPercpu:
|
||
|
def __init__(self):
|
||
|
self.handle_addr = None
|
||
|
self.per_cpu=None
|
||
|
self.g_tickCount=None
|
||
|
self.g_sysClock=None
|
||
|
self.g_tickPerSecond=None
|
||
|
self.g_cycle2NsScale=None
|
||
|
self.task_wait_addr=[]
|
||
|
self.timer_wait_addr=[]
|
||
|
self.g_intCount=None
|
||
|
|
||
|
class _ExtTaskInfo:
|
||
|
def __init__(self):
|
||
|
self.handle_addr=None
|
||
|
self.pend_addr=None
|
||
|
self.name='unknown'
|
||
|
self.buttom=0
|
||
|
self.peek_used=0
|
||
|
self.over=0
|
||
|
self.status_str=None
|
||
|
self.enter_name = 'unknown'
|
||
|
self.task_context = None
|
||
|
self.take_sem = None
|
||
|
|
||
|
class _ExtTimerInfo:
|
||
|
def __init__(self):
|
||
|
self.handle_addr=None
|
||
|
self.func_name=None
|
||
|
|
||
|
class _ExtSemInfo:
|
||
|
def __init__(self):
|
||
|
self.handle_addr=None
|
||
|
self.pend_task_list=[]
|
||
|
|
||
|
class _ExtQueueInfo:
|
||
|
def __init__(self):
|
||
|
self.handle_addr=None
|
||
|
self.pend_read_task_list = []
|
||
|
self.pend_write_task_list =[]
|
||
|
|
||
|
class ExtIsrInfo:
|
||
|
def __init__(self):
|
||
|
self.isr_cnt = LOSCFG_PLATFORM_HWI_LIMIT
|
||
|
self.g_hwiForm=None
|
||
|
|
||
|
def make_isr_info(self):
|
||
|
self.isr_ext_info = self.ExtIsrInfo()
|
||
|
addr = parse_get_symbol_addr('g_hwiForm')
|
||
|
if self.version == 207:
|
||
|
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))
|
||
|
elif self.version == 208:
|
||
|
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))
|
||
|
|
||
|
def print_isr_info(self):
|
||
|
print("\r\n--------------------content of 中断信息:--------------------",file=self.info_fd)
|
||
|
if self.version == 207:
|
||
|
for hwi in self.isr_ext_info.g_hwiForm:
|
||
|
if hwi.hook!=0 or hwi.respCount!=0:
|
||
|
print("%s[0x%x][call_cnt=%d]"%(_addr_in_2_function_name(hwi.hook),hwi.hook,hwi.respCount),file=self.info_fd)
|
||
|
elif self.version == 208:
|
||
|
for hwi in self.isr_ext_info.g_hwiForm:
|
||
|
if hwi.hook!=0 or hwi.respCount!=0:
|
||
|
print("%s[0x%x][call_cnt=%d]"%(_addr_in_2_function_name(hwi.hook),hwi.hook,hwi.respCount),file=self.info_fd)
|
||
|
|
||
|
def make_per_cpu_info(self):
|
||
|
self.core=self._ExtPercpu()
|
||
|
self.core.handle_addr = parse_get_symbol_addr('g_percpu')
|
||
|
self.core.per_cpu = parse_memory_2_class(self.core.handle_addr,Percpu,sizeof(Percpu))
|
||
|
|
||
|
addr = parse_get_symbol_addr('g_tickCount')
|
||
|
if addr:
|
||
|
obj=parse_memory_2_class(addr,c_ulonglong,sizeof(c_ulonglong))
|
||
|
self.core.g_tickCount=obj.value
|
||
|
|
||
|
addr = parse_get_symbol_addr('g_sysClock')
|
||
|
if addr:
|
||
|
obj=parse_memory_2_class(addr,c_uint,sizeof(c_uint))
|
||
|
self.core.g_sysClock=obj.value
|
||
|
|
||
|
addr = parse_get_symbol_addr('g_intCount')
|
||
|
if addr:
|
||
|
obj=parse_memory_2_class(addr,c_uint,sizeof(c_uint))
|
||
|
self.core.g_intCount=obj.value
|
||
|
|
||
|
addr = parse_get_symbol_addr('g_tickPerSecond')
|
||
|
if addr:
|
||
|
obj=parse_memory_2_class(addr,c_uint,sizeof(c_uint))
|
||
|
self.core.g_tickPerSecond=obj.value
|
||
|
|
||
|
addr = parse_get_symbol_addr('g_cycle2NsScale')
|
||
|
if addr:
|
||
|
obj=parse_memory_2_class(addr,c_double,sizeof(c_double))
|
||
|
self.core.g_cycle2NsScale=obj.value
|
||
|
(ret,self.core.task_wait_addr) = _los_List_get_all_node(self.core.per_cpu.taskSortLink.sortLink)
|
||
|
|
||
|
(ret,self.core.timer_wait_addr) = _los_List_get_all_node(self.core.per_cpu.swtmrSortLink.sortLink)
|
||
|
|
||
|
def print_per_cpu_info(self):
|
||
|
print("\r\n--------------------content of 调度信息汇总:--------------------",file=self.info_fd)
|
||
|
print("说明:taskLockCnt锁任务嵌套次数",file=self.info_fd)
|
||
|
if self.core.g_cycle2NsScale:
|
||
|
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)
|
||
|
else:
|
||
|
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)
|
||
|
|
||
|
uapi_print_ctypes_obj('schedule',self.core.per_cpu,self.info_fd)
|
||
|
|
||
|
delay_tick=0
|
||
|
for x in self.core.task_wait_addr:
|
||
|
x = x-ctype_member_offset('sortList.sortLinkNode',LosTaskCB)
|
||
|
i=0
|
||
|
while i< self.task_cnt:
|
||
|
tcb=self.tcb_array[i]
|
||
|
ext_info=self.ext_task_list[i]
|
||
|
if ext_info.handle_addr==x:
|
||
|
delay_tick=delay_tick+tcb.sortList.idxRollNum
|
||
|
print("任务等待剩余时间:%s[%d][剩余时间 delay=%d tick][idxRollNum=%d]"%(ext_info.name,tcb.taskId,delay_tick,tcb.sortList.idxRollNum),file=self.info_fd)
|
||
|
i=i+1
|
||
|
|
||
|
delay_tick=0
|
||
|
for x in self.core.timer_wait_addr:
|
||
|
x = x-ctype_member_offset('sortList.sortLinkNode',LosSwtmrCB)
|
||
|
i=0
|
||
|
while i< self.timer_cnt:
|
||
|
timer=self.timer_array[i]
|
||
|
ext_info=self.timer_ext_info[i]
|
||
|
if ext_info.handle_addr==x:
|
||
|
delay_tick=delay_tick+timer.sortList.idxRollNum
|
||
|
print("定时器到期剩余时间:%s[%d][剩余时间=%d tick][idxRollNum=%d]"%(ext_info.func_name,timer.timerId,delay_tick,timer.sortList.idxRollNum),file=self.info_fd)
|
||
|
i=i+1
|
||
|
|
||
|
def make_task_info(self):
|
||
|
addr = parse_get_symbol_addr('g_taskMaxNum')
|
||
|
obj=parse_memory_2_class(addr,c_uint,4)
|
||
|
self.task_cnt = obj.value
|
||
|
|
||
|
addr = parse_get_symbol_addr('g_osTaskCBArray')
|
||
|
obj=parse_memory_2_class(addr,c_uint,4)
|
||
|
addr=obj.value
|
||
|
i=0
|
||
|
while i < self.task_cnt:
|
||
|
ext_info = self._ExtTaskInfo()
|
||
|
obj=parse_memory_2_class(addr,LosTaskCB,sizeof(LosTaskCB))
|
||
|
self.tcb_array.append(obj)
|
||
|
self.ext_task_list.append(ext_info)
|
||
|
ext_info.handle_addr=addr
|
||
|
ext_info.pend_addr = ext_info.handle_addr+ctype_member_offset('pendList',LosTaskCB)
|
||
|
addr=addr+sizeof(LosTaskCB)
|
||
|
i=i+1
|
||
|
self._make_task_extra_info()
|
||
|
|
||
|
def _task_status_2_string(self,status):
|
||
|
str=''
|
||
|
if (status&OS_TASK_STATUS_UNUSED):
|
||
|
str=str+"unused,"
|
||
|
if (status&OS_TASK_STATUS_RUNNING):
|
||
|
str=str+'runing,'
|
||
|
if (status&OS_TASK_STATUS_READY):
|
||
|
str=str+'ready,'
|
||
|
if (status&OS_TASK_STATUS_SUSPEND):
|
||
|
str=str+'suspend,'
|
||
|
if (status&OS_TASK_STATUS_PEND):
|
||
|
str=str+'pend,'
|
||
|
if (status&OS_TASK_STATUS_DELAY):
|
||
|
str=str+'delay,'
|
||
|
if (status&OS_TASK_STATUS_TIMEOUT):
|
||
|
str=str+'timeout,'
|
||
|
if (status&OS_TASK_STATUS_PEND_TIME):
|
||
|
str=str+'pendtime,'
|
||
|
return str
|
||
|
|
||
|
def _make_task_extra_info(self):
|
||
|
i=0
|
||
|
while i < self.task_cnt:
|
||
|
tcb = self.tcb_array[i]
|
||
|
ext_info=self.ext_task_list[i]
|
||
|
if tcb.taskStatus & OS_TASK_STATUS_UNUSED: #未使用任务返回
|
||
|
i=i+1
|
||
|
continue;
|
||
|
|
||
|
ext_info.buttom = tcb.topOfStack+tcb.stackSize #计算栈buttom
|
||
|
ext_info.status_str = self._task_status_2_string(tcb.taskStatus)
|
||
|
if tcb.taskSem!=0:
|
||
|
ext_info.take_sem = parse_memory_2_class(tcb.taskSem,LosSemCB,sizeof(LosSemCB))
|
||
|
|
||
|
#生成taskname
|
||
|
addr=tcb.taskName
|
||
|
str = parse_memory_2_string(addr,32)
|
||
|
if str!=None:
|
||
|
ext_info.name=str
|
||
|
|
||
|
#判断栈是否溢出
|
||
|
obj = parse_memory_2_class(tcb.topOfStack,c_uint,sizeof(c_uint))
|
||
|
if obj.value==0xCCCCCCCC:
|
||
|
ext_info.over=0
|
||
|
else:
|
||
|
ext_info.over=1
|
||
|
|
||
|
#计算栈峰值
|
||
|
addr = tcb.topOfStack+4
|
||
|
while addr < ext_info.buttom:
|
||
|
obj = parse_memory_2_class(addr,c_uint,sizeof(c_uint))
|
||
|
if obj.value != 0xCACACACA:
|
||
|
break
|
||
|
addr+=4
|
||
|
ext_info.peek_used = ext_info.buttom-addr
|
||
|
|
||
|
enter_name=parse_addr_2_function_name(tcb.taskEntry)
|
||
|
if enter_name!=None:
|
||
|
ext_info.enter_name = enter_name
|
||
|
if self.version == 207:
|
||
|
ext_info.task_context=parse_memory_2_class(tcb.stackPointer,TaskContext,sizeof(TaskContext))
|
||
|
elif self.version == 208:
|
||
|
ext_info.task_context=parse_memory_2_class(tcb.stackPointer,TaskContext,sizeof(TaskContext))
|
||
|
else:
|
||
|
ext_info.task_context=parse_memory_2_class(tcb.stackPointer,td_u32,sizeof(td_u32))
|
||
|
i=i+1
|
||
|
|
||
|
def print_task_short_info(self):
|
||
|
print("\r\n--------------------content of 任务信息摘要:--------------------",file=self.info_fd)
|
||
|
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)
|
||
|
i=0
|
||
|
while i < self.task_cnt:
|
||
|
tcb = self.tcb_array[i]
|
||
|
ext_info = self.ext_task_list[i]
|
||
|
if not tcb.taskStatus & OS_TASK_STATUS_UNUSED:
|
||
|
print('%4d|%20s|%4d|0x%08x|0x%08x|0x%08x |0x%08x|0x%08x|0x%08x|%4d|%15s|'
|
||
|
%(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)
|
||
|
i=i+1
|
||
|
|
||
|
def print_task_detail_info(self):
|
||
|
print("\r\n--------------------content of 任务详细信息:--------------------",file=self.info_fd)
|
||
|
print("说明:tcb任务控制块信息,context:任务上下文的寄存器信息,backtrace 栈回溯",file=self.info_fd)
|
||
|
i=0
|
||
|
while i < self.task_cnt:
|
||
|
print('',file=self.info_fd)
|
||
|
tcb = self.tcb_array[i]
|
||
|
uapi_print_ctypes_obj('tcb',tcb,self.info_fd)
|
||
|
ext_info = self.ext_task_list[i]
|
||
|
i=i+1
|
||
|
if tcb.taskStatus & OS_TASK_STATUS_UNUSED:
|
||
|
continue
|
||
|
#打印寄存器信息
|
||
|
print("[TASK]%s 寄存器:"%(ext_info.name),file=self.info_fd)
|
||
|
uapi_print_ctypes_obj('context',ext_info.task_context,self.info_fd)
|
||
|
|
||
|
#打印back_trace
|
||
|
print("[TASK]%s 栈回溯:"%(ext_info.name),file=self.info_fd)
|
||
|
if self.version == 207:
|
||
|
sp = tcb.stackPointer+sizeof(TaskContext)
|
||
|
elif self.version == 208:
|
||
|
sp = tcb.stackPointer+sizeof(TaskContext)
|
||
|
else:
|
||
|
sp = tcb.stackPointer
|
||
|
self.stack_back_trace(sp,tcb.topOfStack + tcb.stackSize)
|
||
|
print("[TASK]%s 其它状态:"%(ext_info.name),file=self.info_fd)
|
||
|
if ext_info.take_sem:
|
||
|
print("[waitting_sem][id=0x%08x]"%(ext_info.take_sem.semId),file=self.info_fd)
|
||
|
|
||
|
def make_heap_info(self):
|
||
|
addr = parse_get_symbol_addr('m_aucSysMem0')
|
||
|
obj=parse_memory_2_class(addr,c_uint,4)
|
||
|
self.heap_start=obj.value
|
||
|
if self.version == 207:
|
||
|
self.heap_head=parse_memory_2_class(self.heap_start,LosMemPoolInfo,sizeof(LosMemPoolInfo))
|
||
|
if self.heap_head:
|
||
|
self.heap_end = self.heap_start + self.heap_head.size
|
||
|
elif self.version == 208:
|
||
|
self.heap_head=parse_memory_2_class(self.heap_start,LosMemPoolInfo,sizeof(LosMemPoolInfo))
|
||
|
if self.heap_head:
|
||
|
self.heap_end = self.heap_start + self.heap_head.size
|
||
|
|
||
|
|
||
|
def print_heap_info(self):
|
||
|
print("--------------------content of 内存堆信息:--------------------",file=self.info_fd)
|
||
|
self.print_heap_head_info()
|
||
|
self.print_heap_from_head()
|
||
|
self.print_heap_from_tail()
|
||
|
|
||
|
def print_heap_head_info(self):
|
||
|
pass
|
||
|
|
||
|
def print_heap_from_head(self):
|
||
|
print("从头遍历内存池:",file=self.info_fd)
|
||
|
print("说明:node内存节点地址,usr用户空间地址(申请对齐内存场景不准),size内存大小,used是否占用",file=self.info_fd)
|
||
|
if self.heap_head:
|
||
|
addr = self.heap_head.head
|
||
|
while addr >= self.heap_start and addr <= self.heap_end:
|
||
|
node = parse_memory_2_class(addr,LosHeapNode,sizeof(LosHeapNode))
|
||
|
if(node.size==0):
|
||
|
break;
|
||
|
str="[node=0x%x][usr=0x%x][prev=0x%x][size=0x%x][used=%d]"%(addr,addr+8,node.prev,node.size,node.used)
|
||
|
if hasattr(LosHeapNode,'lr'):
|
||
|
i=0
|
||
|
while i< sizeof(node.lr)/sizeof(c_uint):
|
||
|
str="%s[%s][0x%x]"%(str,_addr_in_2_function_name(node.lr[i]),node.lr[i])
|
||
|
i=i+1
|
||
|
print(str,file=self.info_fd)
|
||
|
addr=addr+sizeof(LosHeapNode)+node.size
|
||
|
|
||
|
def print_heap_from_tail(self):
|
||
|
print("从尾遍历内存池:",file=self.info_fd)
|
||
|
print("说明:node内存节点地址,usr用户空间地址(申请对齐内存场景不准),size内存大小,used是否占用",file=self.info_fd)
|
||
|
if self.heap_head:
|
||
|
addr = self.heap_head.tail
|
||
|
while addr >= self.heap_start and addr <= self.heap_end:
|
||
|
node = parse_memory_2_class(addr,LosHeapNode,sizeof(LosHeapNode))
|
||
|
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)
|
||
|
print(str,file=self.info_fd)
|
||
|
if addr==self.heap_head.head:
|
||
|
break
|
||
|
addr=node.prev
|
||
|
|
||
|
def make_queue_info(self):
|
||
|
addr = parse_get_u32_symbol_val('g_osAllQueue')
|
||
|
i=0
|
||
|
while i< self.queue_cnt:
|
||
|
ext_info=self._ExtQueueInfo()
|
||
|
obj=parse_memory_2_class(addr,LosQueueCB,sizeof(LosQueueCB))
|
||
|
ext_info.handle_addr=addr
|
||
|
self.queue_array.append(obj)
|
||
|
self.queue_ext_info.append(ext_info)
|
||
|
addr=addr+sizeof(LosQueueCB)
|
||
|
i=i+1
|
||
|
self._make_queue_ext_info()
|
||
|
|
||
|
def _make_queue_ext_info(self):
|
||
|
i=0
|
||
|
while i< self.queue_cnt:
|
||
|
queue=self.queue_array[i]
|
||
|
ext_info=self.queue_ext_info[i]
|
||
|
if queue and queue.queueState==1: #used
|
||
|
if self.version == 207:
|
||
|
(ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB))
|
||
|
elif self.version == 208:
|
||
|
(ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB))
|
||
|
else:
|
||
|
(ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB) + 4)
|
||
|
for node_addr in addr_list:
|
||
|
ext_info.pend_read_task_list.append(node_addr)
|
||
|
if self.version == 207:
|
||
|
(ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB)+sizeof(LOS_DL_LIST))
|
||
|
elif self.version == 208:
|
||
|
(ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB)+sizeof(LOS_DL_LIST))
|
||
|
else:
|
||
|
(ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB) + 4 + sizeof(LOS_DL_LIST))
|
||
|
for node_addr in addr_list:
|
||
|
ext_info.pend_write_task_list.append(node_addr)
|
||
|
i=i+1
|
||
|
|
||
|
def print_queue_info(self):
|
||
|
print("\r\n--------------------content of 消息队列信息:--------------------",file=self.info_fd)
|
||
|
print("说明:queueHandle队列的内存空间,queueLen队列长度,queueSize单个节点大小,queueId队列id,readWriteableCnt[0]当前队列中有几个数据,readWriteableCnt[1]当前队列中有几个剩余空间",file=self.info_fd)
|
||
|
print("",file=self.info_fd)
|
||
|
i=0
|
||
|
while i< self.queue_cnt:
|
||
|
queue=self.queue_array[i]
|
||
|
ext_info=self.queue_ext_info[i]
|
||
|
if queue.queueState==1:
|
||
|
uapi_print_ctypes_obj('queue',queue,self.info_fd)
|
||
|
list=self.get_pending_task(ext_info.pend_read_task_list)
|
||
|
print("等待读该消息队列的任务ID:",list,file=self.info_fd)
|
||
|
list=self.get_pending_task(ext_info.pend_write_task_list)
|
||
|
print("等待写该消息队列的任务ID:",list,file=self.info_fd)
|
||
|
print("",file=self.info_fd)
|
||
|
i=i+1
|
||
|
|
||
|
def _make_timer_ext_info(self):
|
||
|
i=0
|
||
|
while i< self.timer_cnt:
|
||
|
timer=self.timer_array[i]
|
||
|
ext_info=self.timer_ext_info[i]
|
||
|
if timer.state==OS_SWTMR_STATUS_UNUSED or timer.state==OS_SWTMR_STATUS_DELETING:
|
||
|
i=i+1
|
||
|
continue
|
||
|
ext_info.func_name = parse_addr_2_function_name(timer.handler)
|
||
|
i=i+1
|
||
|
|
||
|
def make_timer_info(self):
|
||
|
addr = parse_get_u32_symbol_val('g_osSwtmrCBArray')
|
||
|
i=0
|
||
|
while i< self.timer_cnt:
|
||
|
obj=parse_memory_2_class(addr,LosSwtmrCB,sizeof(LosSwtmrCB))
|
||
|
ext_info=self._ExtTimerInfo()
|
||
|
self.timer_ext_info.append(ext_info)
|
||
|
self.timer_array.append(obj)
|
||
|
ext_info.handle_addr=addr
|
||
|
|
||
|
addr=addr+sizeof(LosSwtmrCB)
|
||
|
i=i+1
|
||
|
self._make_timer_ext_info()
|
||
|
|
||
|
def print_timer_info(self):
|
||
|
print("--------------------content of 定时器信息:--------------------",file=self.info_fd)
|
||
|
print("说明:timer_id定时器id,handler回调函数的地址(已解析),state(0:未使用 1:删除 2:创建 3:执行中),mode(1:周期 2:单次)",file=self.info_fd)
|
||
|
print("\t overrun周期性定时器执行次数,arg用户参数,inProcess到期已添加到待执行队列",file=self.info_fd)
|
||
|
print('',file=self.info_fd)
|
||
|
i=0
|
||
|
while i< self.timer_cnt:
|
||
|
timer=self.timer_array[i]
|
||
|
ext_info=self.timer_ext_info[i]
|
||
|
if timer.state==OS_SWTMR_STATUS_UNUSED or timer.state==OS_SWTMR_STATUS_DELETING:
|
||
|
i=i+1
|
||
|
continue
|
||
|
print("timer_id=%d %s[0x%x]"%(timer.timerId,ext_info.func_name,timer.handler),file=self.info_fd)
|
||
|
uapi_print_ctypes_obj('timer',timer,self.info_fd)
|
||
|
print('',file=self.info_fd)
|
||
|
i=i+1
|
||
|
|
||
|
def _make_sem_extra_info(self):
|
||
|
i=0
|
||
|
while i< self.sem_cnt:
|
||
|
sem=self.sem_array[i]
|
||
|
ext_info=self.sem_ext_info[i]
|
||
|
if sem.semStat==1: #used
|
||
|
(ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('semList',LosSemCB))
|
||
|
for node_addr in addr_list:
|
||
|
ext_info.pend_task_list.append(node_addr)
|
||
|
i=i+1
|
||
|
|
||
|
def make_sem_info(self):
|
||
|
addr = parse_get_u32_symbol_val('g_osAllSem')
|
||
|
i=0
|
||
|
while i< self.sem_cnt:
|
||
|
ext_info=self._ExtSemInfo()
|
||
|
obj=parse_memory_2_class(addr,LosSemCB,sizeof(LosSemCB))
|
||
|
ext_info.handle_addr=addr
|
||
|
self.sem_array.append(obj)
|
||
|
self.sem_ext_info.append(ext_info)
|
||
|
addr=addr+sizeof(LosSemCB)
|
||
|
i=i+1
|
||
|
self._make_sem_extra_info()
|
||
|
|
||
|
def get_pending_task(self,addr_list):
|
||
|
list=[]
|
||
|
for addr in addr_list:
|
||
|
i=0
|
||
|
while i < self.task_cnt:
|
||
|
ext_task = self.ext_task_list[i]
|
||
|
tcb = self.tcb_array[i]
|
||
|
if addr== ext_task.pend_addr:
|
||
|
list.append(tcb.taskId)
|
||
|
i=i+1
|
||
|
return list
|
||
|
|
||
|
def print_sem_info(self):
|
||
|
print("--------------------content of 信号量:--------------------",file=self.info_fd)
|
||
|
print("说明:semType(0:计数信号量 1:互斥信号量),semCount剩余信号量个数",file=self.info_fd)
|
||
|
print("",file=self.info_fd)
|
||
|
i=0
|
||
|
while i< self.sem_cnt:
|
||
|
sem=self.sem_array[i]
|
||
|
ext_info=self.sem_ext_info[i]
|
||
|
if sem.semStat:
|
||
|
uapi_print_ctypes_obj('sem',sem,self.info_fd)
|
||
|
list=self.get_pending_task(ext_info.pend_task_list)
|
||
|
print("等待该信号量的任务ID:",list,file=self.info_fd)
|
||
|
print('',file=self.info_fd)
|
||
|
i=i+1
|
||
|
|
||
|
def make_crash_info(self):
|
||
|
addr = parse_get_symbol_addr('g_excInfo')
|
||
|
self.excInfo = parse_memory_2_class(addr,ExcInfo,sizeof(ExcInfo))
|
||
|
|
||
|
def print_crash_info(self):
|
||
|
print("--------------------content of 死机信息:--------------------",file=self.info_fd)
|
||
|
uapi_print_ctypes_obj('g_excInfo',self.excInfo,self.info_fd)
|
||
|
if self.excInfo.context!=0:
|
||
|
obj=parse_memory_2_class(self.excInfo.context,ExcContext,sizeof(ExcContext))
|
||
|
uapi_print_ctypes_obj('context',obj,self.info_fd)
|
||
|
if self.version == 207:
|
||
|
self.stack_back_trace(obj.taskContext.sp+sizeof(TaskContext),obj.taskContext.sp+0x1000)
|
||
|
elif self.version == 208:
|
||
|
self.stack_back_trace(obj.taskContext.sp+sizeof(TaskContext),obj.taskContext.sp+0x1000)
|
||
|
else:
|
||
|
self.stack_back_trace(obj.SP, obj.SP + 0x1000)
|
||
|
|
||
|
|
||
|
|
||
|
def stack_back_trace(self,start_addr,end_addr):
|
||
|
sp=start_addr
|
||
|
while sp < end_addr:
|
||
|
obj=parse_memory_2_class(sp,c_uint,sizeof(c_uint))
|
||
|
if obj:
|
||
|
name = parse_addr_in_2_function_name(obj.value-4)
|
||
|
if name:
|
||
|
print("[BACK Trace][addr=0x%08x][val=0x%08x]%s"%(sp,obj.value,name),file=self.info_fd)
|
||
|
else:
|
||
|
pass
|
||
|
#print("[BACK Trace][addr=0x%08x][val=0x%08x]"%(sp,obj.value),file=self.info_fd)
|
||
|
|
||
|
sp=sp+4
|
||
|
|
||
|
_g_parse_liteos_ctrl=_PhaseLiteosCtrl()
|
||
|
def make_liteos_info():
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.make_per_cpu_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]make_per_cpu_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.make_task_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]make_task_info fail.")
|
||
|
if _g_parse_liteos_ctrl.version != 208:
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.make_queue_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]make_queue_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.make_heap_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]make_heap_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.make_timer_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]make_timer_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.make_sem_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]make_sem_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.make_crash_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]make_crash_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.make_isr_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]make_isr_info fail.")
|
||
|
|
||
|
def print_liteos_info():
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.print_isr_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]print_isr_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.print_per_cpu_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]print_per_cpu_info fail.")
|
||
|
if _g_parse_liteos_ctrl.version != 208:
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.print_queue_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]print_queue_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.print_timer_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]print_timer_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.print_heap_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]print_heap_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.print_sem_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]print_sem_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.print_task_short_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]print_task_short_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.print_task_detail_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]print_task_detail_info fail.")
|
||
|
try:
|
||
|
_g_parse_liteos_ctrl.print_crash_info()
|
||
|
except:
|
||
|
print("[EXCEPTION]print_crash_info fail.")
|
||
|
|
||
|
def parse_liteos206_info(log_fp):
|
||
|
_g_parse_liteos_ctrl.info_fd = log_fp
|
||
|
_g_parse_liteos_ctrl.version = 206
|
||
|
make_liteos_info()
|
||
|
print_liteos_info()
|
||
|
|
||
|
def parse_liteos207_info(log_fp):
|
||
|
_g_parse_liteos_ctrl.info_fd = log_fp
|
||
|
_g_parse_liteos_ctrl.version = 207
|
||
|
make_liteos_info()
|
||
|
print_liteos_info()
|
||
|
|
||
|
def parse_liteos208_info(log_fp):
|
||
|
_g_parse_liteos_ctrl.info_fd = log_fp
|
||
|
_g_parse_liteos_ctrl.version = 208
|
||
|
make_liteos_info()
|
||
|
print_liteos_info()
|
||
|
|
||
|
'''
|
||
|
context.mstatus(mcause)=0x80207800
|
||
|
context.mepc=0x12530
|
||
|
context.tp=0xcacacaca
|
||
|
context.sp=0xcacacaca
|
||
|
context.s11=0x4040404--未压栈(中断场景)
|
||
|
context.s10=0x5050505--未压栈
|
||
|
context.s9=0x6060606--未压栈
|
||
|
context.s8=0x7070707--未压栈
|
||
|
context.s7=0x8080808--未压栈
|
||
|
context.s6=0x9090909--未压栈
|
||
|
context.s5=0x80206088--未压栈
|
||
|
context.s4=0x20008000--未压栈
|
||
|
context.s3=0x80206080--未压栈
|
||
|
context.s2=0x200079dc--未压栈
|
||
|
context.s1=0x0--未压栈
|
||
|
context.s0=0x20007a74--未压栈
|
||
|
|
||
|
context.t6=0x4040404
|
||
|
context.t5=0x5050505
|
||
|
context.t4=0x6060606
|
||
|
context.t3=0x7070707
|
||
|
context.a7=0x8080808
|
||
|
context.a6=0x9090909
|
||
|
context.a5=0xa0a0a0a
|
||
|
context.a4=0xb0b0b0b
|
||
|
context.a3=0xc0c0c0c
|
||
|
context.a2=0xd0d0d0d
|
||
|
context.a1=0xe0e0e0e
|
||
|
context.a0=0xf0f0f0f
|
||
|
context.t2=0x10101010
|
||
|
context.t1=0x11111111
|
||
|
context.t0=0x12121212
|
||
|
context.ra=0x13131313
|
||
|
|
||
|
context.fs11=0x20202020--(进中断)未压栈
|
||
|
context.fs10=0x21212121--未压栈
|
||
|
context.fs9=0x22222222--未压栈
|
||
|
context.fs8=0x23232323--未压栈
|
||
|
context.fs7=0x24242424--未压栈
|
||
|
context.fs6=0x25252525--未压栈
|
||
|
context.fs5=0x26262626--未压栈
|
||
|
context.fs4=0x27272727--未压栈
|
||
|
context.fs3=0x28282828--未压栈
|
||
|
context.fs2=0x29292929--未压栈
|
||
|
context.fs1=0x2a2a2a2a--未压栈
|
||
|
context.fs0=0x2b2b2b2b--未压栈
|
||
|
|
||
|
context.ft11=0x20202020
|
||
|
context.ft10=0x21212121
|
||
|
context.ft9=0x22222222
|
||
|
context.ft8=0x23232323
|
||
|
context.fa7=0x24242424
|
||
|
context.fa6=0x25252525
|
||
|
context.fa5=0x26262626
|
||
|
context.fa4=0x27272727
|
||
|
context.fa3=0x28282828
|
||
|
context.fa2=0x80206088
|
||
|
context.fa1=0x20008000
|
||
|
context.fa0=0x80206080
|
||
|
context.ft7=0x20009000
|
||
|
context.ft6=0x20007ad4
|
||
|
context.ft5=0x20007ad4
|
||
|
context.ft4=0x11f5a
|
||
|
context.ft3=0x32
|
||
|
context.ft2=0x20007ad4
|
||
|
context.ft1=0x20007a70
|
||
|
context.ft0=0x117a2
|
||
|
context.fcsr=0x0
|
||
|
context.reserved[0]=0x0
|
||
|
context.reserved[1]=0x20007a74
|
||
|
context.reserved[2]=0x12530
|
||
|
|
||
|
|
||
|
typedef struct {
|
||
|
uint32_t ccause;
|
||
|
uint32_t mcause;
|
||
|
uint32_t mtval;
|
||
|
uint32_t gp;
|
||
|
TaskContext taskContext;
|
||
|
} ExcContext;
|
||
|
|
||
|
typedef struct {
|
||
|
uint16_t phase; /**< Exception occurrence phase: 0 indicates that the exception occurs during
|
||
|
* initialization, 1 indicates that the exception occurs during task, 2
|
||
|
* indicates that the exception occurs during interrupt, and 3 indicates that
|
||
|
* the exception occurs during exception.
|
||
|
*/
|
||
|
uint16_t type; /**< Type of exception, refer to no. 1-19 listed above for exceptions */
|
||
|
uint32_t faultAddr; /**< A precise address access error indicates the error access address where
|
||
|
* the exception occurred.
|
||
|
*/
|
||
|
uint32_t thrdPid; /**< An exception occurs in the interrupt, indicating the interrupt number. An
|
||
|
* exception occurs in the task, indicating the task id, or 0xffffffff if it
|
||
|
* occurs during initialization
|
||
|
*/
|
||
|
uint16_t nestCnt; /**< The number of nested exceptions, currently only support the first time the
|
||
|
* exception into the implementation of the registered hook function
|
||
|
*/
|
||
|
uint16_t reserved; /**< Reserved */
|
||
|
ExcContext *context; /**< The hardware context at which an exception to an automatic stack floating point
|
||
|
* register occurs
|
||
|
*/
|
||
|
} ExcInfo;
|
||
|
'''
|