#include #include #include #include #include #include #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #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); } }