mirror of
https://github.com/oven-sh/bun
synced 2026-02-16 13:51:47 +00:00
try to find a default port with runtime inspector in tests?
This commit is contained in:
@@ -39,6 +39,7 @@ pub const Run = struct {
|
||||
.debugger = ctx.runtime_options.debugger,
|
||||
.dns_result_order = DNSResolver.Order.fromStringOrDie(ctx.runtime_options.dns_result_order),
|
||||
.disable_sigusr1 = ctx.runtime_options.disable_sigusr1,
|
||||
.inspect_port = ctx.runtime_options.inspect_port,
|
||||
}),
|
||||
.arena = arena,
|
||||
.ctx = ctx,
|
||||
@@ -188,6 +189,7 @@ pub const Run = struct {
|
||||
.dns_result_order = DNSResolver.Order.fromStringOrDie(ctx.runtime_options.dns_result_order),
|
||||
.is_main_thread = true,
|
||||
.disable_sigusr1 = ctx.runtime_options.disable_sigusr1,
|
||||
.inspect_port = ctx.runtime_options.inspect_port,
|
||||
},
|
||||
),
|
||||
.arena = arena,
|
||||
|
||||
@@ -164,6 +164,9 @@ hot_reload_counter: u32 = 0,
|
||||
|
||||
debugger: ?jsc.Debugger = null,
|
||||
has_started_debugger: bool = false,
|
||||
/// Pre-configured inspector port for runtime activation (via --inspect-port).
|
||||
/// Used by RuntimeInspector when SIGUSR1/process._debugProcess activates the inspector.
|
||||
inspect_port: ?[]const u8 = null,
|
||||
has_terminated: bool = false,
|
||||
|
||||
debug_thread_id: if (Environment.allow_assert) std.Thread.Id else void,
|
||||
@@ -1083,6 +1086,7 @@ pub fn initWithModuleGraph(
|
||||
uws.Loop.get().internal_loop_data.jsc_vm = vm.jsc_vm;
|
||||
|
||||
vm.configureDebugger(opts.debugger);
|
||||
vm.inspect_port = opts.inspect_port;
|
||||
vm.body_value_hive_allocator = Body.Value.HiveAllocator.init(bun.typedAllocator(jsc.WebCore.Body.Value));
|
||||
|
||||
configureSigusr1Handler(vm, opts);
|
||||
@@ -1115,6 +1119,8 @@ pub const Options = struct {
|
||||
destruct_main_thread_on_exit: bool = false,
|
||||
/// Disable SIGUSR1 handler for runtime debugger activation (matches Node.js).
|
||||
disable_sigusr1: bool = false,
|
||||
/// Pre-configured inspector port for runtime activation (--inspect-port).
|
||||
inspect_port: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
/// Configure SIGUSR1 handling for runtime debugger activation (main thread only).
|
||||
@@ -1280,8 +1286,15 @@ fn configureDebugger(this: *VirtualMachine, cli_flag: bun.cli.Command.Debugger)
|
||||
}
|
||||
},
|
||||
.enable => {
|
||||
// If --inspect/--inspect-brk/--inspect-wait is used without an explicit port,
|
||||
// use --inspect-port if provided.
|
||||
const path_or_port = if (cli_flag.enable.path_or_port.len == 0)
|
||||
this.inspect_port orelse cli_flag.enable.path_or_port
|
||||
else
|
||||
cli_flag.enable.path_or_port;
|
||||
|
||||
this.debugger = .{
|
||||
.path_or_port = cli_flag.enable.path_or_port,
|
||||
.path_or_port = path_or_port,
|
||||
.from_environment_variable = unix,
|
||||
.wait_for_connection = if (cli_flag.enable.wait_for_connection) .forever else wait_for_connection,
|
||||
.set_breakpoint_on_first_line = set_breakpoint_on_first_line or cli_flag.enable.set_breakpoint_on_first_line,
|
||||
|
||||
@@ -28,11 +28,9 @@ const RuntimeInspector = @This();
|
||||
const log = Output.scoped(.RuntimeInspector, .hidden);
|
||||
|
||||
/// Default port for runtime-activated inspector (via SIGUSR1/process._debugProcess).
|
||||
/// Note: If this port is already in use, activation will fail with an error message.
|
||||
/// This matches Node.js behavior where SIGUSR1-activated inspectors also use a fixed
|
||||
/// port (9229). Users can pre-configure a different port using --inspect-port=<port>
|
||||
/// or --inspect=0 for automatic port selection when starting the process.
|
||||
const inspector_port = "6499";
|
||||
/// If the user pre-configured a port via --inspect-port=<port>, that port is used
|
||||
/// instead. Use --inspect-port=0 for automatic port selection.
|
||||
const default_inspector_port = "6499";
|
||||
|
||||
var installed: std.atomic.Value(bool) = std.atomic.Value(bool).init(false);
|
||||
var inspector_activation_requested: std.atomic.Value(bool) = std.atomic.Value(bool).init(false);
|
||||
@@ -104,7 +102,7 @@ fn activateInspector(vm: *VirtualMachine) !void {
|
||||
log("Activating inspector", .{});
|
||||
|
||||
vm.debugger = .{
|
||||
.path_or_port = inspector_port,
|
||||
.path_or_port = vm.inspect_port orelse default_inspector_port,
|
||||
.from_environment_variable = "",
|
||||
.wait_for_connection = .off,
|
||||
.set_breakpoint_on_first_line = false,
|
||||
|
||||
@@ -405,6 +405,8 @@ pub const Command = struct {
|
||||
} = .{},
|
||||
/// Disable SIGUSR1 handler for runtime debugger activation
|
||||
disable_sigusr1: bool = false,
|
||||
/// Pre-configure inspector port for runtime activation (SIGUSR1/process._debugProcess)
|
||||
inspect_port: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
var global_cli_ctx: Context = undefined;
|
||||
|
||||
@@ -87,6 +87,7 @@ pub const runtime_params_ = [_]ParamType{
|
||||
clap.parseParam("--inspect <STR>? Activate Bun's debugger") catch unreachable,
|
||||
clap.parseParam("--inspect-wait <STR>? Activate Bun's debugger, wait for a connection before executing") catch unreachable,
|
||||
clap.parseParam("--inspect-brk <STR>? Activate Bun's debugger, set breakpoint on first line of code and wait") catch unreachable,
|
||||
clap.parseParam("--inspect-port <STR> Set inspector port for runtime debugger activation (0 for random)") catch unreachable,
|
||||
clap.parseParam("--disable-sigusr1 Disable SIGUSR1 handler for runtime debugger activation") catch unreachable,
|
||||
clap.parseParam("--cpu-prof Start CPU profiler and write profile to disk on exit") catch unreachable,
|
||||
clap.parseParam("--cpu-prof-name <STR> Specify the name of the CPU profile file") catch unreachable,
|
||||
@@ -811,6 +812,7 @@ pub fn parse(allocator: std.mem.Allocator, ctx: Command.Context, comptime cmd: C
|
||||
ctx.runtime_options.preconnect = args.options("--fetch-preconnect");
|
||||
ctx.runtime_options.expose_gc = args.flag("--expose-gc");
|
||||
ctx.runtime_options.disable_sigusr1 = args.flag("--disable-sigusr1");
|
||||
ctx.runtime_options.inspect_port = args.option("--inspect-port");
|
||||
|
||||
if (args.option("--console-depth")) |depth_str| {
|
||||
const depth = std.fmt.parseInt(u16, depth_str, 10) catch {
|
||||
|
||||
@@ -1399,6 +1399,7 @@ pub const TestCommand = struct {
|
||||
.debugger = ctx.runtime_options.debugger,
|
||||
.is_main_thread = true,
|
||||
.disable_sigusr1 = ctx.runtime_options.disable_sigusr1,
|
||||
.inspect_port = ctx.runtime_options.inspect_port,
|
||||
},
|
||||
);
|
||||
vm.argv = ctx.passthrough;
|
||||
|
||||
@@ -223,9 +223,9 @@ describe.skipIf(!isWindows)("Runtime inspector Windows file mapping", () => {
|
||||
});
|
||||
|
||||
test("multiple Windows processes can have inspectors sequentially", async () => {
|
||||
// Note: Runtime inspector uses hardcoded port 6499, so we must test
|
||||
// sequential activation (activate first, shut down, then activate second)
|
||||
// rather than concurrent activation.
|
||||
// Test sequential activation: activate first, shut down, then activate second.
|
||||
// Each process uses a random port, so concurrent would also work, but
|
||||
// sequential tests the full lifecycle.
|
||||
using dir = tempDir("windows-multi-test", {
|
||||
"target.js": `
|
||||
const fs = require("fs");
|
||||
@@ -284,7 +284,7 @@ describe.skipIf(!isWindows)("Runtime inspector Windows file mapping", () => {
|
||||
await target1.exited;
|
||||
}
|
||||
|
||||
// Second process: now that first is shut down, port 6499 is free
|
||||
// Second process
|
||||
{
|
||||
await using target2 = spawn({
|
||||
cmd: [bunExe(), "target.js", "2"],
|
||||
|
||||
@@ -24,9 +24,9 @@ async function waitForDebuggerListening(
|
||||
// The banner format is:
|
||||
// --------------------- Bun Inspector ---------------------
|
||||
// Listening:
|
||||
// ws://localhost:6499/...
|
||||
// ws://localhost:<port>/...
|
||||
// Inspect in browser:
|
||||
// https://debug.bun.sh/#localhost:6499/...
|
||||
// https://debug.bun.sh/#localhost:<port>/...
|
||||
// --------------------- Bun Inspector ---------------------
|
||||
try {
|
||||
while ((stderr.match(/Bun Inspector/g) || []).length < 2) {
|
||||
@@ -54,7 +54,7 @@ describe("Runtime inspector activation", () => {
|
||||
test.skipIf(skipASAN)("activates inspector in target process", async () => {
|
||||
// Start target process - prints PID to stdout then stays alive
|
||||
await using targetProc = spawn({
|
||||
cmd: [bunExe(), "-e", `console.log(process.pid); setInterval(() => {}, 1000);`],
|
||||
cmd: [bunExe(), "--inspect-port=0", "-e", `console.log(process.pid); setInterval(() => {}, 1000);`],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
@@ -108,7 +108,7 @@ describe("Runtime inspector activation", () => {
|
||||
test.skipIf(skipASAN)("inspector does not activate twice", async () => {
|
||||
// Start target process - prints PID to stdout then stays alive
|
||||
await using targetProc = spawn({
|
||||
cmd: [bunExe(), "-e", `console.log(process.pid); setInterval(() => {}, 1000);`],
|
||||
cmd: [bunExe(), "--inspect-port=0", "-e", `console.log(process.pid); setInterval(() => {}, 1000);`],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
@@ -170,15 +170,15 @@ describe("Runtime inspector activation", () => {
|
||||
});
|
||||
|
||||
test.skipIf(skipASAN)("can activate inspector in multiple processes sequentially", async () => {
|
||||
// Note: Runtime inspector uses hardcoded port 6499, so we must test
|
||||
// sequential activation (activate first, shut down, then activate second)
|
||||
// rather than concurrent activation.
|
||||
// Test sequential activation: activate first, shut down, then activate second.
|
||||
// Each process uses a random port, so concurrent would also work, but
|
||||
// sequential tests the full lifecycle.
|
||||
const targetScript = `console.log(process.pid); setInterval(() => {}, 1000);`;
|
||||
|
||||
// First process: activate inspector, verify, then shut down
|
||||
{
|
||||
await using target1 = spawn({
|
||||
cmd: [bunExe(), "-e", targetScript],
|
||||
cmd: [bunExe(), "--inspect-port=0", "-e", targetScript],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
@@ -209,10 +209,10 @@ describe("Runtime inspector activation", () => {
|
||||
await target1.exited;
|
||||
}
|
||||
|
||||
// Second process: now that first is shut down, port 6499 is free
|
||||
// Second process
|
||||
{
|
||||
await using target2 = spawn({
|
||||
cmd: [bunExe(), "-e", targetScript],
|
||||
cmd: [bunExe(), "--inspect-port=0", "-e", targetScript],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
@@ -260,7 +260,7 @@ describe("Runtime inspector activation", () => {
|
||||
test.skipIf(skipASAN)("can interrupt an infinite loop", async () => {
|
||||
// Start target process with infinite loop
|
||||
await using targetProc = spawn({
|
||||
cmd: [bunExe(), "-e", `console.log(process.pid); while (true) {}`],
|
||||
cmd: [bunExe(), "--inspect-port=0", "-e", `console.log(process.pid); while (true) {}`],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
@@ -299,7 +299,7 @@ describe("Runtime inspector activation", () => {
|
||||
test.skipIf(skipASAN)("can pause execution during while(true) via CDP", async () => {
|
||||
// Start target process with infinite loop
|
||||
await using targetProc = spawn({
|
||||
cmd: [bunExe(), "-e", `console.log(process.pid); while (true) {}`],
|
||||
cmd: [bunExe(), "--inspect-port=0", "-e", `console.log(process.pid); while (true) {}`],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
@@ -387,7 +387,7 @@ describe("Runtime inspector activation", () => {
|
||||
test.skipIf(skipASAN)("CDP messages work after client reconnects", async () => {
|
||||
// Start target process - prints PID to stdout then stays alive
|
||||
await using targetProc = spawn({
|
||||
cmd: [bunExe(), "-e", `console.log(process.pid); setInterval(() => {}, 1000);`],
|
||||
cmd: [bunExe(), "--inspect-port=0", "-e", `console.log(process.pid); setInterval(() => {}, 1000);`],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
|
||||
Reference in New Issue
Block a user