Compare commits

...

1 Commits

Author SHA1 Message Date
Claude Bot
d2ff0deef6 Replace std.debug.captureStackTrace with WTFGetBacktrace
This change replaces all usages of std.debug.captureStackTrace in
crash_handler.zig with WTFGetBacktrace from WebKit's WTF library.

Changes:
- Added Bun__WTFGetBacktrace binding in c-bindings.cpp that wraps
  WTFGetBacktrace and handles the case where first_addr is non-null
- Created a Zig wrapper function captureStackTrace() that calls the
  C binding with proper type conversions
- Replaced all 3 occurrences of std.debug.captureStackTrace in
  crash_handler.zig with the new wrapper

The WTFGetBacktrace implementation provides better backtrace capture
across different platforms and integrates well with the existing
WTF infrastructure used in Bun.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-12 18:49:55 +00:00
2 changed files with 48 additions and 3 deletions

View File

@@ -973,3 +973,32 @@ extern "C" uint8_t* Bun__getStandaloneModuleGraphPEData()
}
#endif
extern "C" void Bun__WTFGetBacktrace(void** stack, int* size, void* first_addr)
{
if (first_addr) {
// If we have a first_addr, we need to handle it specially
if (*size <= 0) {
return;
}
// Store the first address at the beginning
stack[0] = first_addr;
// If there's only room for one frame, we're done
if (*size == 1) {
return;
}
// Get the remaining frames starting from index 1
int remaining_size = *size - 1;
void** remaining_stack = stack + 1;
WTFGetBacktrace(remaining_stack, &remaining_size);
// Update the actual size (first_addr + captured frames)
*size = remaining_size + 1;
} else {
// No first_addr, just call WTFGetBacktrace directly
WTFGetBacktrace(stack, size);
}
}

View File

@@ -319,7 +319,7 @@ pub fn crashHandler(
.index = 0,
.instruction_addresses = &addr_buf,
};
std.debug.captureStackTrace(begin_addr orelse @returnAddress(), &trace_buf);
captureStackTrace(begin_addr orelse @returnAddress(), &trace_buf);
break :get_backtrace &trace_buf;
};
@@ -1605,6 +1605,22 @@ pub inline fn handleErrorReturnTrace(err: anyerror, maybe_trace: ?*std.builtin.S
handleErrorReturnTraceExtra(err, maybe_trace, false);
}
extern "c" fn WTF__DumpStackTrace(ptr: [*]usize, count: usize) void;
extern "c" fn Bun__WTFGetBacktrace(stack: [*]?*anyopaque, size: *c_int, first_addr: ?*anyopaque) void;
/// Capture a stack trace using WTFGetBacktrace instead of std.debug.captureStackTrace.
/// This function handles the case where first_addr is non-null by passing it to the C function.
inline fn captureStackTrace(first_addr: ?usize, trace: *std.builtin.StackTrace) void {
const max_frames = trace.instruction_addresses.len;
var size: c_int = @intCast(max_frames);
// WTFGetBacktrace expects void** but we have [*]usize
// We need to cast properly
const stack_ptr: [*]?*anyopaque = @ptrCast(trace.instruction_addresses.ptr);
const first_addr_ptr: ?*anyopaque = if (first_addr) |addr| @ptrFromInt(addr) else null;
Bun__WTFGetBacktrace(stack_ptr, &size, first_addr_ptr);
trace.index = @intCast(size);
}
/// Version of the standard library dumpStackTrace that has some fallbacks for
/// cases where such logic fails to run.
@@ -1723,7 +1739,7 @@ fn spawnSymbolizer(program: [:0]const u8, alloc: std.mem.Allocator, trace: *cons
pub fn dumpCurrentStackTrace(first_address: ?usize, limits: WriteStackTraceLimits) void {
var addrs: [32]usize = undefined;
var stack: std.builtin.StackTrace = .{ .index = 0, .instruction_addresses = &addrs };
std.debug.captureStackTrace(first_address orelse @returnAddress(), &stack);
captureStackTrace(first_address orelse @returnAddress(), &stack);
dumpStackTrace(stack, limits);
}
@@ -1772,7 +1788,7 @@ pub const StoredTrace = struct {
pub fn capture(begin: ?usize) StoredTrace {
var stored: StoredTrace = StoredTrace.empty;
var frame = stored.trace();
std.debug.captureStackTrace(begin orelse @returnAddress(), &frame);
captureStackTrace(begin orelse @returnAddress(), &frame);
stored.index = frame.index;
for (frame.instruction_addresses[0..frame.index], 0..) |addr, i| {
if (addr == 0) {