Support print exception info in source debugger (#1212)

This commit is contained in:
Xu Jun 2022-06-08 12:17:48 +08:00 committed by GitHub
parent 48cdbee4e0
commit 93607d0fac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 15 deletions

View File

@ -14,6 +14,7 @@
#endif #endif
#if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0 #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
#include "../libraries/thread-mgr/thread_manager.h" #include "../libraries/thread-mgr/thread_manager.h"
#include "../libraries/debug-engine/debug_engine.h"
#endif #endif
typedef int32 CellType_I32; typedef int32 CellType_I32;
@ -930,6 +931,9 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
#if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0 #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
#define HANDLE_OP_END() \ #define HANDLE_OP_END() \
do { \ do { \
/* Record the current frame_ip, so when exception occurs, \
debugger can know the exact opcode who caused the exception */ \
frame_ip_orig = frame_ip; \
while (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \ while (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
&& exec_env->current_status->step_count++ == 1) { \ && exec_env->current_status->step_count++ == 1) { \
exec_env->current_status->step_count = 0; \ exec_env->current_status->step_count = 0; \
@ -1007,6 +1011,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 cache_index, type_index, param_cell_num, cell_num; uint32 cache_index, type_index, param_cell_num, cell_num;
uint8 value_type; uint8 value_type;
#if WASM_ENABLE_DEBUG_INTERP != 0
uint8 *frame_ip_orig = NULL;
#endif
#if WASM_ENABLE_LABELS_AS_VALUES != 0 #if WASM_ENABLE_LABELS_AS_VALUES != 0
#define HANDLE_OPCODE(op) &&HANDLE_##op #define HANDLE_OPCODE(op) &&HANDLE_##op
DEFINE_GOTO_TABLE(const void *, handle_table); DEFINE_GOTO_TABLE(const void *, handle_table);
@ -3734,6 +3742,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
wasm_set_exception(module, "out of bounds memory access"); wasm_set_exception(module, "out of bounds memory access");
got_exception: got_exception:
#if WASM_ENABLE_DEBUG_INTERP != 0
if (wasm_exec_env_get_instance(exec_env) != NULL) {
uint8 *frame_ip_temp = frame_ip;
frame_ip = frame_ip_orig;
wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TRAP);
CHECK_SUSPEND_FLAGS();
frame_ip = frame_ip_temp;
}
#endif
SYNC_ALL_TO_FRAME(); SYNC_ALL_TO_FRAME();
return; return;

View File

@ -456,7 +456,7 @@ wasm_debug_instance_destroy(WASMCluster *cluster)
} }
} }
static WASMExecEnv * WASMExecEnv *
wasm_debug_instance_get_current_env(WASMDebugInstance *instance) wasm_debug_instance_get_current_env(WASMDebugInstance *instance)
{ {
WASMExecEnv *exec_env = NULL; WASMExecEnv *exec_env = NULL;
@ -829,7 +829,10 @@ WASMDebugInstance *
wasm_exec_env_get_instance(WASMExecEnv *exec_env) wasm_exec_env_get_instance(WASMExecEnv *exec_env)
{ {
WASMDebugInstance *instance = NULL; WASMDebugInstance *instance = NULL;
bh_assert(g_debug_engine);
if (!g_debug_engine) {
return NULL;
}
os_mutex_lock(&g_debug_engine->instance_list_lock); os_mutex_lock(&g_debug_engine->instance_list_lock);
instance = bh_list_first_elem(&g_debug_engine->debug_instance_list); instance = bh_list_first_elem(&g_debug_engine->debug_instance_list);

View File

@ -128,6 +128,9 @@ wasm_debug_set_engine_active(bool active);
bool bool
wasm_debug_get_engine_active(void); wasm_debug_get_engine_active(void);
WASMExecEnv *
wasm_debug_instance_get_current_env(WASMDebugInstance *instance);
uint64 uint64
wasm_debug_instance_get_pid(WASMDebugInstance *instance); wasm_debug_instance_get_pid(WASMDebugInstance *instance);

View File

@ -334,6 +334,8 @@ send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid)
char pc_string[17]; char pc_string[17];
uint32 tids_count, i = 0; uint32 tids_count, i = 0;
uint32 gdb_status = status; uint32 gdb_status = status;
WASMExecEnv *exec_env;
const char *exception;
if (status == 0) { if (status == 0) {
os_mutex_lock(&tmpbuf_lock); os_mutex_lock(&tmpbuf_lock);
@ -370,20 +372,41 @@ send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid)
mem2hex((void *)&pc, pc_string, 8); mem2hex((void *)&pc, pc_string, 8);
pc_string[8 * 2] = '\0'; pc_string[8 * 2] = '\0';
if (status == WAMR_SIG_TRAP) { exec_env = wasm_debug_instance_get_current_env(
len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, (WASMDebugInstance *)server->thread->debug_instance);
"thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc, exception =
pc_string, "breakpoint"); wasm_runtime_get_exception(wasm_runtime_get_module_inst(exec_env));
if (exception) {
/* When exception occurs, use reason:exception so the description can be
* correctly processed by LLDB */
uint32 exception_len = strlen(exception);
len +=
snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
"thread-pcs:%" PRIx64 ";00:%s;reason:%s;description:", pc,
pc_string, "exception");
/* The description should be encoded as HEX */
for (i = 0; i < exception_len; i++) {
len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, "%02x",
exception[i]);
}
len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, ";");
} }
else if (status == WAMR_SIG_SINGSTEP) { else {
len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, if (status == WAMR_SIG_TRAP) {
"thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc, len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
pc_string, "trace"); "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
} pc_string, "breakpoint");
else if (status > 0) { }
len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, else if (status == WAMR_SIG_SINGSTEP) {
"thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc, len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
pc_string, "signal"); "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
pc_string, "trace");
}
else if (status > 0) {
len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
"thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
pc_string, "signal");
}
} }
write_packet(server, tmpbuf); write_packet(server, tmpbuf);
os_mutex_unlock(&tmpbuf_lock); os_mutex_unlock(&tmpbuf_lock);