From ead5282f26a5434434c7aad06bbd7dfa924fc66e Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sun, 18 Sep 2022 16:13:11 -0500 Subject: [PATCH] fixed major issue with debugger --- compiler/include/wasm_emit.h | 2 +- compiler/src/wasm_emit.c | 10 +++++++ interpreter/src/vm/code_builder.c | 12 ++++++++ interpreter/src/vm/vm.c | 13 --------- misc/vscode/onyx-0.0.3.vsix | Bin 702346 -> 702836 bytes misc/vscode/out/ovmDebug.js | 46 +++++++++++++++++++++++++----- misc/vscode/ovmDebug.ts | 43 ++++++++++++++++++++++++---- misc/vscode/package.json | 13 ++++++++- 8 files changed, 112 insertions(+), 27 deletions(-) diff --git a/compiler/include/wasm_emit.h b/compiler/include/wasm_emit.h index 3a79e549..d057f5a9 100644 --- a/compiler/include/wasm_emit.h +++ b/compiler/include/wasm_emit.h @@ -810,7 +810,7 @@ typedef struct DebugFuncContext { u32 file_id; u32 line; u32 op_offset; - u32 stack_ptr_idx; + u64 stack_ptr_idx; u32 name_length; char *name; diff --git a/compiler/src/wasm_emit.c b/compiler/src/wasm_emit.c index 83427bf3..8c7fd5df 100644 --- a/compiler/src/wasm_emit.c +++ b/compiler/src/wasm_emit.c @@ -391,6 +391,14 @@ static void debug_begin_function(OnyxWasmModule *mod, u32 func_idx, OnyxToken *t debug_set_position(mod, token); } +static void debug_function_set_ptr_idx(OnyxWasmModule *mod, u32 func_idx, u64 ptr_idx) { + bh_arr_each(DebugFuncContext, func, mod->debug_context->funcs) { + if (func->func_index == func_idx) { + func->stack_ptr_idx = ptr_idx; + } + } +} + static void debug_end_function(OnyxWasmModule *mod) { bh_buffer_write_byte(&mod->debug_context->op_buffer, DOT_POPF); bh_buffer_write_byte(&mod->debug_context->op_buffer, DOT_END); @@ -415,6 +423,7 @@ static void debug_leave_symbol_frame(OnyxWasmModule *mod) { #define debug_set_position(mod, token) (void)0 #define debug_emit_instruction(mod, token) (void)0 #define debug_begin_function(mod, idx, token, name) (void)0 +#define debug_function_set_ptr_idx(mod, func_idx, ptr_idx) (void)0 #define debug_end_function(mod) (void)0 #define debug_enter_symbol_frame(mod) (void)0 #define debug_leave_symbol_frame(mod) (void)0 @@ -3815,6 +3824,7 @@ static void emit_function(OnyxWasmModule* mod, AstFunction* fd) { // TODO: Emit debug info for the above instructions mod->stack_base_idx = local_raw_allocate(mod->local_alloc, WASM_TYPE_PTR); + debug_function_set_ptr_idx(mod, func_idx, mod->stack_base_idx); // Generate code emit_function_body(mod, &wasm_func.code, fd); diff --git a/interpreter/src/vm/code_builder.c b/interpreter/src/vm/code_builder.c index ec84b473..eb27a810 100644 --- a/interpreter/src/vm/code_builder.c +++ b/interpreter/src/vm/code_builder.c @@ -123,6 +123,18 @@ void ovm_code_builder_patch_else(ovm_code_builder_t *builder, label_target_t if_ } void ovm_code_builder_add_nop(ovm_code_builder_t *builder) { + // + // If debugging info was not present in the binary, + // do not create NOP instructions. NOP instructions are + // normally used as placeholders / special instructions + // to signify something weird happened, such as an expanded + // macro or operator overload. When this happens, it is + // nice to have the correct location in the source tree + // so you don't magically jump from one place to another. + // HOWEVER, if there is no debug info, then this is not + // a concern, and NOPs can be ommited. + if (builder->debug_builder->data == NULL) return; + ovm_instr_t nop = {0}; nop.full_instr = OVMI_NOP; diff --git a/interpreter/src/vm/vm.c b/interpreter/src/vm/vm.c index 28a42627..aa7e8d32 100644 --- a/interpreter/src/vm/vm.c +++ b/interpreter/src/vm/vm.c @@ -675,19 +675,6 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t ovm_value_t tmp_val; while (state->pc < bh_arr_length(program->code)) { - // This will become the line change detection - // debug_loc_info_t loc_info; - // debug_info_lookup_location(engine->debug->info, state->pc, &loc_info); - // if (loc_info.file_id != last_file || loc_info.line != last_line) { - // last_file = loc_info.file_id; - // last_line = loc_info.line; - - // debug_file_info_t file_info; - // debug_info_lookup_file(engine->debug->info, last_file, &file_info); - // - // printf("(%d, %d) %s:%d\n", last_file, last_line, file_info.name, last_line); - // } - #ifdef OVM_VERBOSE ovm_program_print_instructions(program, state->pc, 1); #endif diff --git a/misc/vscode/onyx-0.0.3.vsix b/misc/vscode/onyx-0.0.3.vsix index ba5d515741443ee98170ced23e95ad19a20ca45e..59266f93afb96a379bfed50b1bbaab1e71581d9e 100644 GIT binary patch delta 17409 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 { - this.sendEvent(new debugadapter_1.OutputEvent(chunk, "console")); + return __awaiter(this, void 0, void 0, function* () { + if (args.wasmFile) { + this.running_process = child_process.spawn("onyx-run", ["--debug", args.wasmFile], { + "cwd": args.workingDir, + }); + } + else if (args.onyxFiles) { + this.running_process = child_process.spawn("onyx", ["run", "--debug", ...args.onyxFiles], { + "cwd": args.workingDir, + }); + } + else { + this.sendErrorResponse(response, { + format: "Expected either wasmFile or onyxFiles in launch configuration.", + id: 1 + }); + return; + } + this.running_process.stdout.setEncoding("utf-8"); + this.running_process.stdout.on("data", (chunk) => { + this.sendEvent(new debugadapter_1.OutputEvent(chunk, "console")); + }); + this.attachRequest(response, { "socketPath": "/tmp/ovm-debug.0000", "stopOnEntry": args.stopOnEntry }); }); - this.attachRequest(response, { "socketPath": "/tmp/ovm-debug.0000", "stopOnEntry": args.stopOnEntry }); } attachRequest(response, args, request) { return __awaiter(this, void 0, void 0, function* () { @@ -279,6 +295,8 @@ class OVMDebugger extends EventEmitter { }); } pause(thread_id = 0xffffffff) { + if (this.client == null) + return; let data = new ArrayBuffer(12); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -289,6 +307,8 @@ class OVMDebugger extends EventEmitter { this.pending_responses[cmd_id] = OVMCommand.PAUSE; } resume(thread_id = 0xffffffff) { + if (this.client == null) + return; let data = new ArrayBuffer(12); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -300,6 +320,8 @@ class OVMDebugger extends EventEmitter { } set_breakpoint(filename, line) { return __awaiter(this, void 0, void 0, function* () { + if (this.client == null) + return Promise.resolve({}); let data = new ArrayBuffer(16 + filename.length); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -317,6 +339,8 @@ class OVMDebugger extends EventEmitter { } remove_breakpoints_in_file(filename) { return __awaiter(this, void 0, void 0, function* () { + if (this.client == null) + return Promise.resolve(false); let data = new ArrayBuffer(12 + filename.length); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -332,6 +356,8 @@ class OVMDebugger extends EventEmitter { }); } step(granularity, thread_id) { + if (this.client == null) + return; let data = new ArrayBuffer(16); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -356,6 +382,8 @@ class OVMDebugger extends EventEmitter { this.pending_responses[cmd_id] = OVMCommand.STEP; } trace(thread_id) { + if (this.client == null) + return Promise.resolve([]); let data = new ArrayBuffer(12); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -367,6 +395,8 @@ class OVMDebugger extends EventEmitter { return this.preparePromise(cmd_id); } threads() { + if (this.client == null) + return Promise.resolve([]); let data = new ArrayBuffer(8); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -377,6 +407,8 @@ class OVMDebugger extends EventEmitter { return this.preparePromise(cmd_id); } variables(frame_index, thread_id) { + if (this.client == null) + return Promise.resolve([]); let data = new ArrayBuffer(16); let view = new DataView(data); let cmd_id = this.next_command_id; diff --git a/misc/vscode/ovmDebug.ts b/misc/vscode/ovmDebug.ts index 08d85494..f646927f 100644 --- a/misc/vscode/ovmDebug.ts +++ b/misc/vscode/ovmDebug.ts @@ -12,6 +12,7 @@ import { Subject } from "await-notify"; import * as net from "node:net"; import * as child_process from "node:child_process"; import { ChildProcess } from 'node:child_process'; +import { openStdin } from 'node:process'; interface IOVMAttachRequestArguments extends DebugProtocol.AttachRequestArguments { @@ -20,7 +21,8 @@ interface IOVMAttachRequestArguments extends DebugProtocol.AttachRequestArgument } interface IOVMLaunchRequestArguments extends DebugProtocol.AttachRequestArguments { - wasmFile: string; + wasmFile?: string; + onyxFiles?: [string]; workingDir: string; stopOnEntry?: boolean; } @@ -257,10 +259,25 @@ export class OVMDebugSession extends LoggingDebugSession { this.sendResponse(response); } - protected launchRequest(response: DebugProtocol.LaunchResponse, args: IOVMLaunchRequestArguments, request?: DebugProtocol.Request): void { - this.running_process = child_process.spawn("onyx-run", ["--debug", args.wasmFile], { - "cwd": args.workingDir, - }); + protected async launchRequest(response: DebugProtocol.LaunchResponse, args: IOVMLaunchRequestArguments, request?: DebugProtocol.Request): Promise { + if (args.wasmFile) { + this.running_process = child_process.spawn("onyx-run", ["--debug", args.wasmFile], { + "cwd": args.workingDir, + }); + + } else if (args.onyxFiles) { + this.running_process = child_process.spawn("onyx", ["run", "--debug", ...args.onyxFiles], { + "cwd": args.workingDir, + }); + + } else { + this.sendErrorResponse(response, { + format: "Expected either wasmFile or onyxFiles in launch configuration.", + id: 1 + } as DebugProtocol.Message); + + return; + } this.running_process.stdout.setEncoding("utf-8"); this.running_process.stdout.on("data", (chunk) => { @@ -398,6 +415,8 @@ class OVMDebugger extends EventEmitter { } pause(thread_id: number = 0xffffffff): void { + if (this.client == null) return; + let data = new ArrayBuffer(12); let view = new DataView(data); @@ -413,6 +432,8 @@ class OVMDebugger extends EventEmitter { } resume(thread_id: number = 0xffffffff): void { + if (this.client == null) return; + let data = new ArrayBuffer(12); let view = new DataView(data); @@ -428,6 +449,8 @@ class OVMDebugger extends EventEmitter { } async set_breakpoint(filename: string, line: number): Promise { + if (this.client == null) return Promise.resolve({} as IBreakpointValidation); + let data = new ArrayBuffer(16+filename.length); let view = new DataView(data); @@ -450,6 +473,8 @@ class OVMDebugger extends EventEmitter { } async remove_breakpoints_in_file(filename: string): Promise { + if (this.client == null) return Promise.resolve(false); + let data = new ArrayBuffer(12+filename.length); let view = new DataView(data); @@ -471,6 +496,8 @@ class OVMDebugger extends EventEmitter { } step(granularity: "line" | "instruction" | "over" | "out", thread_id: number): void { + if (this.client == null) return; + let data = new ArrayBuffer(16); let view = new DataView(data); @@ -493,6 +520,8 @@ class OVMDebugger extends EventEmitter { } trace(thread_id: number): Promise { + if (this.client == null) return Promise.resolve([]); + let data = new ArrayBuffer(12); let view = new DataView(data); @@ -510,6 +539,8 @@ class OVMDebugger extends EventEmitter { } threads(): Promise { + if (this.client == null) return Promise.resolve([]); + let data = new ArrayBuffer(8); let view = new DataView(data); @@ -526,6 +557,8 @@ class OVMDebugger extends EventEmitter { } variables(frame_index: number, thread_id: number): Promise { + if (this.client == null) return Promise.resolve([]); + let data = new ArrayBuffer(16); let view = new DataView(data); diff --git a/misc/vscode/package.json b/misc/vscode/package.json index 8ad40eaa..7bbd3ff0 100644 --- a/misc/vscode/package.json +++ b/misc/vscode/package.json @@ -14,6 +14,9 @@ "activationEvents": [ "onLanguage:onyx" ], + "repository": { + "url": "https://github.com/onyx-lang/onyx" + }, "icon": "logo.png", "main": "./out/extension.js", "contributes": { @@ -88,6 +91,11 @@ "description": "The WASM file for debugging, compiled with the --debug flag.", "default": "out.wasm" }, + "onyxFiles": { + "type": "array", + "description": "The Onyx files for compiling.", + "default": "[]" + }, "workingDir": { "type": "string", "description": "The working directory for the execution", @@ -103,11 +111,14 @@ }, "initialConfigurations": [ { + "name": "Onyx Attach", "type": "onyx", "request": "attach", - "stopOnEntry": true + "stopOnEntry": true, + "socketPath": "/tmp/ovm-debug.0000" }, { + "name": "Onyx Launch", "type": "onyx", "request": "launch", "wasmFile": "out.wasm", -- 2.25.1