feat: L0-L1 支持Trace
1.【需求描述】
L0~L1 支持Trace,提供两种工作模式:在线模式、离线缓存模式, 用于按时间线追踪系统事件,如任务切换、中断、ipc等。
2.【方案描述】
L0:
(1).在内核模块预置静态代码桩
(2).触发桩后,收集系统上下文信息
(3).离线模式则写入内存,用户可通过dump导出;
(4).在线模式通过pipeline对接IDE进行可视化解析和展示;
L1:
新增trace字符设备,位于"/dev/trace",通过对设备节点的read\write\ioctl,实现用户态trace;
BREAKING CHANGE:
1.新增一系列trace的对外API,位于los_trace.h中.
LOS_TRACE_EASY简易插桩
LOS_TRACE标准插桩
LOS_TraceInit配置Trace缓冲区的地址和大小
LOS_TraceStart开启事件记录
LOS_TraceStop停止事件记录
LOS_TraceRecordDump输出Trace缓冲区数据
LOS_TraceRecordGet获取Trace缓冲区的首地址
LOS_TraceReset清除Trace缓冲区中的事件
LOS_TraceEventMaskSet设置事件掩码,仅记录某些模块的事件
LOS_TraceHwiFilterHookReg注册过滤特定中断号事件的钩子函数
Close #I46WA0
Signed-off-by: LiteOS2021 <dinglu@huawei.com>
Change-Id: I6a8e64794c4852f2c2980993a06180e09ec6ee0d
This commit is contained in:
@@ -40,14 +40,11 @@
|
||||
#include "los_sched_pri.h"
|
||||
#include "los_spinlock.h"
|
||||
#include "los_task_pri.h"
|
||||
#ifdef LOSCFG_KERNEL_TRACE
|
||||
#include "los_trace.h"
|
||||
#include "los_trace_frame.h"
|
||||
#endif
|
||||
#include "los_vm_lock.h"
|
||||
#include "los_vm_map.h"
|
||||
#include "los_vm_page.h"
|
||||
#include "los_vm_phys.h"
|
||||
#include "los_hook.h"
|
||||
|
||||
#define USE_TASKID_AS_HANDLE YES
|
||||
#define USE_MMAP YES
|
||||
@@ -93,7 +90,6 @@ STATIC UINT32 LiteIpcWrite(IpcContent *content);
|
||||
STATIC UINT32 GetTid(UINT32 serviceHandle, UINT32 *taskID);
|
||||
STATIC UINT32 HandleSpecialObjects(UINT32 dstTid, IpcListNode *node, BOOL isRollback);
|
||||
|
||||
|
||||
STATIC const struct file_operations_vfs g_liteIpcFops = {
|
||||
.open = LiteIpcOpen, /* open */
|
||||
.close = LiteIpcClose, /* close */
|
||||
@@ -101,47 +97,6 @@ STATIC const struct file_operations_vfs g_liteIpcFops = {
|
||||
.mmap = LiteIpcMmap, /* mmap */
|
||||
};
|
||||
|
||||
#ifdef LOSCFG_KERNEL_TRACE
|
||||
typedef enum {
|
||||
WRITE,
|
||||
WRITE_DROP,
|
||||
TRY_READ,
|
||||
READ,
|
||||
READ_DROP,
|
||||
READ_TIMEOUT,
|
||||
KILL,
|
||||
OPERATION_NUM
|
||||
} IpcOpertion;
|
||||
|
||||
const char *g_operStr[OPERATION_NUM] = {"WRITE", "WRITE_DROP", "TRY_READ", "READ", "READ_DROP", "READ_TIMEOUT"};
|
||||
const char *g_msgTypeStr[MT_NUM] = {"REQUEST", "REPLY", "FAILED_REPLY", "DEATH_NOTIFY"};
|
||||
const char *g_ipcStatusStr[2] = {"NOT_PEND", "PEND"};
|
||||
|
||||
LITE_OS_SEC_TEXT STATIC VOID IpcTrace(IpcMsg *msg, UINT32 operation, UINT32 ipcStatus, UINT32 msgType)
|
||||
{
|
||||
UINT32 curTid = LOS_CurTaskIDGet();
|
||||
UINT32 curPid = LOS_GetCurrProcessID();
|
||||
UINT32 srcTid;
|
||||
UINT32 srcPid;
|
||||
UINT32 dstTid;
|
||||
UINT32 dstPid;
|
||||
UINT32 ret = (msg == NULL) ? INVAILD_ID : GetTid(msg->target.handle, &dstTid);
|
||||
if (operation <= WRITE_DROP) {
|
||||
srcTid = curTid;
|
||||
srcPid = curPid;
|
||||
dstTid = ret ? INVAILD_ID : dstTid;
|
||||
dstPid = ret ? INVAILD_ID : OS_TCB_FROM_TID(dstTid)->processID;
|
||||
} else {
|
||||
srcTid = (msg == NULL) ? INVAILD_ID : msg->taskID;
|
||||
srcPid = (msg == NULL) ? INVAILD_ID : msg->processID;
|
||||
dstTid = curTid;
|
||||
dstPid = curPid;
|
||||
}
|
||||
UINT8 code = (msg == NULL) ? INVAILD_ID : (UINT8)msg->code;
|
||||
LOS_Trace(LOS_TRACE_IPC, srcTid, srcPid, dstTid, dstPid, msgType, code, operation, ipcStatus);
|
||||
}
|
||||
#endif
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 OsLiteIpcInit(VOID)
|
||||
{
|
||||
UINT32 ret, i;
|
||||
@@ -162,12 +117,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsLiteIpcInit(VOID)
|
||||
for (i = 0; i < LOSCFG_BASE_CORE_PROCESS_LIMIT; i++) {
|
||||
LOS_ListInit(&(g_ipcUsedNodelist[i]));
|
||||
}
|
||||
#ifdef LOSCFG_KERNEL_TRACE
|
||||
ret = LOS_TraceReg(LOS_TRACE_IPC, OsIpcTrace, LOS_TRACE_IPC_NAME, LOS_TRACE_ENABLE);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("liteipc LOS_TraceReg failed:%d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -941,9 +891,14 @@ LITE_OS_SEC_TEXT STATIC UINT32 CheckPara(IpcContent *content, UINT32 *dstTid)
|
||||
}
|
||||
#if (USE_TIMESTAMP == YES)
|
||||
if (now > msg->timestamp + LITEIPC_TIMEOUT_NS) {
|
||||
#ifdef LOSCFG_KERNEL_TRACE
|
||||
IpcTrace(msg, WRITE_DROP, 0, msg->type);
|
||||
#ifdef LOSCFG_KERNEL_HOOK
|
||||
ret = GetTid(msg->target.handle, dstTid);
|
||||
if (ret != LOS_OK) {
|
||||
*dstTid = INVAILD_ID;
|
||||
}
|
||||
#endif
|
||||
OsHookCall(LOS_HOOK_TYPE_IPC_WRITE_DROP, msg, *dstTid,
|
||||
(*dstTid == INVAILD_ID) ? INVAILD_ID : OS_TCB_FROM_TID(*dstTid)->processID, 0);
|
||||
PRINT_ERR("A timeout reply, request timestamp:%lld, now:%lld\n", msg->timestamp, now);
|
||||
return -ETIME;
|
||||
}
|
||||
@@ -999,9 +954,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcWrite(IpcContent *content)
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LosTaskCB *tcb = OS_TCB_FROM_TID(dstTid);
|
||||
LOS_ListTailInsert(&(tcb->msgListHead), &(buf->listNode));
|
||||
#ifdef LOSCFG_KERNEL_TRACE
|
||||
IpcTrace(&buf->msg, WRITE, tcb->ipcStatus, buf->msg.type);
|
||||
#endif
|
||||
OsHookCall(LOS_HOOK_TYPE_IPC_WRITE, &buf->msg, dstTid, tcb->processID, tcb->ipcStatus);
|
||||
if (tcb->ipcStatus & IPC_THREAD_STATUS_PEND) {
|
||||
tcb->ipcStatus &= ~IPC_THREAD_STATUS_PEND;
|
||||
OsTaskWakeClearPendMask(tcb);
|
||||
@@ -1059,15 +1012,11 @@ LITE_OS_SEC_TEXT STATIC UINT32 CheckRecievedMsg(IpcListNode *node, IpcContent *c
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (ret != LOS_OK) {
|
||||
#ifdef LOSCFG_KERNEL_TRACE
|
||||
IpcTrace(&node->msg, READ_DROP, tcb->ipcStatus, node->msg.type);
|
||||
#endif
|
||||
OsHookCall(LOS_HOOK_TYPE_IPC_READ_DROP, &node->msg, tcb->ipcStatus);
|
||||
(VOID)HandleSpecialObjects(LOS_CurTaskIDGet(), node, TRUE);
|
||||
(VOID)LiteIpcNodeFree(LOS_GetCurrProcessID(), (VOID *)node);
|
||||
} else {
|
||||
#ifdef LOSCFG_KERNEL_TRACE
|
||||
IpcTrace(&node->msg, READ, tcb->ipcStatus, node->msg.type);
|
||||
#endif
|
||||
OsHookCall(LOS_HOOK_TYPE_IPC_READ, &node->msg, tcb->ipcStatus);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -1087,24 +1036,18 @@ LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcRead(IpcContent *content)
|
||||
do {
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (LOS_ListEmpty(listHead)) {
|
||||
#ifdef LOSCFG_KERNEL_TRACE
|
||||
IpcTrace(NULL, TRY_READ, tcb->ipcStatus, syncFlag ? MT_REPLY : MT_REQUEST);
|
||||
#endif
|
||||
OsHookCall(LOS_HOOK_TYPE_IPC_TRY_READ, syncFlag ? MT_REPLY : MT_REQUEST, tcb->ipcStatus);
|
||||
tcb->ipcStatus |= IPC_THREAD_STATUS_PEND;
|
||||
OsTaskWaitSetPendMask(OS_TASK_WAIT_LITEIPC, OS_INVALID_VALUE, timeout);
|
||||
ret = OsSchedTaskWait(&g_ipcPendlist, timeout, TRUE);
|
||||
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
|
||||
#ifdef LOSCFG_KERNEL_TRACE
|
||||
IpcTrace(NULL, READ_TIMEOUT, tcb->ipcStatus, syncFlag ? MT_REPLY : MT_REQUEST);
|
||||
#endif
|
||||
OsHookCall(LOS_HOOK_TYPE_IPC_READ_TIMEOUT, syncFlag ? MT_REPLY : MT_REQUEST, tcb->ipcStatus);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
if (OsTaskIsKilled(tcb)) {
|
||||
#if (LOSCFG_KERNEL_TRACE == YES)
|
||||
IpcTrace(NULL, KILL, tcb->ipcStatus, syncFlag ? MT_REPLY : MT_REQUEST);
|
||||
#endif
|
||||
OsHookCall(LOS_HOOK_TYPE_IPC_KILL, syncFlag ? MT_REPLY : MT_REQUEST, tcb->ipcStatus);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return -ERFKILL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user