diff --git a/include/debugger.h b/include/debugger.h index 96c3155..78b5408 100644 --- a/include/debugger.h +++ b/include/debugger.h @@ -29,6 +29,18 @@ struct ain_variable; +enum dbg_stop_type { + DBG_STOP_PAUSE, + DBG_STOP_ERROR, + DBG_STOP_BREAKPOINT, + DBG_STOP_STEP, +}; + +struct dbg_stop { + enum dbg_stop_type type; + const char *message; +}; + struct breakpoint { enum opcode restore_op; void *data; @@ -54,7 +66,7 @@ extern unsigned dbg_current_frame; void dbg_init(void); void dbg_fini(void); -void dbg_repl(void); +void dbg_repl(enum dbg_stop_type, const char *msg); void dbg_log(const char *log, const char *fmt, va_list ap); @@ -80,7 +92,7 @@ struct string *dbg_value_to_string(struct ain_type *type, union vm_value value, void dbg_dap_init(void); void dbg_dap_quit(void); -void dbg_dap_repl(void); +void dbg_dap_repl(struct dbg_stop *stop); void dbg_dap_handle_messages(void); void dbg_dap_log(const char *log, const char *fmt, va_list ap); diff --git a/src/debug.c b/src/debug.c index b1dc80d..d21286e 100644 --- a/src/debug.c +++ b/src/debug.c @@ -73,19 +73,25 @@ void dbg_start(void(*fun)(void*), void *data) fun(data); } -static void _dbg_repl(void *_) +static void _dbg_repl(void *stop) { if (dbg_dap) - dbg_dap_repl(); + dbg_dap_repl(stop); else dbg_cmd_repl(); } -void dbg_repl(void) +void dbg_repl(enum dbg_stop_type type, const char *msg) { if (!dbg_enabled) return; - dbg_start(_dbg_repl, NULL); + + struct dbg_stop stop = { + .type = type, + .message = msg, + }; + + dbg_start(_dbg_repl, &stop); } void dbg_init(void) @@ -97,8 +103,9 @@ void dbg_init(void) #ifdef HAVE_SCHEME dbg_scm_init(); #endif - if (!dbg_dap && dbg_start_in_debugger) - dbg_repl(); + if (!dbg_dap && dbg_start_in_debugger) { + dbg_repl(DBG_STOP_PAUSE, ""); + } } void dbg_fini(void) @@ -216,7 +223,8 @@ static void dbg_step_breakpoint_cb(struct breakpoint *bp) if ((intptr_t)bp->data != call_stack_ptr) return; delete_breakpoint(instr_ptr, bp); - _dbg_repl(NULL); + struct dbg_stop stop = { DBG_STOP_STEP, NULL }; + _dbg_repl(&stop); } static void dbg_set_step_breakpoint(int32_t address, int call_index) @@ -405,7 +413,8 @@ static void _dbg_handle_breakpoint(void *data) bp->cb(bp); } else { log_message("debug", "%s\n", bp->message); - _dbg_repl(NULL); + struct dbg_stop stop = { DBG_STOP_BREAKPOINT, NULL }; + _dbg_repl(&stop); } } diff --git a/src/debugger_dap.c b/src/debugger_dap.c index ac47df3..4237295 100644 --- a/src/debugger_dap.c +++ b/src/debugger_dap.c @@ -105,11 +105,28 @@ static void emit_terminated_event(void) emit_event("terminated", NULL); } -static void emit_stopped_event(void) +static void emit_stopped_event(struct dbg_stop *stop) { cJSON *body = cJSON_CreateObject(); - // TODO: specify correct reason - cJSON_AddStringToObject(body, "reason", "pause"); + switch (stop->type) { + case DBG_STOP_PAUSE: + cJSON_AddStringToObject(body, "reason", "pause"); + cJSON_AddStringToObject(body, "description", "Paused by user"); + break; + case DBG_STOP_ERROR: + cJSON_AddStringToObject(body, "reason", "exception"); + cJSON_AddStringToObject(body, "description", "Paused on error"); + break; + case DBG_STOP_BREAKPOINT: + cJSON_AddStringToObject(body, "reason", "breakpoint"); + cJSON_AddStringToObject(body, "description", "Paused on breakpoint"); + break; + case DBG_STOP_STEP: + cJSON_AddStringToObject(body, "reason", "step"); + cJSON_AddStringToObject(body, "description", "Paused by step action"); + } + if (stop->message) + cJSON_AddStringToObject(body, "text", stop->message); emit_event("stopped", body); } @@ -551,7 +568,7 @@ static void cmd_pause(cJSON *args, cJSON *resp) send_json(resp); if (dap_state != DAP_STOPPED) { - dbg_repl(); + dbg_repl(DBG_STOP_PAUSE, NULL); } } @@ -862,9 +879,9 @@ void dbg_dap_quit(void) emit_terminated_event(); } -void dbg_dap_repl(void) +void dbg_dap_repl(struct dbg_stop *stop) { - emit_stopped_event(); + emit_stopped_event(stop); dap_state = DAP_STOPPED; bool continue_repl = true; diff --git a/src/input.c b/src/input.c index c3c6187..0d4672f 100644 --- a/src/input.c +++ b/src/input.c @@ -246,7 +246,7 @@ static void mouse_event(SDL_MouseButtonEvent *e) #ifdef DEBUGGER_ENABLED if (e->button == SDL_BUTTON_MIDDLE && e->state == SDL_PRESSED && (dbg_start_in_debugger || dbg_dap)) - dbg_repl(); + dbg_repl(DBG_STOP_PAUSE, NULL); #endif } diff --git a/src/vm.c b/src/vm.c index 0712e3a..616afac 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2393,7 +2393,13 @@ _Noreturn void _vm_error(const char *fmt, ...) va_end(ap); sys_warning("at %s (0x%X) in:\n", current_instruction_name(), instr_ptr); vm_stack_trace(); - dbg_repl(); + + char msg[1024]; + va_start(ap, fmt); + vsnprintf(msg, 1024, fmt, ap); + va_end(ap); + + dbg_repl(DBG_STOP_ERROR, msg); sys_exit(1); }