#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
}
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) {
}
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);
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);
}
}
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;
}
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;
+ }
}
}
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;
}
} \
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); \