mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-29 18:48:09 +08:00
improve debugger
This commit is contained in:
parent
c69c4e5a9d
commit
5edd18f480
@ -1,4 +1,8 @@
|
||||
# 最新动态
|
||||
|
||||
2024/08/15
|
||||
* 修改debugger_lldb_get_callstack_ex增加tid的参数并且增加fdb的测试例子(感谢智明提供补丁)
|
||||
|
||||
2024/08/14
|
||||
* fix fscript_math.md
|
||||
* 完善ui test支持保存变量和表达式
|
||||
|
@ -198,11 +198,11 @@ tk_object_t* debugger_get_callstack(debugger_t* debugger) {
|
||||
return debugger->vt->get_callstack(debugger);
|
||||
}
|
||||
|
||||
tk_object_t* debugger_get_callstack_ex(debugger_t* debugger, uint32_t start, uint32_t levels) {
|
||||
tk_object_t* debugger_get_callstack_ex(debugger_t* debugger, uint32_t start, uint32_t levels, uint64_t thread_id) {
|
||||
return_value_if_fail(debugger != NULL && debugger->vt != NULL, NULL);
|
||||
return_value_if_fail(debugger->vt->get_callstack_ex != NULL, NULL);
|
||||
|
||||
return debugger->vt->get_callstack_ex(debugger, start, levels);
|
||||
return debugger->vt->get_callstack_ex(debugger, start, levels, thread_id);
|
||||
}
|
||||
|
||||
ret_t debugger_clear_break_points(debugger_t* debugger) {
|
||||
|
@ -77,7 +77,7 @@ typedef tk_object_t* (*debugger_get_local_t)(debugger_t* debugger, uint32_t fram
|
||||
typedef tk_object_t* (*debugger_get_self_t)(debugger_t* debugger);
|
||||
typedef tk_object_t* (*debugger_get_global_t)(debugger_t* debugger);
|
||||
typedef tk_object_t* (*debugger_get_callstack_t)(debugger_t* debugger);
|
||||
typedef tk_object_t* (*debugger_get_callstack_ex_t)(debugger_t* debugger, uint32_t start, uint32_t levels);
|
||||
typedef tk_object_t* (*debugger_get_callstack_ex_t)(debugger_t* debugger, uint32_t start, uint32_t levels, uint64_t thread_id);
|
||||
typedef ret_t (*debugger_clear_break_points_t)(debugger_t* debugger);
|
||||
typedef ret_t (*debugger_set_break_point_t)(debugger_t* debugger, uint32_t line);
|
||||
typedef ret_t (*debugger_remove_break_point_t)(debugger_t* debugger, uint32_t line);
|
||||
@ -368,13 +368,17 @@ tk_object_t* debugger_get_callstack(debugger_t* debugger);
|
||||
/**
|
||||
* @method debugger_get_callstack_ex
|
||||
* 获取当前线程的callstack。
|
||||
* 备注:
|
||||
* 1,如果 tk_object_t 的 callstack.#size 返回来的长度小于 levels 的话,就已经全部拿完了。
|
||||
* 2,返回值和 debugger_get_callstack 是一样的。
|
||||
* @param {debugger_t*} debugger debugger对象。
|
||||
* @param {uint32_t} start 堆栈 startFrame。
|
||||
* @param {uint32_t} levels 堆栈层数。
|
||||
* @param {uint32_t} levels 堆栈层数。(如果是输入 0 的话,就获取最大层数)
|
||||
* @param {uint64_t} thread_id 线程 id。
|
||||
*
|
||||
* @return {tk_object_t*} 返回堆栈信息。
|
||||
*/
|
||||
tk_object_t* debugger_get_callstack_ex(debugger_t* debugger, uint32_t start, uint32_t levels);
|
||||
tk_object_t* debugger_get_callstack_ex(debugger_t* debugger, uint32_t start, uint32_t levels, uint64_t thread_id);
|
||||
|
||||
/**
|
||||
* @method debugger_clear_break_points
|
||||
|
@ -94,7 +94,8 @@
|
||||
#define LLDB_KEY_STOPFORDESTROYORDETACH "StopForDestroyOrDetach"
|
||||
|
||||
#define LLDB_CALLSTCK_DEFAULT_STARTFRAME 0
|
||||
#define LLDB_CALLSTCK_DEFAULT_LEVELS 100
|
||||
// 获取全部层数
|
||||
#define LLDB_CALLSTCK_DEFAULT_LEVELS 0
|
||||
|
||||
#define VARREF_LOCALS (int64_t)1
|
||||
#define VARREF_GLOBALS (int64_t)2
|
||||
@ -107,6 +108,8 @@ static ret_t debugger_lldb_simple_command(debugger_t* debugger, const char* cmd)
|
||||
static ret_t debugger_lldb_disconnect(debugger_t* debugger, bool_t terminate_debuggee);
|
||||
static tk_object_t* debugger_lldb_get_callstack_impl(debugger_t* debugger, uint32_t start_frame,
|
||||
uint32_t levels);
|
||||
static tk_object_t* debugger_lldb_get_callstack_for_tid_impl(debugger_t* debugger, uint32_t start_frame,
|
||||
uint32_t levels, int64_t thread_id);
|
||||
static tk_object_t* object_find_variable_value(tk_object_t* obj, const char* name,
|
||||
const char* full_name);
|
||||
|
||||
@ -250,7 +253,7 @@ static ret_t debugger_lldb_set_current_thread_id_ex(debugger_t* debugger, uint64
|
||||
debugger_unlock(debugger);
|
||||
}
|
||||
if (swith) {
|
||||
lldb->callstack = debugger_lldb_get_callstack_impl(debugger, 0, 100);
|
||||
lldb->callstack = debugger_lldb_get_callstack_impl(debugger, LLDB_CALLSTCK_DEFAULT_STARTFRAME, LLDB_CALLSTCK_DEFAULT_LEVELS);
|
||||
debugger_set_state(debugger, DEBUGGER_PROGRAM_STATE_PAUSED);
|
||||
debugger_set_current_frame(debugger, 0);
|
||||
}
|
||||
@ -261,18 +264,23 @@ static ret_t debugger_lldb_set_current_thread_id(debugger_t* debugger, uint64_t
|
||||
return debugger_lldb_set_current_thread_id_ex(debugger, thread_id, FALSE);
|
||||
}
|
||||
|
||||
static tk_object_t* debugger_lldb_get_callstack_ex_obj(debugger_t* debugger, uint32_t start, uint32_t levels) {
|
||||
static tk_object_t* debugger_lldb_get_callstack_for_tid_obj(debugger_t* debugger, uint32_t start, uint32_t levels, int64_t tid, bool_t no_cache) {
|
||||
debugger_lldb_t* lldb = DEBUGGER_LLDB(debugger);
|
||||
|
||||
if (lldb->callstack == NULL) {
|
||||
lldb->callstack = debugger_lldb_get_callstack_impl(debugger, start, levels);
|
||||
if (no_cache) {
|
||||
return debugger_lldb_get_callstack_for_tid_impl(debugger, start, levels, tid);
|
||||
} else if (lldb->callstack == NULL) {
|
||||
lldb->callstack = debugger_lldb_get_callstack_for_tid_impl(debugger, start, levels, tid);
|
||||
}
|
||||
|
||||
return lldb->callstack;
|
||||
}
|
||||
|
||||
static tk_object_t* debugger_lldb_get_callstack_obj(debugger_t* debugger) {
|
||||
return debugger_lldb_get_callstack_ex_obj(debugger, LLDB_CALLSTCK_DEFAULT_STARTFRAME, LLDB_CALLSTCK_DEFAULT_LEVELS);
|
||||
uint64_t thread_id = 0;
|
||||
return_value_if_fail(debugger != NULL, NULL);
|
||||
thread_id = debugger_lldb_get_current_thread_id(debugger);
|
||||
return debugger_lldb_get_callstack_for_tid_obj(debugger, LLDB_CALLSTCK_DEFAULT_STARTFRAME, LLDB_CALLSTCK_DEFAULT_LEVELS, thread_id, FALSE);
|
||||
}
|
||||
|
||||
static const char* debugger_lldb_get_source_path(debugger_t* debugger, uint32_t frame_index) {
|
||||
@ -929,10 +937,9 @@ static ret_t debugger_lldb_update_func_break_points(debugger_t* debugger) {
|
||||
}
|
||||
|
||||
static tk_object_t* debugger_lldb_create_get_callstack_req(debugger_t* debugger,
|
||||
uint32_t start_frame, uint32_t levels) {
|
||||
uint32_t start_frame, uint32_t levels, int64_t thread_id ) {
|
||||
tk_object_t* req = NULL;
|
||||
tk_object_t* arguments = NULL;
|
||||
int64_t thread_id = debugger_lldb_get_current_thread_id(debugger);
|
||||
|
||||
req = object_default_create();
|
||||
return_value_if_fail(req != NULL, NULL);
|
||||
@ -951,12 +958,12 @@ static tk_object_t* debugger_lldb_create_get_callstack_req(debugger_t* debugger,
|
||||
return req;
|
||||
}
|
||||
|
||||
static tk_object_t* debugger_lldb_get_callstack_impl(debugger_t* debugger, uint32_t start_frame,
|
||||
uint32_t levels) {
|
||||
static tk_object_t* debugger_lldb_get_callstack_for_tid_impl(debugger_t* debugger, uint32_t start_frame,
|
||||
uint32_t levels, int64_t thread_id) {
|
||||
tk_object_t* req = NULL;
|
||||
tk_object_t* resp = NULL;
|
||||
return_value_if_fail(debugger != NULL, NULL);
|
||||
req = debugger_lldb_create_get_callstack_req(debugger, start_frame, levels);
|
||||
req = debugger_lldb_create_get_callstack_req(debugger, start_frame, levels, thread_id);
|
||||
return_value_if_fail(req != NULL, NULL);
|
||||
|
||||
if (debugger_lldb_write_req(debugger, req) == RET_OK) {
|
||||
@ -968,6 +975,14 @@ static tk_object_t* debugger_lldb_get_callstack_impl(debugger_t* debugger, uint3
|
||||
return resp;
|
||||
}
|
||||
|
||||
static tk_object_t* debugger_lldb_get_callstack_impl(debugger_t* debugger, uint32_t start_frame,
|
||||
uint32_t levels) {
|
||||
uint64_t thread_id = 0;
|
||||
return_value_if_fail(debugger != NULL, NULL);
|
||||
thread_id = debugger_lldb_get_current_thread_id(debugger);
|
||||
return debugger_lldb_get_callstack_for_tid_impl(debugger, start_frame, levels, thread_id);
|
||||
}
|
||||
|
||||
static tk_object_t* debugger_lldb_create_get_variables_req(debugger_t* debugger, uint32_t type,
|
||||
uint32_t start, uint32_t count) {
|
||||
tk_object_t* req = NULL;
|
||||
@ -1334,7 +1349,7 @@ static tk_object_t* debugger_lldb_get_global(debugger_t* debugger) {
|
||||
return debugger_lldb_get_variables_impl(debugger, VARREF_GLOBALS, 0, 0);
|
||||
}
|
||||
|
||||
static tk_object_t* debugger_lldb_get_callstack_ex(debugger_t* debugger, uint32_t start, uint32_t levels) {
|
||||
static tk_object_t* debugger_lldb_get_callstack_ex_impl(debugger_t* debugger, uint32_t start, uint32_t levels, uint64_t thread_id, bool_t no_cache) {
|
||||
int32_t i = 0;
|
||||
int32_t n = 0;
|
||||
uint32_t num = 0;
|
||||
@ -1345,7 +1360,7 @@ static tk_object_t* debugger_lldb_get_callstack_ex(debugger_t* debugger, uint32_
|
||||
return_value_if_fail(lldb != NULL, NULL);
|
||||
|
||||
debugger_lldb_dispatch_messages(debugger, 10, &num);
|
||||
callstack = debugger_lldb_get_callstack_ex_obj(debugger, start, levels);
|
||||
callstack = debugger_lldb_get_callstack_for_tid_obj(debugger, start, levels, thread_id, no_cache);
|
||||
return_value_if_fail(callstack != NULL, NULL);
|
||||
|
||||
ret_obj = conf_ubjson_create();
|
||||
@ -1378,8 +1393,15 @@ static tk_object_t* debugger_lldb_get_callstack_ex(debugger_t* debugger, uint32_
|
||||
return ret_obj;
|
||||
}
|
||||
|
||||
static tk_object_t* debugger_lldb_get_callstack_ex(debugger_t* debugger, uint32_t start, uint32_t levels, uint64_t thread_id) {
|
||||
return debugger_lldb_get_callstack_ex_impl(debugger, start, levels, thread_id, TRUE);
|
||||
}
|
||||
|
||||
static tk_object_t* debugger_lldb_get_callstack(debugger_t* debugger) {
|
||||
return debugger_lldb_get_callstack_ex(debugger, LLDB_CALLSTCK_DEFAULT_STARTFRAME, LLDB_CALLSTCK_DEFAULT_LEVELS);
|
||||
uint64_t thread_id = 0;
|
||||
return_value_if_fail(debugger != NULL, NULL);
|
||||
thread_id = debugger_lldb_get_current_thread_id(debugger);
|
||||
return debugger_lldb_get_callstack_ex_impl(debugger, LLDB_CALLSTCK_DEFAULT_STARTFRAME, LLDB_CALLSTCK_DEFAULT_LEVELS, thread_id, FALSE);
|
||||
}
|
||||
|
||||
static ret_t debugger_lldb_update_break_points(debugger_t* debugger) {
|
||||
|
@ -162,7 +162,7 @@ static ret_t fdb_show_threads(const char* title, tk_object_t* obj) {
|
||||
log_debug("---------------------\n");
|
||||
if (obj != NULL) {
|
||||
uint32_t i = 0;
|
||||
int32_t id = 0;
|
||||
uint64_t id = 0;
|
||||
const char* name = NULL;
|
||||
char path[MAX_PATH + 1] = {0};
|
||||
uint32_t n = tk_object_get_prop_uint32(obj, "body.threads.#size", 0);
|
||||
@ -172,9 +172,9 @@ static ret_t fdb_show_threads(const char* title, tk_object_t* obj) {
|
||||
name = tk_object_get_prop_str(obj, path);
|
||||
|
||||
tk_snprintf(path, sizeof(path) - 1, "body.threads.[%d].id", i);
|
||||
id = tk_object_get_prop_int32(obj, path, 0);
|
||||
id = tk_object_get_prop_uint64(obj, path, 0);
|
||||
|
||||
log_debug("[%d]: %s\n", id, name);
|
||||
log_debug("[%llu]: %s\n", id, name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -397,7 +397,9 @@ static ret_t func_pause(app_info_t* app, tokenizer_t* tokenizer) {
|
||||
}
|
||||
|
||||
static ret_t func_stop(app_info_t* app, tokenizer_t* tokenizer) {
|
||||
tk_object_t* obj = TK_OBJECT(app->debugger);
|
||||
debugger_stop(app->debugger);
|
||||
TK_OBJECT_UNREF(obj);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
@ -458,10 +460,15 @@ static ret_t func_list_debuggers(app_info_t* app, tokenizer_t* tokenizer) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fdb_show_callstack(app_info_t* app) {
|
||||
static ret_t fdb_show_callstack(app_info_t* app, uint32_t start, uint32_t level, bool_t is_ex) {
|
||||
int32_t i = 0, n = 0;
|
||||
tk_object_t* obj = debugger_get_callstack(app->debugger);
|
||||
return_value_if_fail(obj != NULL, RET_BAD_PARAMS);
|
||||
if (is_ex) {
|
||||
obj = debugger_get_callstack_ex(app->debugger, start, level, debugger_get_current_thread_id(app->debugger));
|
||||
} else {
|
||||
obj = debugger_get_callstack(app->debugger);
|
||||
}
|
||||
|
||||
log_debug("thread_id:%lld callstack:\n---------------------------\n",
|
||||
debugger_get_current_thread_id(app->debugger));
|
||||
@ -513,13 +520,15 @@ static ret_t fdb_show_callstack(app_info_t* app) {
|
||||
}
|
||||
|
||||
static ret_t func_backtrace(app_info_t* app, tokenizer_t* tokenizer) {
|
||||
fdb_show_callstack(app);
|
||||
int32_t level = tokenizer_next_int(tokenizer, -1);
|
||||
bool_t is_ex = level >= 0;
|
||||
fdb_show_callstack(app, 0, level, is_ex);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t func_set_thread_id(app_info_t* app, tokenizer_t* tokenizer) {
|
||||
int32_t thread_id = tokenizer_next_int(tokenizer, -1);
|
||||
uint64_t thread_id = tokenizer_next_int64(tokenizer, -1);
|
||||
if (thread_id >= 0) {
|
||||
ret_t ret = RET_OK;
|
||||
bool_t find = FALSE;
|
||||
@ -528,10 +537,10 @@ static ret_t func_set_thread_id(app_info_t* app, tokenizer_t* tokenizer) {
|
||||
n = tk_object_get_prop_uint32(obj, "body.threads.#size", 0);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
int32_t id = 0;
|
||||
uint64_t id = 0;
|
||||
char path[MAX_PATH + 1] = {0};
|
||||
tk_snprintf(path, sizeof(path) - 1, "body.threads.[%d].id", i);
|
||||
id = tk_object_get_prop_int32(obj, path, 0);
|
||||
id = tk_object_get_prop_uint64(obj, path, 0);
|
||||
if (thread_id == id) {
|
||||
find = TRUE;
|
||||
break;
|
||||
@ -540,7 +549,7 @@ static ret_t func_set_thread_id(app_info_t* app, tokenizer_t* tokenizer) {
|
||||
if (find) {
|
||||
ret = debugger_set_current_thread_id(app->debugger, thread_id);
|
||||
return_value_if_fail(ret == RET_OK, ret);
|
||||
return fdb_show_callstack(app);
|
||||
return fdb_show_callstack(app, 0, 0, FALSE);
|
||||
} else {
|
||||
log_debug("not found thread id, set fail ! \r\n");
|
||||
return RET_NOT_FOUND;
|
||||
@ -612,6 +621,14 @@ static ret_t func_frame(app_info_t* app, tokenizer_t* tokenizer) {
|
||||
}
|
||||
}
|
||||
|
||||
static ret_t func_get_curr_frame(app_info_t* app, tokenizer_t* tokenizer) {
|
||||
uint64_t thread_id = debugger_get_current_thread_id(app->debugger);
|
||||
int32_t frame = debugger_get_current_frame(app->debugger);
|
||||
log_debug("thread_id:%llu, frame:%d", thread_id, frame);
|
||||
log_debug("\n");
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t func_get_code(app_info_t* app, tokenizer_t* tokenizer) {
|
||||
fdb_show_code(app, FALSE);
|
||||
return RET_OK;
|
||||
@ -628,6 +645,7 @@ static const cmd_entry_t s_cmds[] = {
|
||||
{"run", "r", "run a program", "r program arg1 arg2...", func_launch},
|
||||
{"print", "p", "show a var, support path(eg: a.b[1].name).", "p name", func_print},
|
||||
{"frame", "f", "select current frame", "f index", func_frame},
|
||||
{"get_frame", "gf", "get current frame", "gf", func_get_curr_frame},
|
||||
{"flush", "fl", "flush socket", "fl", func_flush},
|
||||
{"next", "n", "run next line code", "n", func_next},
|
||||
{"pause", "ps", "pause the running program", "pause", func_pause},
|
||||
@ -646,7 +664,7 @@ static const cmd_entry_t s_cmds[] = {
|
||||
{"global", "global", "show global variables", "global", func_global},
|
||||
{"threads", "threads", "show threads", "threads", func_threads},
|
||||
{"set_thread", "st", "set curr thread id", "st id", func_set_thread_id},
|
||||
{"backtrace", "bt", "show backtrace", "bt", func_backtrace},
|
||||
{"backtrace (level)", "bt", "show backtrace (level)", "bt (level)", func_backtrace},
|
||||
{"quit", "q", "Quit debugger", "q", func_quit},
|
||||
{"restart", "rs", "restart app", "rs", func_restart},
|
||||
{"config", "conf", "load config", "conf lldb.json", func_config},
|
||||
|
Loading…
Reference in New Issue
Block a user