From 21cb503c06adf867ffe016dae226af1ea7d4611e Mon Sep 17 00:00:00 2001 From: Nunuhara Cabbage Date: Thu, 14 Apr 2022 10:38:45 -0700 Subject: [PATCH] Read debugger config at startup Read .xsys4-debugrc from ~/.xsystem4 and/or the game directory on startup. This is just a text file with one debugger command per line. Can be used to set breakpoints or log functions automatically at startup. This can also be used to work around a limitation on Windows where the IME doesn't work in the debugger, making it impossible to input Japanese text. --- include/debugger.h | 1 + include/vm.h | 1 + src/debug.c | 11 +++++-- src/debugger_cmd.c | 76 +++++++++++++++++++++++++++++++++------------ src/vm.c | 10 +++++- subprojects/libsys4 | 2 +- 6 files changed, 76 insertions(+), 25 deletions(-) diff --git a/include/debugger.h b/include/debugger.h index 5611431..9a8ef1f 100644 --- a/include/debugger.h +++ b/include/debugger.h @@ -46,6 +46,7 @@ void dbg_repl(void); void dbg_continue(void); void dbg_quit(void); void dbg_start(void(*fun)(void*), void *data); +void dbg_cmd_init(void); void dbg_cmd_repl(void); void dbg_handle_breakpoint(void); bool dbg_set_function_breakpoint(const char *_name, void(*cb)(struct breakpoint*), void *data); diff --git a/include/vm.h b/include/vm.h index f7a114c..ab64916 100644 --- a/include/vm.h +++ b/include/vm.h @@ -92,6 +92,7 @@ union vm_value stack_pop(void); union vm_value global_get(int varno); void global_set(int varno, union vm_value val, bool call_dtors); struct page *local_page(void); +struct page *get_local_page(int frame_no); struct page *get_struct_page(int frame_no); int vm_string_ref(struct string *s); diff --git a/src/debug.c b/src/debug.c index de1abd9..0c4bb0f 100644 --- a/src/debug.c +++ b/src/debug.c @@ -85,6 +85,7 @@ void dbg_repl(void) void dbg_init(void) { + dbg_cmd_init(); #ifdef HAVE_SCHEME dbg_scm_init(); #endif @@ -137,11 +138,11 @@ bool dbg_set_function_breakpoint(const char *_name, void(*cb)(struct breakpoint* bp->data = data; bp->message = xmalloc(512); snprintf(bp->message, 511, "Hit breakpoint at function '%s' (0x%08x)", - display_sjis0(_name), f->address); + display_utf0(_name), f->address); LittleEndian_putW(ain->code, f->address, BREAKPOINT | bp->restore_op); add_breakpoint(f->address, bp); - printf("Set breakpoint at function '%s' (0x%08x)\n", display_sjis0(_name), f->address); + printf("Set breakpoint at function '%s' (0x%08x)\n", display_utf0(_name), f->address); return true; } @@ -234,7 +235,11 @@ struct ain_variable *dbg_get_member(const char *name, union vm_value *val_out) struct ain_variable *dbg_get_local(const char *name, union vm_value *val_out) { - struct page *page = local_page(); + struct page *page = get_local_page(dbg_current_frame); + if (!page) + return NULL; + assert(page->type == LOCAL_PAGE); + assert(page->index >= 0 && page->index < ain->nr_functions); struct ain_function *f = &ain->functions[page->index]; for (int i = 0; i < f->nr_vars; i++) { if (!strcmp(f->vars[i].name, name)) { diff --git a/src/debugger_cmd.c b/src/debugger_cmd.c index 9e26863..10e1625 100644 --- a/src/debugger_cmd.c +++ b/src/debugger_cmd.c @@ -21,8 +21,11 @@ #include #include #include +#include #include +#include "system4.h" +#include "system4/file.h" #include "system4/string.h" #include "system4/utfsjis.h" @@ -271,30 +274,63 @@ static char **cmd_parse(char *line, unsigned *nr_words) return words; } +static void execute_line(char *line) +{ + unsigned nr_words; + char **words = cmd_parse(line, &nr_words); + if (!nr_words) + return; + + struct dbg_cmd *cmd = dbg_get_command(words[0]); + if (!cmd) { + printf("Invalid command: %s (type 'help' for a list of commands)\n", words[0]); + return; + } + + if ((nr_words-1) < cmd->min_args || (nr_words-1) > cmd->max_args) { + printf("Wrong number of arguments to '%s' command\n", cmd->fullname); + return; + } + + cmd->run(nr_words-1, words+1); +} + void dbg_cmd_repl(void) { puts("Entering the debugger REPL. Type 'help' for a list of commands."); while (1) { char *line = cmd_gets(); - if (!line) - continue; - - unsigned nr_words; - char **words = cmd_parse(line, &nr_words); - if (!nr_words) - continue; - - struct dbg_cmd *cmd = dbg_get_command(words[0]); - if (!cmd) { - printf("Invalid command: %s (type 'help' for a list of commands)\n", words[0]); - continue; - } - - if ((nr_words-1) < cmd->min_args || (nr_words-1) > cmd->max_args) { - printf("Wrong number of arguments to '%s' command\n", cmd->fullname); - continue; - } - - cmd->run(nr_words-1, words+1); + if (line) + execute_line(line); } } + +static void execute_config(void *_f) +{ + FILE *f = _f; + char line[1024]; + while (fgets(line, 1024, f)) { + execute_line(line); + } +} + +static void read_config(const char *path) +{ + FILE *f = file_open_utf8(path, "rb"); + if (!f) + return; + dbg_start(execute_config, f); + fclose(f); +} + +void dbg_cmd_init(void) +{ + char *path = xmalloc(PATH_MAX); + snprintf(path, PATH_MAX, "%s/.xsys4-debugrc", config.home_dir); + read_config(path); + free(path); + + path = gamedir_path(".xsys4-debugrc"); + read_config(path); + free(path); +} diff --git a/src/vm.c b/src/vm.c index 782c2fc..5b6de7a 100644 --- a/src/vm.c +++ b/src/vm.c @@ -108,6 +108,14 @@ struct page *local_page(void) return heap[local_page_slot()].page; } +struct page *get_local_page(int frame_no) +{ + if (frame_no < 0 || frame_no >= call_stack_ptr) + return NULL; + int slot = call_stack[call_stack_ptr - (frame_no + 1)].page_slot; + return slot < 1 ? NULL : heap[slot].page; +} + static union vm_value local_get(int varno) { return local_page()->values[varno]; @@ -166,7 +174,7 @@ struct page *get_struct_page(int frame_no) if (frame_no < 0 || frame_no >= call_stack_ptr) return NULL; int slot = call_stack[call_stack_ptr - (frame_no + 1)].struct_page; - return slot < 0 ? NULL : heap[slot].page; + return slot < 1 ? NULL : heap[slot].page; } static union vm_value member_get(int varno) diff --git a/subprojects/libsys4 b/subprojects/libsys4 index f46686e..eaa6577 160000 --- a/subprojects/libsys4 +++ b/subprojects/libsys4 @@ -1 +1 @@ -Subproject commit f46686ee09cb7005e8d099d3e049473e7a3dca56 +Subproject commit eaa6577bef8b4f67871027b38686648ddf0b7e61