aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-11 00:19:50 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-11 00:20:42 -0800
commit2432150321d94eae21013d2175a96e557fd207e5 (patch)
treee34fe8ed3ffc4aa41d749f943239186f27ae2b8e /src
parent38141e3aa7c2db5b01a6fd9a97776f9257a10049 (diff)
downloadbun-2432150321d94eae21013d2175a96e557fd207e5.tar.gz
bun-2432150321d94eae21013d2175a96e557fd207e5.tar.zst
bun-2432150321d94eae21013d2175a96e557fd207e5.zip
Replace `libbacktrace` with `WTFGetBacktrace`
Diffstat (limited to 'src')
-rw-r--r--src/bun.js/bindings/exports.zig2
-rw-r--r--src/bun.js/bindings/wtf-bindings.cpp34
-rw-r--r--src/bun.js/module_loader.zig1
-rw-r--r--src/crash_reporter.zig50
-rw-r--r--src/deps/backtrace.zig148
-rw-r--r--src/main.zig8
-rw-r--r--src/report.zig20
7 files changed, 105 insertions, 158 deletions
diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig
index e6ccc039e..2e2c5e556 100644
--- a/src/bun.js/bindings/exports.zig
+++ b/src/bun.js/bindings/exports.zig
@@ -26,7 +26,7 @@ const JSModuleLoader = JSC.JSModuleLoader;
const JSModuleRecord = JSC.JSModuleRecord;
const Microtask = JSC.Microtask;
const JSPrivateDataPtr = @import("../base.zig").JSPrivateDataPtr;
-const Backtrace = @import("../../deps/backtrace.zig");
+const Backtrace = @import("../../crash_reporter.zig");
const JSPrinter = @import("../../js_printer.zig");
const JSLexer = @import("../../js_lexer.zig");
const typeBaseName = @import("../../meta.zig").typeBaseName;
diff --git a/src/bun.js/bindings/wtf-bindings.cpp b/src/bun.js/bindings/wtf-bindings.cpp
index 561c83ffa..d1d73a891 100644
--- a/src/bun.js/bindings/wtf-bindings.cpp
+++ b/src/bun.js/bindings/wtf-bindings.cpp
@@ -1,6 +1,8 @@
#include "wtf-bindings.h"
#include "wtf/text/Base64.h"
+#include "wtf/StackTrace.h"
+
extern "C" void WTF__copyLCharsFromUCharSource(LChar* destination, const UChar* source, size_t length)
{
WTF::StringImpl::copyCharacters(destination, source, length);
@@ -11,4 +13,36 @@ extern "C" JSC::EncodedJSValue WTF__toBase64URLStringValue(const uint8_t* bytes,
WTF::String string = WTF::base64URLEncodeToString(reinterpret_cast<const LChar*>(bytes), static_cast<unsigned int>(length));
string.impl()->ref();
return JSC::JSValue::encode(JSC::jsString(globalObject->vm(), string));
+}
+
+extern "C" void Bun__crashReportWrite(void* ctx, const char* message, size_t length);
+extern "C" void Bun__crashReportDumpStackTrace(void* ctx)
+{
+ static constexpr int framesToShow = 32;
+ static constexpr int framesToSkip = 4;
+ void* stack[framesToShow + framesToSkip];
+ int frames = framesToShow + framesToSkip;
+ WTFGetBacktrace(stack, &frames);
+ bool isFirst = true;
+ WTF::StackTraceSymbolResolver { { stack, static_cast<size_t>(frames) } }.forEach([&](int frameNumber, void* stackFrame, const char* name) {
+ if (frameNumber < framesToSkip)
+ return;
+
+ StringPrintStream out;
+ if (isFirst) {
+ isFirst = false;
+ if (name)
+ out.printf("\n%-3d %p %s", frameNumber, stackFrame, name);
+ else
+ out.printf("\n%-3d %p", frameNumber, stackFrame);
+ } else {
+ if (name)
+ out.printf("%-3d %p %s", frameNumber, stackFrame, name);
+ else
+ out.printf("%-3d %p", frameNumber, stackFrame);
+ }
+
+ auto str = out.toCString();
+ Bun__crashReportWrite(ctx, str.data(), str.length());
+ });
} \ No newline at end of file
diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig
index 82e96c8ed..59a4288fb 100644
--- a/src/bun.js/module_loader.zig
+++ b/src/bun.js/module_loader.zig
@@ -1357,6 +1357,7 @@ pub const ModuleLoader = struct {
if (err == error.AsyncModule) {
unreachable;
}
+
VirtualMachine.processFetchLog(globalObject, specifier.*, referrer.*, &log, ret, err);
return true;
}) |builtin| {
diff --git a/src/crash_reporter.zig b/src/crash_reporter.zig
new file mode 100644
index 000000000..4d98b47f4
--- /dev/null
+++ b/src/crash_reporter.zig
@@ -0,0 +1,50 @@
+const std = @import("std");
+
+fn setup_sigactions(act: ?*const os.Sigaction) !void {
+ try os.sigaction(os.SIG.ABRT, act, null);
+ try os.sigaction(os.SIG.BUS, act, null);
+ try os.sigaction(os.SIG.FPE, act, null);
+ try os.sigaction(os.SIG.ILL, act, null);
+ try os.sigaction(os.SIG.SEGV, act, null);
+ try os.sigaction(os.SIG.TRAP, act, null);
+}
+
+const builtin = @import("builtin");
+const ErrorCallback = fn (sig: i32, addr: usize) void;
+var on_error: ?ErrorCallback = null;
+noinline fn sigaction_handler(sig: i32, info: *const std.os.siginfo_t, _: ?*const anyopaque) callconv(.C) void {
+ // Prevent recursive calls
+ setup_sigactions(null) catch unreachable;
+
+ const addr = switch (comptime builtin.target.os.tag) {
+ .linux => @ptrToInt(info.fields.sigfault.addr),
+ .macos, .freebsd => @ptrToInt(info.addr),
+ .netbsd => @ptrToInt(info.info.reason.fault.addr),
+ .openbsd => @ptrToInt(info.data.fault.addr),
+ .solaris => @ptrToInt(info.reason.fault.addr),
+ else => unreachable,
+ };
+ if (on_error) |handle| handle(sig, addr);
+}
+
+pub fn reloadHandlers() !void {
+ try setup_sigactions(null);
+
+ var act = os.Sigaction{
+ .handler = .{ .sigaction = sigaction_handler },
+ .mask = os.empty_sigset,
+ .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
+ };
+
+ try setup_sigactions(&act);
+}
+const os = std.os;
+pub fn start() !void {
+ var act = os.Sigaction{
+ .handler = .{ .sigaction = sigaction_handler },
+ .mask = os.empty_sigset,
+ .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
+ };
+
+ try setup_sigactions(&act);
+}
diff --git a/src/deps/backtrace.zig b/src/deps/backtrace.zig
index 47293d1cf..e69de29bb 100644
--- a/src/deps/backtrace.zig
+++ b/src/deps/backtrace.zig
@@ -1,148 +0,0 @@
-const Environment = @import("../env.zig");
-pub const backtrace_state = struct_backtrace_state;
-pub const struct_backtrace_state = opaque {};
-pub const backtrace_error_callback = ?fn (
- ?*anyopaque,
- [*c]const u8,
- c_int,
-) callconv(.C) void;
-pub extern fn backtrace_create_state(
- filename: [*c]const u8,
- threaded: c_int,
- error_callback: backtrace_error_callback,
- data: ?*anyopaque,
-) ?*struct_backtrace_state;
-pub const backtrace_full_callback = ?fn (
- ?*anyopaque,
- usize,
- [*c]const u8,
- c_int,
- [*c]const u8,
-) callconv(.C) c_int;
-pub extern fn backtrace_full(
- state: ?*struct_backtrace_state,
- skip: c_int,
- callback: backtrace_full_callback,
- error_callback: backtrace_error_callback,
- data: ?*anyopaque,
-) c_int;
-pub const backtrace_simple_callback = ?fn (?*anyopaque, usize) callconv(.C) c_int;
-pub extern fn backtrace_simple(
- state: ?*struct_backtrace_state,
- skip: c_int,
- callback: backtrace_simple_callback,
- error_callback: backtrace_error_callback,
- data: ?*anyopaque,
-) c_int;
-pub extern fn backtrace_print(state: ?*struct_backtrace_state, skip: c_int, [*c]anyopaque) void;
-pub extern fn backtrace_pcinfo(
- state: ?*struct_backtrace_state,
- pc: usize,
- callback: backtrace_full_callback,
- error_callback: backtrace_error_callback,
- data: ?*anyopaque,
-) c_int;
-pub const backtrace_syminfo_callback = ?fn (?*anyopaque, usize, [*c]const u8, usize, usize) callconv(.C) void;
-pub extern fn backtrace_syminfo(
- state: ?*struct_backtrace_state,
- addr: usize,
- callback: backtrace_syminfo_callback,
- error_callback: backtrace_error_callback,
- data: ?*anyopaque,
-) c_int;
-
-pub const BACKTRACE_SUPPORTED = @as(c_int, 1);
-pub const BACKTRACE_USES_MALLOC = @as(c_int, 0);
-pub const BACKTRACE_SUPPORTS_THREADS = @as(c_int, 1);
-pub const BACKTRACE_SUPPORTS_DATA = @as(c_int, 1);
-
-fn error_callback(data: *anyopaque, msg: [*c]u8, errnum: c_int) callconv(.C) void {
- _ = data;
- _ = msg;
- _ = errnum;
-}
-
-pub const StackFrame = struct {
- pc: usize,
- filename: []const u8,
- function_name: []const u8,
- line_number: c_int,
-};
-
-pub const PrintCallback = fn (ctx: ?*anyopaque, frame: StackFrame) void;
-
-var callback: PrintCallback = undefined;
-var callback_ctx: ?*anyopaque = null;
-
-const std = @import("std");
-
-noinline fn full_callback(_: ?*anyopaque, pc: usize, filename: [*c]const u8, line_number: c_int, function_name: [*c]const u8) callconv(.C) c_int {
- var stack_frame = StackFrame{
- .pc = pc,
- .line_number = line_number,
- .function_name = if (function_name) |fn_| std.mem.span(fn_) else "",
- .filename = if (filename) |fn_| std.mem.span(fn_) else "",
- };
- callback(callback_ctx, stack_frame);
- return 0;
-}
-
-var state: ?*backtrace_state = null;
-pub inline fn print() void {
- if (Environment.isMac) return;
- state = backtrace_create_state(null, BACKTRACE_SUPPORTS_THREADS, null, null);
- _ = backtrace_full(state, 2, full_callback, null, null);
-}
-
-fn setup_sigactions(act: ?*const os.Sigaction) !void {
- try os.sigaction(os.SIG.ABRT, act, null);
- try os.sigaction(os.SIG.BUS, act, null);
- try os.sigaction(os.SIG.FPE, act, null);
- try os.sigaction(os.SIG.ILL, act, null);
- try os.sigaction(os.SIG.SEGV, act, null);
- try os.sigaction(os.SIG.TRAP, act, null);
-}
-
-const builtin = @import("builtin");
-const ErrorCallback = fn (sig: i32, addr: usize) void;
-var on_error: ?ErrorCallback = null;
-noinline fn sigaction_handler(sig: i32, info: *const std.os.siginfo_t, _: ?*const anyopaque) callconv(.C) void {
- // Prevent recursive calls
- setup_sigactions(null) catch unreachable;
-
- const addr = switch (comptime builtin.target.os.tag) {
- .linux => @ptrToInt(info.fields.sigfault.addr),
- .macos, .freebsd => @ptrToInt(info.addr),
- .netbsd => @ptrToInt(info.info.reason.fault.addr),
- .openbsd => @ptrToInt(info.data.fault.addr),
- .solaris => @ptrToInt(info.reason.fault.addr),
- else => unreachable,
- };
- if (on_error) |handle| handle(sig, addr);
-}
-
-pub fn reloadHandlers() !void {
- try setup_sigactions(null);
-
- var act = os.Sigaction{
- .handler = .{ .sigaction = sigaction_handler },
- .mask = os.empty_sigset,
- .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
- };
-
- try setup_sigactions(&act);
-}
-const os = std.os;
-pub fn start(ctx: ?*anyopaque, callback_: PrintCallback, onError: ErrorCallback) !void {
- callback_ctx = ctx;
- callback = callback_;
- on_error = onError;
-
- var act = os.Sigaction{
- .handler = .{ .sigaction = sigaction_handler },
- .mask = os.empty_sigset,
- .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
- };
-
- try setup_sigactions(&act);
-}
diff --git a/src/main.zig b/src/main.zig
index 9d92942be..e7073328f 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -30,16 +30,12 @@ pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) nore
MainPanicHandler.handle_panic(msg, error_return_trace);
}
-const CrashReporter = @import("crash_reporter");
-
-pub fn PLCrashReportHandler() void {
- Report.fatal(null, null);
-}
+const CrashReporter = @import("./crash_reporter.zig");
pub var start_time: i128 = 0;
pub fn main() void {
if (comptime Environment.isRelease)
- CrashReporter.start(null, Report.CrashReportWriter.printFrame, Report.handleCrash) catch unreachable;
+ CrashReporter.start(null) catch unreachable;
start_time = std.time.nanoTimestamp();
diff --git a/src/report.zig b/src/report.zig
index a39734a9d..8037c2899 100644
--- a/src/report.zig
+++ b/src/report.zig
@@ -15,7 +15,7 @@ const CLI = @import("./cli.zig").Cli;
const Features = @import("./analytics/analytics_thread.zig").Features;
const Platform = @import("./analytics/analytics_thread.zig").GenerateHeader.GeneratePlatform;
const HTTP = @import("http").AsyncHTTP;
-const CrashReporter = @import("crash_reporter");
+const CrashReporter = @import("./crash_reporter.zig");
const Report = @This();
@@ -230,7 +230,11 @@ pub fn fatal(err_: ?anyerror, msg_: ?string) void {
// It only is a real crash report if it's not coming from Zig
- CrashReportWriter.dump();
+ if (comptime !@import("javascript_core").is_bindgen) {
+ std.mem.doNotOptimizeAway(&Bun__crashReportWrite);
+ Bun__crashReportDumpStackTrace(&crash_report_writer);
+ }
+
crash_report_writer.flush();
crash_report_writer.printPath();
@@ -244,6 +248,13 @@ pub fn fatal(err_: ?anyerror, msg_: ?string) void {
var globalError_ranOnce = false;
+export fn Bun__crashReportWrite(ctx: *CrashReportWriter, bytes_ptr: [*]const u8, len: usize) void {
+ if (len > 0)
+ ctx.print("{s}\n", .{bytes_ptr[0..len]});
+}
+
+extern "C" fn Bun__crashReportDumpStackTrace(ctx: *anyopaque) void;
+
pub noinline fn handleCrash(signal: i32, addr: usize) void {
const had_printed_fatal = has_printed_fatal;
if (has_printed_fatal) return;
@@ -263,7 +274,10 @@ pub noinline fn handleCrash(signal: i32, addr: usize) void {
.{ @errorName(name), std.fmt.fmtSliceHexUpper(std.mem.asBytes(&addr)) },
);
printMetadata();
- CrashReportWriter.dump();
+ if (comptime !@import("javascript_core").is_bindgen) {
+ std.mem.doNotOptimizeAway(&Bun__crashReportWrite);
+ Bun__crashReportDumpStackTrace(&crash_report_writer);
+ }
if (!had_printed_fatal) {
crash_report_writer.print("\nAsk for #help in https://bun.sh/discord or go to https://bun.sh/issues\n\n", .{});