From 09d84c9dff152daf30629cb07f90d45e97d47eca Mon Sep 17 00:00:00 2001 From: lixianjing Date: Fri, 27 Oct 2023 18:17:49 +0800 Subject: [PATCH] improve debugger --- docs/changes.md | 3 +++ src/debugger/debugger_client.c | 4 +++- src/debugger/debugger_const.h | 1 + src/debugger/debugger_lldb.c | 9 +++++--- src/debugger/debugger_lldb.h | 1 + src/debugger/debugger_message.c | 25 ++++++++++++++++++++++ src/debugger/debugger_message.h | 38 +++++++++++++++++++++++++++++++++ src/debugger/debugger_server.c | 1 + src/tkc/socket_helper.c | 2 +- tools/fdb/fdb.cpp | 16 ++++++++++++++ 10 files changed, 95 insertions(+), 5 deletions(-) diff --git a/docs/changes.md b/docs/changes.md index 7ac7370b7..fbbdcba27 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -1,5 +1,8 @@ # 最新动态 +2023/10/27 + * debugger的中断事件和堆栈改变事件增加文件路径(感谢智明提供补丁) + 2023/10/26 * 图片控件支持[packed image](how_to_use_packed_image.md) diff --git a/src/debugger/debugger_client.c b/src/debugger/debugger_client.c index 3ae29ab4c..f93c8eb6e 100644 --- a/src/debugger/debugger_client.c +++ b/src/debugger/debugger_client.c @@ -65,12 +65,14 @@ static ret_t debugger_client_dispatch_message(debugger_t* debugger, debugger_res switch (resp->code) { case DEBUGGER_RESP_MSG_BREAKED: { uint32_t line = 0; + const char* file_path = NULL; debugger_breaked_event_t event; tk_object_t* obj = ubjson_to_object(client->buff, resp->size); return_value_if_fail(obj != NULL, RET_BAD_PARAMS); line = tk_object_get_prop_int(obj, STR_DEBUGGER_EVENT_PROP_LINE, 0); + file_path = tk_object_get_prop_str(obj, STR_DEBUGGER_EVENT_PROP_FILE_PATH); debugger_set_state(debugger, DEBUGGER_PROGRAM_STATE_PAUSED); - emitter_dispatch(EMITTER(debugger), debugger_breaked_event_init(&event, line)); + emitter_dispatch(EMITTER(debugger), debugger_breaked_event_init_ex(&event, line, file_path)); TK_OBJECT_UNREF(obj); break; } diff --git a/src/debugger/debugger_const.h b/src/debugger/debugger_const.h index 1634fc052..59284ac60 100644 --- a/src/debugger/debugger_const.h +++ b/src/debugger/debugger_const.h @@ -26,6 +26,7 @@ #define STR_DEBUGGER_EVENT_PROP_LINE "line" #define STR_DEBUGGER_EVENT_PROP_MESSAGE "message" +#define STR_DEBUGGER_EVENT_PROP_FILE_PATH "file_path" #define DEBUGGER_IO_READ_TIMEOUT 1000000 #define DEBUGGER_IO_WRITE_TIMEOUT 500000 diff --git a/src/debugger/debugger_lldb.c b/src/debugger/debugger_lldb.c index 7607f4494..95cf2873a 100644 --- a/src/debugger/debugger_lldb.c +++ b/src/debugger/debugger_lldb.c @@ -169,16 +169,18 @@ static ret_t debugger_lldb_emit(debugger_t* debugger, tk_object_t* resp) { if (tk_str_eq(event, EVENT_STOPPED)) { int32_t line = 0; + const char* file_path = NULL; debugger_breaked_event_t event; TK_OBJECT_UNREF(lldb->callstack); - + lldb->stop_thread_id = tk_object_get_prop_int64(resp, "body.threadId", 0); lldb->callstack = debugger_lldb_get_callstack_impl(debugger, 0, 100); + file_path = debugger_lldb_get_source_path(debugger, debugger->current_frame_index); debugger_set_state(debugger, DEBUGGER_PROGRAM_STATE_PAUSED); debugger_set_current_frame(debugger, 0); /*LLDB 行号从1开始*/ line = lldb->current_frame_line - 1; - emitter_dispatch(EMITTER(debugger), debugger_breaked_event_init(&event, line)); + emitter_dispatch(EMITTER(debugger), debugger_breaked_event_init_ex(&event, line, file_path)); log_debug("threadId = %d stopped\n", (int)lldb->stop_thread_id); } else if (tk_str_eq(event, EVENT_OUTPUT)) { @@ -982,11 +984,12 @@ static ret_t debugger_lldb_set_current_frame(debugger_t* debugger, uint32_t fram lldb->current_frame_id = debugger_lldb_get_frame_id(debugger, frame_index); lldb->current_frame_name = debugger_lldb_get_frame_name(debugger, frame_index); lldb->current_frame_line = debugger_lldb_get_source_line(debugger, frame_index); + lldb->current_frame_file_path = debugger_lldb_get_source_path(debugger, frame_index); debugger_lldb_scopes_command(debugger, lldb->current_frame_id); /*LLDB 行号从1开始*/ - debugger_frame_changed_event_init(&event, lldb->current_frame_name, lldb->current_frame_line - 1); + debugger_frame_changed_event_init_ex(&event, lldb->current_frame_name, lldb->current_frame_line - 1, lldb->current_frame_file_path); emitter_dispatch(EMITTER(debugger), (event_t*)&(event)); return RET_OK; diff --git a/src/debugger/debugger_lldb.h b/src/debugger/debugger_lldb.h index 14bb97508..617d8d61c 100644 --- a/src/debugger/debugger_lldb.h +++ b/src/debugger/debugger_lldb.h @@ -56,6 +56,7 @@ typedef struct _debugger_lldb_t { int64_t current_frame_line; const char* current_frame_name; const char* current_frame_source; + const char* current_frame_file_path; tk_object_t* resps; /*代码文件缓存*/ diff --git a/src/debugger/debugger_message.c b/src/debugger/debugger_message.c index 147a35471..c891be7c3 100644 --- a/src/debugger/debugger_message.c +++ b/src/debugger/debugger_message.c @@ -71,6 +71,18 @@ event_t* debugger_breaked_event_init(debugger_breaked_event_t* event, uint32_t l return (event_t*)event; } +event_t* debugger_breaked_event_init_ex(debugger_breaked_event_t* event, uint32_t line, const char* file_path) { + return_value_if_fail(event != NULL, NULL); + + memset(event, 0x00, sizeof(*event)); + event->e = event_init(DEBUGGER_RESP_MSG_BREAKED, NULL); + event->e.size = sizeof(*event); + event->line = line; + event->file_path = file_path; + + return (event_t*)event; +} + debugger_breaked_event_t* debugger_breaked_event_cast(event_t* event) { return_value_if_fail(event != NULL && event->type == DEBUGGER_RESP_MSG_BREAKED, NULL); return_value_if_fail(event->size == sizeof(debugger_breaked_event_t), NULL); @@ -90,6 +102,19 @@ event_t* debugger_frame_changed_event_init(debugger_frame_changed_event_t* event return (event_t*)event; } +event_t* debugger_frame_changed_event_init_ex(debugger_frame_changed_event_t* event, const char* func, uint32_t line, const char* file_path) { + return_value_if_fail(event != NULL, NULL); + + memset(event, 0x00, sizeof(*event)); + event->e = event_init(DEBUGGER_RESP_MSG_FRAME_CHANGED, NULL); + event->e.size = sizeof(*event); + event->func = func; + event->line = line; + event->file_path = file_path; + + return (event_t*)event; +} + debugger_frame_changed_event_t* debugger_frame_changed_event_cast(event_t* event) { return_value_if_fail(event != NULL && event->type == DEBUGGER_RESP_MSG_FRAME_CHANGED, NULL); return_value_if_fail(event->size == sizeof(debugger_frame_changed_event_t), NULL); diff --git a/src/debugger/debugger_message.h b/src/debugger/debugger_message.h index 8229c79fb..5db3a86ce 100644 --- a/src/debugger/debugger_message.h +++ b/src/debugger/debugger_message.h @@ -458,6 +458,13 @@ typedef struct _debugger_breaked_event_t { * 中断运行的行号。 */ uint32_t line; + + /** + * @property {const char*} file_path + * @annotation ["readable"] + * 中断运行的文件路径。(备注:可能文件路径为空) + */ + const char* file_path; } debugger_breaked_event_t; /** @@ -471,6 +478,18 @@ typedef struct _debugger_breaked_event_t { */ event_t* debugger_breaked_event_init(debugger_breaked_event_t* event, uint32_t line); +/** + * @method debugger_breaked_event_init_ex + * 初始调试器中断运行的事件。 + * + * @param {debugger_breaked_event_t*} event event对象。 + * @param {uint32_t} line 中断运行的行号。 + * @param {const char*} file_path 中断运行的行号。 + * + * @return {event_t*} 返回event对象。 + */ +event_t* debugger_breaked_event_init_ex(debugger_breaked_event_t* event, uint32_t line, const char* file_path); + /** * @method debugger_breaked_event_cast * @annotation ["cast"] @@ -503,6 +522,12 @@ typedef struct _debugger_frame_changed_event_t { */ const char* func; + /** + * @property {const char*} file_path + * @annotation ["readable"] + * 文件路径。(备注:可能文件路径为空) + */ + const char* file_path; } debugger_frame_changed_event_t; /** @@ -517,6 +542,19 @@ typedef struct _debugger_frame_changed_event_t { */ event_t* debugger_frame_changed_event_init(debugger_frame_changed_event_t* event, const char* func, uint32_t line); +/** + * @method debugger_frame_changed_event_init + * 初始化 + * + * @param {debugger_frame_changed_event_t*} event event对象。 + * @param {const char*} func 函数名。 + * @param {uint32_t} line 行号。 + * @param {const char*} file_path 文件路径。 + * + * @return {event_t*} 返回event对象。 + */ +event_t* debugger_frame_changed_event_init_ex(debugger_frame_changed_event_t* event, const char* func, uint32_t line, const char* file_path); + /** * @method debugger_frame_changed_event_cast * @annotation ["cast"] diff --git a/src/debugger/debugger_server.c b/src/debugger/debugger_server.c index 3100d9909..7588d7299 100644 --- a/src/debugger/debugger_server.c +++ b/src/debugger/debugger_server.c @@ -296,6 +296,7 @@ static ret_t debugger_server_on_events(void* ctx, event_t* e) { case DEBUGGER_RESP_MSG_BREAKED: { debugger_breaked_event_t* event = debugger_breaked_event_cast(e); tk_object_set_prop_int(obj, STR_DEBUGGER_EVENT_PROP_LINE, event->line); + tk_object_set_prop_str(obj, STR_DEBUGGER_EVENT_PROP_FILE_PATH, event->file_path); ret = debugger_server_send_object(server, &msg, obj); break; } diff --git a/src/tkc/socket_helper.c b/src/tkc/socket_helper.c index 414a8bcba..8dc623d2e 100644 --- a/src/tkc/socket_helper.c +++ b/src/tkc/socket_helper.c @@ -251,7 +251,7 @@ ret_t tk_socket_wait_for_data(int sock, uint32_t timeout_ms) { FD_SET(sock, &fdsr); ret = select(sock + 1, &fdsr, NULL, NULL, &tv); - return ret > 0 ? RET_OK : RET_TIMEOUT; + return ret > 0 && FD_ISSET(sock, &fdsr) ? RET_OK : RET_TIMEOUT; } bool_t tk_socket_last_io_has_error(void) { diff --git a/tools/fdb/fdb.cpp b/tools/fdb/fdb.cpp index 5d8593fd7..300c59893 100644 --- a/tools/fdb/fdb.cpp +++ b/tools/fdb/fdb.cpp @@ -251,11 +251,27 @@ static ret_t fdb_on_debugger_events(void* ctx, event_t* e) { debugger_frame_changed_event_t* event = debugger_frame_changed_event_cast(e); app->current_func = event->func; app->current_line = event->line; + str_append(str, ">[frame_info]"); + if (event->file_path != NULL) { + str_append(str, event->file_path); + str_append(str, ":"); + } + str_append_int64(str, event->line); + str_append(str, ":"); + str_append(str, event->func); break; } case DEBUGGER_RESP_MSG_BREAKED: { debugger_breaked_event_t* event = debugger_breaked_event_cast(e); app->current_line = event->line; + str_append(str, ">[bread]"); + if (event->file_path != NULL) { + str_append(str, event->file_path); + str_append(str, ":"); + } else { + str_append(str, "line:"); + } + str_append_int64(str, event->line); break; } case DEBUGGER_RESP_MSG_LOG: {