From 5583ce50ec4701172e6b6c79bb904ee1708bbce1 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Wed, 10 Aug 2022 22:25:03 -0500 Subject: [PATCH] step in, out, over --- include/ovm_debug.h | 2 + src/debug/debug_thread.c | 88 +++++++++++++++++++++------------------ src/vm/vm.c | 29 +++++++++---- src/wasm/module_parsing.h | 9 +++- 4 files changed, 76 insertions(+), 52 deletions(-) diff --git a/include/ovm_debug.h b/include/ovm_debug.h index ff40cc6..2037b3b 100644 --- a/include/ovm_debug.h +++ b/include/ovm_debug.h @@ -121,6 +121,8 @@ typedef struct debug_thread_state_t { sem_t wait_semaphore; bool pause_at_next_line; + i32 pause_within; + i32 extra_frames_since_last_pause; debug_pause_reason_t pause_reason; bh_arr(debug_breakpoint_t) breakpoints; diff --git a/src/debug/debug_thread.c b/src/debug/debug_thread.c index 7de5aae..bffe9a9 100644 --- a/src/debug/debug_thread.c +++ b/src/debug/debug_thread.c @@ -12,7 +12,6 @@ #define CMD_RES 1 #define CMD_BRK 2 #define CMD_CLR_BRK 3 -#define CMD_LOC 4 #define CMD_STEP 5 #define CMD_TRACE 6 @@ -34,9 +33,15 @@ static void send_response_header(debug_state_t *debug, unsigned int message_numb } static void send_string(debug_state_t *debug, const char *str) { - unsigned int len = strlen(str); - send(debug->client_fd, &len, 4, 0); - send(debug->client_fd, str, len, 0); + unsigned int len; + if (!str) { + len = 0; + send(debug->client_fd, &len, 4, 0); + } else { + len = strlen(str); + send(debug->client_fd, &len, 4, 0); + send(debug->client_fd, str, len, 0); + } } static void send_bytes(debug_state_t *debug, const char *bytes, unsigned int len) { @@ -86,6 +91,10 @@ static void resume_thread(debug_thread_state_t *thread) { } static void process_command(debug_state_t *debug, struct msg_parse_ctx_t *ctx) { +#define ON_THREAD(tid) \ + bh_arr_each(debug_thread_state_t *, thread, debug->threads) \ + if ((*thread)->id == tid) + u32 msg_id = parse_int(debug, ctx); u32 command_id = parse_int(debug, ctx); @@ -195,49 +204,47 @@ static void process_command(debug_state_t *debug, struct msg_parse_ctx_t *ctx) { break; } - case CMD_LOC: { + case CMD_STEP: { + u32 granularity = parse_int(debug, ctx); u32 thread_id = parse_int(debug, ctx); + + if (granularity == 1) { + ON_THREAD(thread_id) { + (*thread)->pause_at_next_line = true; + (*thread)->pause_within = -1; + resume_thread(*thread); + } + } - bh_arr_each(debug_thread_state_t *, thread, debug->threads) { - if ((*thread)->id == thread_id) { - bool success = true; - - debug_loc_info_t loc_info; - u32 instr = (*thread)->ovm_state->pc; - while (!debug_info_lookup_location(debug->info, instr, &loc_info)) { - instr++; - } - - debug_file_info_t file_info; - success = success && debug_info_lookup_file(debug->info, loc_info.file_id, &file_info); + if (granularity == 2) { + ON_THREAD(thread_id) { + (*thread)->run_count = 1; + resume_thread(*thread); + } + } - if (success) { - send_response_header(debug, msg_id); - send_bool(debug, true); - send_string(debug, file_info.name); - send_int(debug, loc_info.line); - return; - } + if (granularity == 3) { + ON_THREAD(thread_id) { + ovm_stack_frame_t *last_frame = &bh_arr_last((*thread)->ovm_state->stack_frames); + (*thread)->pause_at_next_line = true; + (*thread)->pause_within = last_frame->func->id; + (*thread)->extra_frames_since_last_pause = 0; + resume_thread(*thread); } } - send_response_header(debug, msg_id); - send_bool(debug, false); - send_string(debug, ""); - send_int(debug, -1); - break; - } - - case CMD_STEP: { - u32 granularity = parse_int(debug, ctx); - u32 thread_id = parse_int(debug, ctx); - - if (granularity == 1) { - bh_arr_each(debug_thread_state_t *, thread, debug->threads) { - if ((*thread)->id == thread_id) { - (*thread)->pause_at_next_line = true; - resume_thread(*thread); + if (granularity == 4) { + ON_THREAD(thread_id) { + if (bh_arr_length((*thread)->ovm_state->stack_frames) == 1) { + (*thread)->pause_within = -1; + } else { + ovm_stack_frame_t *last_frame = &bh_arr_last((*thread)->ovm_state->stack_frames); + (*thread)->pause_within = (last_frame - 1)->func->id; } + + (*thread)->pause_at_next_line = true; + (*thread)->extra_frames_since_last_pause = 0; + resume_thread(*thread); } } @@ -276,7 +283,6 @@ static void process_command(debug_state_t *debug, struct msg_parse_ctx_t *ctx) { assert(debug_info_lookup_func(debug->info, func->id, &func_info)); send_string(debug, func_info.name); - // :CopyPaste from CMD_LOC case debug_loc_info_t loc_info; debug_file_info_t file_info; diff --git a/src/vm/vm.c b/src/vm/vm.c index 63561a5..150644a 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -691,15 +691,18 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t } if (state->debug->pause_at_next_line) { - debug_loc_info_t l1, l2; - debug_info_lookup_location(engine->debug->info, state->pc - 1, &l1); - debug_info_lookup_location(engine->debug->info, state->pc, &l2); - - if (l1.file_id != l2.file_id || l1.line != l2.line) { - state->debug->pause_at_next_line = false; - state->debug->pause_reason = debug_pause_step; - state->debug->state = debug_state_pausing; - goto should_wait; + if (state->debug->pause_within == -1 || state->debug->pause_within == bh_arr_last(state->stack_frames).func->id) { + + debug_loc_info_t l1, l2; + debug_info_lookup_location(engine->debug->info, state->pc - 1, &l1); + debug_info_lookup_location(engine->debug->info, state->pc, &l2); + + if (l1.file_id != l2.file_id || l1.line != l2.line) { + state->debug->pause_at_next_line = false; + state->debug->pause_reason = debug_pause_step; + state->debug->state = debug_state_pausing; + goto should_wait; + } } } @@ -1079,6 +1082,13 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t ovm_stack_frame_t frame = ovm__func_teardown_stack_frame(engine, state, program); state->pc = frame.return_address; + if (state->debug) { + state->debug->extra_frames_since_last_pause--; + if (state->debug->extra_frames_since_last_pause < 0) { + state->debug->pause_within = -1; + } + } + if (bh_arr_length(state->stack_frames) == 0) { return val; } @@ -1114,6 +1124,7 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t } \ bh_arr_fastdeleten(state->params, func->param_count); \ \ + if (state->debug) state->debug->extra_frames_since_last_pause++; \ state->pc = func->start_instr; \ } else { \ ovm__func_setup_stack_frame(engine, state, program, fidx, instr.r); \ diff --git a/src/wasm/module_parsing.h b/src/wasm/module_parsing.h index 8d1e2ef..29d01d2 100644 --- a/src/wasm/module_parsing.h +++ b/src/wasm/module_parsing.h @@ -509,8 +509,13 @@ static void parse_instruction(build_context *ctx) { unsigned char instr_byte = CONSUME_BYTE(ctx); switch (instr_byte) { - case 0x00: break; - case 0x01: break; + case 0x00: + break; + + case 0x01: + ovm_code_builder_add_nop(&ctx->builder); + break; + case 0x02: { // Currently, only "void" block types are valid. assert(CONSUME_BYTE(ctx) == 0x40); -- 2.25.1