yb_arm/osp/src/ospDbg.c
lishuang.xie 5a4df32dec update dev_ck_v2.1_feature#1627# to dev_ck_v2.1
1. delete call osp_signal_init()
2. Test:
   2.1 spu_case0_arm_case0_cpri:      Pass
   2.2 spu_case14_arm_case20_cpri:    Pass
   2.3 spu_case20_arm_case20_cpri:    Pass
   2.4 spu_case21_arm_case21_cpri:    Pass
   2.5 spu_case34_arm_case5:          Pass
   2.6 spu_case44_arm_case5:         Pass
   2.7 spu_case20_arm_case20_task_ok: Pass
   2.8 spu_case20_arm_case20_task_ng: Pass
2024-01-29 09:44:38 +08:00

628 lines
13 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <termios.h>
#define _GNU_SOURCE
#include <dlfcn.h>
#include <signal.h>
#include <stdarg.h>
#include <execinfo.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "osp.h"
#define IOSIZE (32*1024*1024)
void *g_SemDeadFunc;
int32_t osp_signal_init(void);
uint32_t *gOspPrintLevel = NULL;
/*keep DbgOut with order !*/
void *g_DbgOutSem = 0;
char DbgBuf[MAX_DBGINFO_LEN] = {0};
static OSP_FUNCPTR gpfunc[DeadFuncNum] = {0};
int32_t osp_task_dbg_out_enable(uint32_t taskid)
{
gOspTask[taskid].dbg_out_is_enable = 1;
return 0;
}
int32_t osp_task_dbg_out_disable(uint32_t taskid)
{
gOspTask[taskid].dbg_out_is_enable = 0;
return 0;
}
int32_t osp_task_dbg_out_enable_all(void)
{
int32_t i;
for (i = 0; i < OSP_MAX_TASK; i++)
{
if (gOspTask[i].Active)
{
osp_task_dbg_out_enable(i);
}
}
return OSP_OK;
}
int32_t osp_task_dbg_out_disable_all(void)
{
int32_t i;
for (i = 0; i < OSP_MAX_TASK; i++)
{
if (gOspTask[i].Active)
{
osp_task_dbg_out_disable(i);
}
}
return OSP_OK;
}
int32_t osp_task_dbg_is_log(uint32_t taskid)
{
return gOspTask[taskid].dbg_out2log_is_enable;
}
int32_t osp_task_dbg_out2log_disable_all(void)
{
int32_t i;
for (i = 0; i < OSP_MAX_TASK; i++)
{
if (gOspTask[i].Active)
{
osp_task_dbg_out2log_disable(i);
}
}
return OSP_OK;
}
int32_t osp_task_dbg_out2log_disable(uint32_t taskid)
{
gOspTask[taskid].dbg_out2log_is_enable = 0;
return 0;
}
int32_t osp_task_dbg_out2log_enable_all(void)
{
int32_t i;
for (i = 0; i < OSP_MAX_TASK; i++)
{
if (!osp_task_is_shell(i))
osp_task_dbg_out2log_enable(i);
}
return OSP_OK;
}
int32_t osp_task_dbg_out2log_enable(uint32_t taskid)
{
gOspTask[taskid].dbg_out2log_is_enable = 1;
return 0;
}
int32_t osp_task_dbg_out_is_enable(uint32_t taskid)
{
return gOspTask[taskid].dbg_out_is_enable;
}
void osp_local_shell_out_main(Osp_Msg_Head *pMsg)
{
if (osp_local_shell_task_is_reged())
{
osp_print(MSG_HEAD_TO_COMM(pMsg), MSG_DADA_LEN(pMsg));
}
//osp_net_shell_out(pMsg);
osp_free_msg(pMsg);
}
void osp_debug_out_set_level(int32_t level)
{
*gOspPrintLevel = level;
}
OSP_STATUS osp_debug_out(int32_t level, char *fmt,...)
{
va_list vl;
Osp_Msg_Head *pMsg;
int32_t buflen = 0;
if (!osp_is_init_done())
{
/*to makesure osp_debug_out can be useful anytime*/
char *pbuf = malloc(MAX_DBGINFO_LEN);
if (NULL != pbuf)
{
va_start(vl, fmt);
buflen = vsnprintf(pbuf + buflen, MAX_DBGINFO_LEN - buflen, fmt, vl);
va_end(vl);
printf("%s\n", pbuf);
free(pbuf);
}
return OSP_OK;
}
if ((NULL == gOspPrintLevel) && (*gOspPrintLevel < level))
return (OSP_ERROR);
if (!osp_task_dbg_out_is_enable(CURRENT_TASKID))
return (OSP_ERROR);
if (NULL == g_DbgOutSem)
{
return OSP_ERROR;
}
osp_sem_take(g_DbgOutSem, -1);
if ((osp_task_dbg_is_log(CURRENT_TASKID)) && (CMD_DEBUG_LEVEL != level))
{
char *pbuf = DbgBuf;
va_start(vl, fmt);
buflen = vsnprintf(pbuf, MAX_DBGINFO_LEN, fmt, vl);
va_end(vl);
pbuf[buflen] = '\0';
osp_dbg_log(pbuf, buflen);
osp_sem_give(g_DbgOutSem);
return OSP_OK;
}
pMsg = osp_alloc_msg_print_log();
if (NULL == pMsg)
{
/*to makesure osp_debug_out can be useful anytime*/
char *pbuf = DbgBuf;
va_start(vl, fmt);
buflen = vsnprintf(pbuf, MAX_DBGINFO_LEN, fmt, vl);
va_end(vl);
printf("%s", pbuf);
osp_sem_give(g_DbgOutSem);
return OSP_ERROR;
}
va_start(vl, fmt);
buflen = vsnprintf(MSG_HEAD_TO_COMM(pMsg), MAX_DBGINFO_LEN, fmt, vl);
va_end(vl);
pMsg->DstId = localshellout;
pMsg->SrcId = CURRENT_TASKID;
pMsg->MsgSize = buflen + MSG_HEAD_SIZE;
osp_send_msg(pMsg);
osp_sem_give(g_DbgOutSem);
return (OSP_OK);
}
OSP_STATUS osp_debug_out_with_time(int32_t level, char *fmt,...)
{
va_list vl;
Osp_Msg_Head *pMsg;
int32_t buflen = 0;
OSP_RTCTIME osptime;
if (!osp_is_init_done())
{
/*to makesure osp_debug_out can be useful anytime*/
char *pbuf = malloc(MAX_DBGINFO_LEN);
if (NULL != pbuf)
{
osp_get_rtc_time(&osptime);
buflen = snprintf((char *)pbuf, (size_t)(MAX_DBGINFO_LEN), \
"[%04d/%02d/%02d-%02d:%02d:%02d:%02d]", \
osptime.year, osptime.month, osptime.day, \
osptime.hour, osptime.minute, osptime.second, osptime.usecond);
va_start(vl, fmt);
buflen = vsnprintf(pbuf+buflen, MAX_DBGINFO_LEN-buflen, fmt, vl);
va_end(vl);
printf("%s", pbuf);
free(pbuf);
}
return OSP_OK;
}
if ((gOspPrintLevel) && (*gOspPrintLevel < level))
{
return (OSP_ERROR);
}
if (!osp_task_dbg_out_is_enable(CURRENT_TASKID))
{
return (OSP_ERROR);
}
if (NULL == g_DbgOutSem)
{
return OSP_ERROR;
}
osp_sem_take(g_DbgOutSem, -1);
if (osp_task_dbg_is_log(CURRENT_TASKID))
{
char *pbuf = DbgBuf;
/*to makesure osp_debug_out_with_time can be useful anytime*/
osp_get_rtc_time(&osptime);
buflen = snprintf((char *)pbuf, (size_t)(MAX_DBGINFO_LEN), \
"[%04d/%02d/%02d-%02d:%02d:%02d:%02d]", \
osptime.year, osptime.month, osptime.day, \
osptime.hour, osptime.minute, osptime.second, osptime.usecond);
va_start(vl, fmt);
buflen += vsnprintf(pbuf+buflen, MAX_DBGINFO_LEN, fmt, vl);
va_end(vl);
pbuf[buflen] = '\0';
osp_dbg_log(pbuf, buflen);
osp_sem_give(g_DbgOutSem);
return OSP_OK;
}
pMsg = osp_alloc_msg_print_log();
if (NULL == pMsg)
{
/*to makesure osp_debug_out_with_time can be useful anytime*/
char *pbuf = DbgBuf;
osp_get_rtc_time(&osptime);
buflen = snprintf((char *)pbuf, (size_t)(MAX_DBGINFO_LEN), \
"[%04d/%02d/%02d-%02d:%02d:%02d:%02d]", \
osptime.year, osptime.month, osptime.day, \
osptime.hour, osptime.minute, osptime.second, osptime.usecond);
va_start(vl, fmt);
buflen = vsnprintf(pbuf + buflen, MAX_DBGINFO_LEN, fmt, vl);
va_end(vl);
printf("%s",pbuf);
osp_sem_give(g_DbgOutSem);
return OSP_OK;
}
osp_get_rtc_time(&osptime);
buflen = snprintf((char *)MSG_HEAD_TO_COMM(pMsg), (size_t)(MAX_DBGINFO_LEN), \
"[%04d/%02d/%02d-%02d:%02d:%02d:%02d]", \
osptime.year, osptime.month, osptime.day, \
osptime.hour, osptime.minute, osptime.second, osptime.usecond);
va_start(vl, fmt);
buflen += vsnprintf(MSG_HEAD_TO_COMM(pMsg) + buflen, MAX_DBGINFO_LEN - buflen, fmt, vl);
va_end(vl);
pMsg->DstId = localshellout;
pMsg->SrcId = CURRENT_TASKID;
pMsg->MsgSize = buflen + MSG_HEAD_SIZE;
osp_send_msg(pMsg);
osp_sem_give(g_DbgOutSem);
return (OSP_OK);
}
OSP_STATUS osp_print(char *pbuf, uint32_t len)
{
if ((NULL == pbuf) || (0 == len))
{
return OSP_ERROR;
}
printf("%s", pbuf);
fflush(stdout);
return OSP_OK;
}
int32_t osp_shell_dis_mem(int32_t num, uint64_t addr)
{
uint32_t *p = (uint32_t *)addr;
int32_t i;
char *pbuf;
int32_t len = 0;
if (NULL == p)
{
return -1;
}
if ((num * 4) > MAX_DBGINFO_LEN)
{
osp_debug_out(CMD_DEBUG_LEVEL, "mux display memsize : %d\r\n", (MAX_DBGINFO_LEN / 4));
return -1;
}
pbuf = malloc(MAX_DBGINFO_LEN);
if (NULL == pbuf)
{
return -1;
}
for (i = 0; i < num; i++)
{
if ((i & 0x3) == 0)
len += sprintf(pbuf + len, "%p : \t", p+i);
len += sprintf(pbuf + len, "0x%08x\t", p[i]);
if ((i & 0x3) == 0x3)
len += sprintf(pbuf + len, "%c", '\n');
}
pbuf[len] = '\0';
osp_debug_out(CMD_DEBUG_LEVEL, "%s", pbuf);
free(pbuf);
return OSP_OK;
}
int32_t osp_shell_set_mem(int32_t val, uint64_t addr)
{
uint32_t *p = (uint32_t *)addr;
if (NULL == p)
return -1;
*p = val;
return OSP_OK;
}
int32_t osp_local_shell_in_main()
{
return OSP_OK;
}
void osp_debug_init(void)
{
g_DbgOutSem = osp_get_init_mem(sizeof(lx_sem_t));
gOspPrintLevel = (uint32_t *)osp_get_init_mem(sizeof(uint32_t));
if (0 == g_ProcessId)
{
*gOspPrintLevel = DBG_DEBUG_LEVEL;
osp_semsm_create(g_DbgOutSem);
}
//osp_signal_init();
}
void osp_signal_action_trace(int32_t nr, siginfo_t *info, void *void_context)
{
void *trace[100] = {0};
int32_t trace_size = 0;
char **messages = NULL;
int32_t i;
trace_size = backtrace(trace, 100);
messages = (char **)backtrace_symbols(trace, trace_size);
for (i = 0; i < trace_size; ++i)
{
osp_debug_out(CMD_DEBUG_LEVEL, "[bt] %s\n", messages[i]);
}
return;
}
void osp_signal_action_suspend(int32_t nr, siginfo_t *info, void *void_context)
{
sigset_t SigSet;
int32_t Sig;
(void)sigemptyset(&SigSet);
(void)sigaddset(&SigSet,OSP_TASK_SIGNAL_RESUME);
// osp_debug_out(CMD_DEBUG_LEVEL, "task:%d suspend\n", CURRENT_TASKID);
TASK_STATE(CURRENT_TASKID)= TASK_SUSPEND;
(void)sigwait(&SigSet, &Sig);
TASK_STATE(CURRENT_TASKID)= TASK_RUNNING;
// osp_debug_out(CMD_DEBUG_LEVEL, "task:%d resume\n", CURRENT_TASKID);
}
void osp_signal_action_resume(int32_t nr, siginfo_t *info, void *void_context)
{
}
void osp_signal_action_except(int32_t nr, siginfo_t *info, void *void_context)
{
osp_assert(0);
}
int32_t osp_signal_init(void)
{
struct sigaction act;
act.sa_sigaction = &osp_signal_action_trace;
act.sa_flags = SA_SIGINFO;
if (sigaction(OSP_TASK_SIGNAL_TRACE, &act, NULL) < 0) {
osp_assert(0);
}
act.sa_sigaction = &osp_signal_action_suspend;
act.sa_flags = SA_SIGINFO;
if (sigaction(OSP_TASK_SIGNAL_SUSPEND, &act, NULL) < 0) {
osp_assert(0);
}
act.sa_sigaction = &osp_signal_action_resume;
act.sa_flags = SA_SIGINFO;
if (sigaction(OSP_TASK_SIGNAL_RESUME, &act, NULL) < 0) {
osp_assert(0);
}
act.sa_sigaction = &osp_signal_action_except ;
act.sa_flags = SA_SIGINFO;
if (sigaction(OSP_TASK_SIGNAL_SEGV, &act, NULL) < 0) {
osp_assert(0);
}
act.sa_sigaction = &osp_signal_action_except ;
act.sa_flags = SA_SIGINFO;
if (sigaction(OSP_TASK_SIGNAL_BUSSERR, &act, NULL) < 0) {
osp_assert(0);
}
signal(SIGTTOU, SIG_IGN);
g_SemDeadFunc = osp_semm_create();
return OSP_OK;
}
int32_t osp_trace_task(uint32_t Id)
{
if (gOspTask[Id].PhreadId)
{
(void)pthread_kill(TASK_THREADID(Id),OSP_TASK_SIGNAL_TRACE);
}
return OSP_OK;
}
int32_t osp_suspend_task(uint32_t Id)
{
if (gOspTask[Id].PhreadId)
{
(void)pthread_kill(TASK_THREADID(Id),OSP_TASK_SIGNAL_SUSPEND);
}
return OSP_ERROR;
}
int32_t osp_resume_task(uint32_t Id)
{
if (gOspTask[Id].PhreadId)
{
(void)pthread_kill(TASK_THREADID(Id),OSP_TASK_SIGNAL_RESUME);
}
return OSP_ERROR;
}
void osp_set_dbg_cmdlev(void)
{
osp_debug_out_set_level(CMD_DEBUG_LEVEL);
}
void osp_set_dbg_errlev(void)
{
osp_debug_out_set_level(ERR_DEBUG_LEVEL);
}
void osp_set_dbg_crunlev(void)
{
osp_debug_out_set_level(RUN_DEBUG_LEVEL);
}
void osp_set_dbg_cwarlev(void)
{
osp_debug_out_set_level(WARNING_DEBUG_LEVEL);
}
int32_t osp_reg_dead_func(OSP_FUNCPTR pfunc)
{
osp_sem_take(g_SemDeadFunc, -1);
{
static int32_t num = 0;
if ((NULL == pfunc)||(num == (DeadFuncNum-1)))
{
osp_sem_give(g_SemDeadFunc);
return OSP_ERROR;
}
gpfunc[num++] = pfunc;
osp_sem_give(g_SemDeadFunc);
return 0 ;
}
}
void osp_run_dead_func(void)
{
int32_t i=0;
for (i = 0; i < DeadFuncNum; i++)
{
if (gpfunc[i])
gpfunc[i]();
else
break;
}
osp_debug_out_with_time(CMD_DEBUG_LEVEL,"%d DeadFunc called!\r\n", i);
}
void osp_assert(int32_t val)
{
if (val == 0)
{
osp_run_dead_func();
/*to make sure deadmsg has been recorded! anyway this shuld to change in reliable way,todoa*/
usleep(100);
osp_trace_task(CURRENT_TASKID);
osp_fflush_all_logfile();
osp_suspend_task(CURRENT_TASKID);
while (1);
}
}