From 52660bb6594cb4ff16340ad990b8bb3d925b08aa Mon Sep 17 00:00:00 2001 From: "tayor.fish" Date: Mon, 24 Nov 2025 10:08:19 -0800 Subject: [PATCH] Try additional stack trace options --- cmake/CompilerFlags.cmake | 6 +-- src/bun.zig | 2 +- src/crash_handler.zig | 18 ++++++- src/env_var.zig | 1 + src/new_debug/cpu_context.zig | 88 +++++++++++++++++------------------ 5 files changed, 64 insertions(+), 51 deletions(-) diff --git a/cmake/CompilerFlags.cmake b/cmake/CompilerFlags.cmake index bff19e1974..c7276fdaa9 100644 --- a/cmake/CompilerFlags.cmake +++ b/cmake/CompilerFlags.cmake @@ -164,9 +164,9 @@ if(UNIX) ) register_compiler_flags( - DESCRIPTION "Disable unwind tables" - -fno-unwind-tables - -fno-asynchronous-unwind-tables + DESCRIPTION "ENABLE unwind tables" + -funwind-tables + -fasynchronous-unwind-tables ) # needed for libuv stubs because they use diff --git a/src/bun.zig b/src/bun.zig index 7ba582bee2..6b02ffc67e 100644 --- a/src/bun.zig +++ b/src/bun.zig @@ -2507,7 +2507,7 @@ pub const Dirname = struct { pub noinline fn outOfMemory() noreturn { @branchHint(.cold); - crash_handler.crashHandler(.out_of_memory, null, @returnAddress()); + crash_handler.crashHandler(.out_of_memory, null, @returnAddress(), null); } pub const handleOom = @import("./handle_oom.zig").handleOom; diff --git a/src/crash_handler.zig b/src/crash_handler.zig index 58f58592c6..89aaa8642d 100644 --- a/src/crash_handler.zig +++ b/src/crash_handler.zig @@ -200,6 +200,7 @@ pub fn crashHandler( // TODO: if both of these are specified, what is supposed to happen? error_return_trace: ?*std.builtin.StackTrace, begin_addr: ?usize, + ucontext: ?*const anyopaque, ) noreturn { @branchHint(.cold); @@ -356,8 +357,18 @@ pub fn crashHandler( std.debug.print("\n", .{}); var new_addrs: [20]usize = undefined; + std.debug.print("has ucontext? {any}\n", .{ucontext != null}); + const cpu_context = if (ucontext == null) + null + else + bun.new_debug.cpu_context.fromPosixSignalContext(ucontext); + std.debug.print("has cpu_context.Native? {any}\n", .{cpu_context != null}); + const bstd = bun.env_var.BUN_STACKTRACE_DEBUG.get(); + std.debug.print("bstd: {d}\n", .{bstd}); const new_trace = bun.new_debug.captureCurrentStackTrace(.{ .first_address = desired_begin_addr, + .context = if (bstd & 1 == 1) if (cpu_context) |*c| c else null else null, + .allow_unsafe_unwind = bstd & 2 == 1, }, &new_addrs); std.debug.print("new trace:", .{}); for (0..new_trace.index) |i| { @@ -809,6 +820,7 @@ pub fn panicImpl(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, .{ .panic = msg }, error_return_trace, begin_addr orelse @returnAddress(), + null, ); } @@ -850,7 +862,7 @@ const metadata_version_line = std.fmt.comptimePrint( }, ); -fn handleSegfaultPosix(sig: i32, info: *const std.posix.siginfo_t, _: ?*const anyopaque) callconv(.c) noreturn { +fn handleSegfaultPosix(sig: i32, info: *const std.posix.siginfo_t, ucontext: ?*const anyopaque) callconv(.c) noreturn { const addr = switch (bun.Environment.os) { .linux => @intFromPtr(info.fields.sigfault.addr), .mac => @intFromPtr(info.addr), @@ -869,6 +881,7 @@ fn handleSegfaultPosix(sig: i32, info: *const std.posix.siginfo_t, _: ?*const an }, null, @returnAddress(), + ucontext, ); } @@ -962,6 +975,7 @@ pub fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(.winapi }, null, @intFromPtr(info.ExceptionRecord.ExceptionAddress), + null, ); } @@ -2288,7 +2302,7 @@ export fn CrashHandler__unsupportedUVFunction(name: ?[*:0]const u8) callconv(.c) } export fn Bun__crashHandler(message_ptr: [*]u8, message_len: usize) noreturn { - crashHandler(.{ .panic = message_ptr[0..message_len] }, null, @returnAddress()); + crashHandler(.{ .panic = message_ptr[0..message_len] }, null, @returnAddress(), null); } export fn CrashHandler__setDlOpenAction(action: ?[*:0]const u8) void { diff --git a/src/env_var.zig b/src/env_var.zig index 13fea31056..2634e35e6a 100644 --- a/src/env_var.zig +++ b/src/env_var.zig @@ -37,6 +37,7 @@ pub const BUN_CONFIG_DISABLE_ioctl_ficlonerange = New(kind.boolean, "BUN_CONFIG_ /// /// It's unclear why this was done. pub const BUN_CONFIG_DNS_TIME_TO_LIVE_SECONDS = New(kind.unsigned, "BUN_CONFIG_DNS_TIME_TO_LIVE_SECONDS", .{ .default = 30 }); +pub const BUN_STACKTRACE_DEBUG = New(kind.unsigned, "BUN_STACKTRACE_DEBUG", .{ .default = 0 }); pub const BUN_CRASH_REPORT_URL = New(kind.string, "BUN_CRASH_REPORT_URL", .{}); pub const BUN_DEBUG = New(kind.string, "BUN_DEBUG", .{}); pub const BUN_DEBUG_ALL = New(kind.boolean, "BUN_DEBUG_ALL", .{}); diff --git a/src/new_debug/cpu_context.zig b/src/new_debug/cpu_context.zig index 6565185538..c2da30292b 100644 --- a/src/new_debug/cpu_context.zig +++ b/src/new_debug/cpu_context.zig @@ -36,7 +36,7 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native { const uc: *const signal_ucontext_t = @ptrCast(@alignCast(ctx_ptr)); // Deal with some special cases first. - if (native_arch.isArc() and native_os == .linux) { + if (false and native_arch.isArc() and native_os == .linux) { var native: Native = .{ .r = [_]u32{ uc.mcontext.r31, uc.mcontext.r30, 0, uc.mcontext.r28 } ++ uc.mcontext.r27_26 ++ @@ -112,7 +112,7 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native { .pc = uc.mcontext.pc, .lr = uc.mcontext.lr, }, - .riscv32, .riscv32be, .riscv64, .riscv64be => .{ + .riscv32, .riscv64 => .{ // You can thank FreeBSD and OpenBSD for this silliness; they decided to be cute and // group the registers by ABI mnemonic rather than register number. .x = [_]Riscv.Gpr{0} ++ @@ -1734,20 +1734,20 @@ const X86_64 = struct { const signal_ucontext_t = switch (native_os) { .linux => switch (native_arch) { // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/alpha/include/asm/ucontext.h - .alpha => extern struct { - _flags: u64, - _link: ?*signal_ucontext_t, - _osf_sigmask: u64, - _stack: std.os.linux.stack_t, - // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/alpha/include/uapi/asm/sigcontext.h - mcontext: extern struct { - _onstack: i64, - _mask: i64, - pc: u64, - _ps: i64, - r: [32]u64, - }, - }, + //.alpha => extern struct { + // _flags: u64, + // _link: ?*signal_ucontext_t, + // _osf_sigmask: u64, + // _stack: std.os.linux.stack_t, + // // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/alpha/include/uapi/asm/sigcontext.h + // mcontext: extern struct { + // _onstack: i64, + // _mask: i64, + // pc: u64, + // _ps: i64, + // r: [32]u64, + // }, + //}, // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/arm64/include/uapi/asm/ucontext.h .aarch64, .aarch64_be, @@ -1809,7 +1809,6 @@ const signal_ucontext_t = switch (native_os) { }, // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/include/uapi/asm-generic/ucontext.h .arc, - .arceb, .arm, .armeb, .thumb, @@ -1826,14 +1825,13 @@ const signal_ucontext_t = switch (native_os) { .x86, .x86_64, .xtensa, - .xtensaeb, => extern struct { _flags: usize, _link: ?*signal_ucontext_t, _stack: std.os.linux.stack_t, mcontext: switch (native_arch) { // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/arc/include/uapi/asm/sigcontext.h - .arc, .arceb => extern struct { + .arc => extern struct { _pad1: u32, _bta: u32, _lp: extern struct { @@ -1887,20 +1885,20 @@ const signal_ucontext_t = switch (native_os) { pc: u32, }, // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/parisc/include/uapi/asm/sigcontext.h - .hppa => extern struct { - _flags: u32, - _psw: u32, - r1_19: [19]u32, - r20: u32, - r21: u32, - r22: u32, - r23_29: [7]u32, - r30: u32, - r31: u32, - _fr: [32]f64, - _iasq: [2]u32, - iaoq: [2]u32, - }, + //.hppa => extern struct { + // _flags: u32, + // _psw: u32, + // r1_19: [19]u32, + // r20: u32, + // r21: u32, + // r22: u32, + // r23_29: [7]u32, + // r30: u32, + // r31: u32, + // _fr: [32]f64, + // _iasq: [2]u32, + // iaoq: [2]u32, + //}, // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/m68k/include/asm/ucontext.h .m68k => extern struct { _version: i32, @@ -1909,10 +1907,10 @@ const signal_ucontext_t = switch (native_os) { pc: u32, }, // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/microblaze/include/uapi/asm/sigcontext.h - .microblaze, .microblazeel => extern struct { - r: [32]u32, - pc: u32, - }, + //.microblaze, .microblazeel => extern struct { + // r: [32]u32, + // pc: u32, + //}, // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/mips/include/uapi/asm/sigcontext.h .mips, .mipsel => extern struct { _regmask: u32, @@ -1943,12 +1941,12 @@ const signal_ucontext_t = switch (native_os) { r: [16]u64, }, // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/sh/include/uapi/asm/sigcontext.h - .sh, .sheb => extern struct { - _oldmask: u32, - r: [16]u32, - pc: u32, - pr: u32, - }, + //.sh, .sheb => extern struct { + // _oldmask: u32, + // r: [16]u32, + // pc: u32, + // pr: u32, + //}, // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/x86/include/uapi/asm/sigcontext.h .x86 => extern struct { _gs: u32, @@ -1988,7 +1986,7 @@ const signal_ucontext_t = switch (native_os) { rip: u64, }, // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/xtensa/include/uapi/asm/sigcontext.h - .xtensa, .xtensaeb => extern struct { + .xtensa => extern struct { pc: u32, _ps: u32, _l: extern struct { @@ -2129,7 +2127,7 @@ const signal_ucontext_t = switch (native_os) { }, }, // https://github.com/ziglang/zig/blob/60be67d3c0ba6ae15fa7115596734ab1e74fbcd3/lib/libc/include/any-macos-any/sys/_types/_ucontext.h - .driverkit, .ios, .maccatalyst, .macos, .tvos, .watchos, .visionos => extern struct { + .driverkit, .ios, .macos, .tvos, .watchos, .visionos => extern struct { _onstack: i32, _sigmask: std.c.sigset_t, _stack: std.c.stack_t,