From 384a44bd1189119326350996fcdff1cf4394a8cd Mon Sep 17 00:00:00 2001 From: David Czihak Date: Thu, 7 May 2026 18:12:39 +0200 Subject: Feat: Add LLDB log creation setting, improve logs --- Scripts/lldb-dap-proxy.pl | 23 +++++++++++++++++------ Scripts/main.js | 19 ++++++++++++++++--- extension.json | 29 ++++++++++++++++++++++++++++- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/Scripts/lldb-dap-proxy.pl b/Scripts/lldb-dap-proxy.pl index 5f545b1..beb6eaa 100644 --- a/Scripts/lldb-dap-proxy.pl +++ b/Scripts/lldb-dap-proxy.pl @@ -1,6 +1,7 @@ #!/usr/bin/perl use strict; use warnings; +use Fcntl qw(O_WRONLY O_APPEND O_CREAT O_NOFOLLOW); use IPC::Open3; use IO::Select; use JSON::PP; @@ -13,7 +14,7 @@ my @adapter_args = @ARGV > 2 ? @ARGV[2 .. $#ARGV] : (); sub log_msg { return unless defined $log_path; my ($msg) = @_; - open(my $fh, '>>', $log_path) or return; + sysopen(my $fh, $log_path, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW, 0600) or return; my @t = gmtime(time); printf $fh "[%04d-%02d-%02dT%02d:%02d:%02dZ] %s\n", $t[5] + 1900, $t[4] + 1, $t[3], $t[2], $t[1], $t[0], $msg; @@ -41,8 +42,8 @@ if ($@) { binmode($_, ':raw') for \*STDIN, \*STDOUT, $child_in, $child_out, $child_err; -$SIG{INT} = sub { kill 'INT', $pid }; -$SIG{TERM} = sub { kill 'TERM', $pid }; +$SIG{INT} = sub { log_msg('received SIGINT'); kill 'INT', $pid }; +$SIG{TERM} = sub { log_msg('received SIGTERM'); kill 'TERM', $pid }; my $json = JSON::PP->new->utf8; @@ -63,8 +64,15 @@ LOOP: while ($sel->count > 0) { unless (defined $n && $n > 0) { $sel->remove($fh); my $fn = fileno($fh); - close($child_in) if $fn == $stdin_fn; - last LOOP if $fn == $child_out_fn; # adapter stdout closing ends the session + if ($fn == $stdin_fn) { + log_msg('stdin closed'); + close($child_in); + } elsif ($fn == $child_out_fn) { + log_msg('adapter stdout closed'); + last LOOP; + } else { + log_msg('adapter stderr closed'); + } next; } my $fn = fileno($fh); @@ -82,6 +90,7 @@ LOOP: while ($sel->count > 0) { } waitpid($pid, 0); +log_msg(sprintf 'adapter exited status=%d signal=%d', $? >> 8, $? & 127); # $? encodes exit code in the high byte and terminating signal in the low 7 bits. # Re-raise the signal so the parent sees a signal-killed exit rather than exit(0). my $signal = $? & 127; @@ -90,6 +99,7 @@ if ($signal) { kill $signal, $$; sleep 1; } +log_msg(sprintf 'proxy exit code=%d', $? >> 8); exit($? >> 8); sub flush_dap { @@ -119,7 +129,7 @@ sub flush_dap { syswrite($dest, 'Content-Length: ' . length($out) . "\r\n\r\n"); syswrite($dest, $out); } else { - log_msg('non-json message forwarded'); + log_msg(sprintf 'non-json message forwarded%s', $@ ? " error=$@" : ' reason=not-a-hash'); syswrite($dest, 'Content-Length: ' . $body_len . "\r\n\r\n"); syswrite($dest, $body); } @@ -157,6 +167,7 @@ sub rewrite_client_message { command => $command, arguments => $msg->{arguments}, }; + log_msg(sprintf 'client seq map %s=>%s', $orig, $rewrite); } $msg->{seq} = $rewrite; } diff --git a/Scripts/main.js b/Scripts/main.js index 1058dfe..d9aac14 100644 --- a/Scripts/main.js +++ b/Scripts/main.js @@ -12,6 +12,7 @@ const CONFIG_KEYS = { zlsEnabled: `${EXTENSION_ID}.zls.enabled`, zlsBuildOnSave: `${EXTENSION_ID}.zls.build-on-save`, zlsDebug: `${EXTENSION_ID}.zls.debug`, + lldbDapDebug: `${EXTENSION_ID}.debug-adapter.debug`, }; let languageServer = null; @@ -264,7 +265,7 @@ function lldbDapProxyPath() { } function debugAdapterLogPath() { - return "/tmp/zig-lldb-dap-proxy.log"; + return nova.path.join(nova.extension.globalStoragePath, "lldb-dap-proxy.log"); } function issueNormalizerScriptPath() { @@ -806,12 +807,24 @@ class ZigTaskAssistant { const action = new TaskDebugAdapterAction("zig-lldb-dap"); action.transport = "stdio"; action.command = "/usr/bin/perl"; - action.args = [lldbDapProxyPath(), lldbDapPath, debugAdapterLogPath()]; + const debugLog = getBooleanConfigValue(CONFIG_KEYS.lldbDapDebug, false); + let logPath; + if (debugLog) { + try { + const p = debugAdapterLogPath(); + const dir = nova.path.dirname(p); + if (!nova.fs.stat(dir)) nova.fs.mkdir(dir); + logPath = p; + } catch (_) {} + } + action.args = logPath + ? [lldbDapProxyPath(), lldbDapPath, logPath] + : [lldbDapProxyPath(), lldbDapPath]; action.debugRequest = "launch"; action.env = { DYLD_FRAMEWORK_PATH: lldbFrameworkPaths().join(":"), NOVA_ZIG_LLDB_DAP_PATH: lldbDapPath, - NOVA_ZIG_DEBUG_LOG: debugAdapterLogPath(), + ...(logPath ? { NOVA_ZIG_DEBUG_LOG: logPath } : {}), }; action.debugArgs = { program: programPath, diff --git a/extension.json b/extension.json index f9e76e9..a3302b1 100644 --- a/extension.json +++ b/extension.json @@ -19,7 +19,7 @@ ], "entitlements": { "process": true, - "filesystem": "readonly" + "filesystem": "readwrite" }, "debugAdapters": { "zig-lldb-dap": { @@ -88,6 +88,20 @@ "description": "Log ZLS traffic to the Extension Console while developing the extension." } ] + }, + { + "type": "section", + "title": "Debug Adapter", + "description": "Controls for the lldb-dap integration.", + "children": [ + { + "key": "at.dcz.nova-zig.debug-adapter.debug", + "title": "Enable Proxy Log", + "type": "boolean", + "default": false, + "description": "Write lldb-dap-proxy traffic to a log file in the extension's storage directory. For extension development only." + } + ] } ], "configWorkspace": [ @@ -143,6 +157,19 @@ "description": "Log ZLS traffic to the Extension Console while developing the extension." } ] + }, + { + "type": "section", + "title": "Debug Adapter", + "description": "Controls for the lldb-dap integration.", + "children": [ + { + "key": "at.dcz.nova-zig.debug-adapter.debug", + "title": "Enable Proxy Log", + "type": "boolean", + "description": "Write lldb-dap-proxy traffic to a log file in the extension's storage directory. For extension development only." + } + ] } ], "issueMatchers": { -- cgit v1.3