Hey! I'm trying to enable debugging for StarlingMonkey components that don't target WASI/HTTP. Based on my understanding this should be possible by:
The problem is that after calling content_debugger::maybe_init_debugger from step 2, the function cannot access the environment variables needed for debugger configuration (such as DEBUGGER_PORT) that I pass to the wasmtime run command.
I see that the environment is deinitialized after wizening, which makes sense to avoid polluting variables from the wizening pass. I tried to call __wasilibc_initialize_environ again within the debugger initialization function, but the environment list remains empty.
Does anyone know why the environment variables aren't being set? Why would this work when we have http handler installed but not for an arbitrary entrypoint?
With those changes I would also hope to fix the implicit dependency on wasi/environement by moving this call to debugger initialization so that it is gated behind debugger opt-in.
package component:greeter;
interface greeter {
hello-user: func(user: string);
}
world example {
import wasi:cli/environment@0.2.3;
import wasi:sockets/network@0.2.3;
import wasi:sockets/instance-network@0.2.3;
import wasi:sockets/tcp@0.2.3;
import wasi:sockets/tcp-create-socket@0.2.3;
export greeter;
}
export const greeter = {
helloUser(user) {
console.log("Hello", user);
}
}
componentize-js --aot --wit wit --world-name example --runtime-args "--enable-script-debugging" -o out.wasm index.js
wasmtime run -S cli,tcp,http --dir /home/tandr/workspace/sm-debug/::/ --invoke 'hello-user("Gordon Shumway")' out.wasm --env STARLINGMONKEY_CONFIG="--verbose -d" --env DEBUGGER_PORT=64373
The ComponentizeJS diff looks like this:
diff --git a/embedding/embedding.cpp b/embedding/embedding.cpp
index 585f3ed..60ba219 100644
--- a/embedding/embedding.cpp
+++ b/embedding/embedding.cpp
@@ -1,4 +1,5 @@
#include "embedding.h"
+#include "debugger.h"
#include "builtins/web/performance.h"
namespace builtins::web::console {
@@ -147,6 +148,7 @@ cabi_realloc(void *ptr, size_t orig_size, size_t org_align, size_t new_size) {
__attribute__((export_name("call"))) uint32_t call(uint32_t fn_idx,
void *argptr) {
if (Runtime.first_call) {
+ content_debugger::maybe_init_debugger(Runtime.engine, true);
js::ResetMathRandomSeed(Runtime.cx);
Runtime.first_call = false;
if (Runtime.clocks) {
The StarlingMonkey diff:
diff --git a/host-apis/wasi-0.2.0/host_api.cpp b/host-apis/wasi-0.2.0/host_api.cpp
index e87bd9e..e33ec36 100644
--- a/host-apis/wasi-0.2.0/host_api.cpp
+++ b/host-apis/wasi-0.2.0/host_api.cpp
@@ -2,8 +2,6 @@
#include "bindings/bindings.h"
#include "handles.h"
-#include <wasi/libc-environ.h>
-
static std::optional<wasi_clocks_monotonic_clock_own_pollable_t> immediately_ready;
size_t poll_handles(vector<WASIHandle<host_api::Pollable>::Borrowed> handles) {
@@ -1032,9 +1030,6 @@ void exports_wasi_http_incoming_handler(exports_wasi_http_incoming_request reque
// that it properly initializes the runtime and installs a request handler.
if (!REQUEST_HANDLER) {
init_from_environment();
- } else {
- // Resuming a wizer snapshot, so we have to ensure that the environment is reset.
- __wasilibc_initialize_environ();
}
MOZ_ASSERT(REQUEST_HANDLER);
diff --git a/runtime/debugger.cpp b/runtime/debugger.cpp
index e81dcaa..dececee 100644
--- a/runtime/debugger.cpp
+++ b/runtime/debugger.cpp
@@ -4,6 +4,8 @@
#include <encode.h>
#include <js/CompilationAndEvaluation.h>
#include <js/SourceText.h>
+#include <wasi/libc-environ.h>
+
#include <string_view>
mozilla::Maybe<std::string> main_path;
@@ -278,6 +280,10 @@ void content_debugger::maybe_init_debugger(api::Engine * engine, bool content_al
return;
}
debugger_initialized = true;
+
+ // Resuming a wizer snapshot, so we have to ensure that the environment is reset.
+ __wasilibc_initialize_environ();
+
auto port_str = std::getenv("DEBUGGER_PORT");
if (port_str) {
uint32_t port = std::stoi(port_str);
I think I've found what was the issue:
wasmtime run command is interpreting everything after positional argument as an input to WASM module, or when using invoke option, an input to specified function as per trailing_var_arg = true setting:
https://github.com/bytecodealliance/wasmtime/blob/main/src/commands/run.rs#L80
The debugger plugin is appending the --env options to componentRuntime , so when I switch the debugger command from serve to run all appended env variables are being parsed as an module input not actual wasmtime options.
As a side note, I think requiring -- to separate wasmtime options from WASM arguments could be beneficial.
Last updated: Dec 06 2025 at 07:03 UTC