#include "precompile.h" #include "sp_dbg_export.h" #include "sp_gui_def.h" #include "sp_def.h" #include "sp_dir.h" #include "log.h" #include #include "fileutil.h" #include "memutil.h" #include #include "dbgutil.h" #define MAX_ERR_TRACE_MSG_LEN 512 #define MAX_ERR_TRACE_DEEP 100 typedef struct err_stack_item { char err_msg[MAX_ERR_TRACE_MSG_LEN]; } err_stack_item; typedef struct err_stack { err_stack_item* msgs[MAX_ERR_TRACE_DEEP]; int map_idx[MAX_ERR_TRACE_DEEP]; int cur_trace_idx; } err_stack; static err_stack* g_track; SPBASE_API void sp_trace_init() { if (!g_track) { int i = 0; g_track = MALLOC_T(err_stack); memset(g_track, 0, sizeof(err_stack)); g_track->cur_trace_idx = -1; for (i = 0; i < MAX_ERR_TRACE_DEEP; ++i) { g_track->map_idx[i] = -1; g_track->msgs[i] = NULL; } } } SPBASE_API void sp_trace_append(const char* str) { int i, len; len = strlen(str); if (g_track && str != NULL && len > 0) { int next_idx = g_track->cur_trace_idx + 1; if (!g_track->msgs[next_idx]) { g_track->msgs[next_idx] = MALLOC_T(err_stack_item); memset(g_track->msgs[next_idx], 0, sizeof(err_stack_item)); //TOOLKIT_ASSERT(g_track->map_idx[next_idx] == (char)-1); } strcpy(g_track->msgs[next_idx]->err_msg, str); len = len > MAX_ERR_TRACE_MSG_LEN - 1 ? MAX_ERR_TRACE_MSG_LEN - 1 : len; g_track->msgs[next_idx]->err_msg[len] = '\0'; for (i = MAX_ERR_TRACE_DEEP - 1; i >= 1; i--) { g_track->map_idx[i] = g_track->map_idx[i - 1]; } g_track->map_idx[0] = next_idx; g_track->cur_trace_idx++; if (g_track->cur_trace_idx == MAX_ERR_TRACE_DEEP - 1) g_track->cur_trace_idx = -1; } } SPBASE_API void sp_trace_retrieve(char** trace_ptr, uint32_t* trace_cnt) { int i; size_t len; if (trace_ptr && g_track) { for (len = 0, i = 0; i < MAX_ERR_TRACE_DEEP; i++) { const int idx = g_track->map_idx[i]; if (idx != -1) { len += (strlen(g_track->msgs[idx]->err_msg) + strlen("\n")); } } if (len > 0) { char* content = CALLOC_T((len), char); for (i = 0; i < MAX_ERR_TRACE_DEEP; ++i) { const int idx = g_track->map_idx[i]; if (idx != -1) { if (i != 0) strcat(content, "\n"); strcat(content, g_track->msgs[idx]->err_msg); } } content[len - 1] = '\0'; if (trace_ptr) { *trace_ptr = content; } else FREE(content); if (trace_cnt) { *trace_cnt = len; } } } } SPBASE_API void sp_trace_term() { if (g_track) { int i; for (i = 0; i < MAX_ERR_TRACE_DEEP; ++i) { if (g_track->msgs[i]) { FREE(g_track->msgs[i]); } } FREE(g_track); } } SPBASE_API int sp_trace_exist() { return (g_track != NULL); }