Compare commits

...

2 Commits

Author SHA1 Message Date
Jarred Sumner
3ffbacab34 Update main.zig 2025-04-18 19:52:38 -07:00
Jarred Sumner
07ac1d8714 init 2025-04-18 19:18:01 -07:00
4 changed files with 110 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
import { watch } from "node:fs";
import { readFile, unlink } from "node:fs/promises";
import { join } from "node:path";
import { Readable } from "node:stream";
import { pipeline } from "node:stream/promises";
import { createGzip } from "node:zlib";
import { isBuildkite } from "./runner.node.mjs";
import { uploadArtifact } from "./utils.mjs";
import { existsSync, readFileSync } from "node:fs";
// Get core dump directory from system configuration or use default
function getCoreDumpDir() {
try {
// Try to read from /proc/sys/kernel/core_pattern
const corePattern = readFileSync("/proc/sys/kernel/core_pattern", "utf8").trim();
// If core_pattern contains a path (not starting with | for piping)
if (corePattern && !corePattern.startsWith("|")) {
// Extract directory path from the pattern
const dir = corePattern.split("/").slice(0, -1).join("/");
if (dir) return dir;
}
} catch (error) {
// Fallback to default if any error occurs
console.warn("Could not determine core dump directory:", error.message);
}
// Check common locations
for (const dir of ["/var/crash", "/var/lib/systemd/coredump", "/cores"]) {
if (existsSync(dir)) return dir;
}
return "/var/crash"; // Default fallback
}
var watcher;
/**
* Watches for core dumps on Linux, compresses them in memory,
* uploads them as BuildKite artifacts, and deletes the original files.
*/
export function startWatcher() {
// Skip if not on Linux or not in BuildKite
if (process.platform !== "linux" || !isBuildkite) {
console.log("Core dump watcher not started (requires Linux and BuildKite)");
return;
}
const coreDumpDir = getCoreDumpDir();
try {
console.log(`Starting core dump watcher on ${coreDumpDir}`);
let uploadedFiles = new Set();
watcher = watch(coreDumpDir, async (eventType, filename) => {
if (!filename || !filename.startsWith("core.")) {
return;
}
if (eventType === "rename") return;
const coreDumpPath = join(coreDumpDir, filename);
try {
if (uploadedFiles.has(coreDumpPath) || statSync(coreDumpPath).size === 0) {
return;
}
uploadedFiles.add(coreDumpPath);
console.log(`Found core dump: ${coreDumpPath}`);
// Compress the file and write it to disk
const compressedFilePath = `${coreDumpPath}.gz`;
await pipeline(fs.createReadStream(coreDumpPath), createGzip(), fs.createWriteStream(compressedFilePath));
unlink(coreDumpPath).catch(() => {});
await uploadArtifact(compressedFilePath, coreDumpDir);
console.log(`Uploaded core dump as artifact: ${compressedFilePath}`);
console.log(`Deleted original core dump: ${coreDumpPath}`);
} catch (error) {
console.error(`Error processing core dump ${filename}:`, error);
}
});
// Keep track of the watcher to close it if needed
process.on("beforeExit", () => {
watcher.close();
});
} catch (error) {
console.error("Failed to start core dump watcher:", error);
}
}

View File

@@ -695,6 +695,7 @@ async function spawnBun(execPath, { args, cwd, timeout, env, stdout, stderr }) {
SHELLOPTS: isWindows ? "igncr" : undefined, // ignore "\r" on Windows
// Used in Node.js tests.
TEST_TMPDIR: tmpdirPath,
BUN_FEATURE_FLAG_DISABLE_CRASH_HANDLER: "1",
};
if (env) {

View File

@@ -40,6 +40,10 @@ const default_report_base_url = "https://bun.report";
/// flow is not returned to the main application.
var has_printed_message = false;
/// Disabled at runtime via BUN_FEATURE_FLAG_DISABLE_CRASH_HANDLER
/// Used in CI to allow crash dumps to work.
pub var disable_at_runtime = false;
/// Non-zero whenever the program triggered a panic.
/// The counter is incremented/decremented atomically.
var panicking = std.atomic.Value(u8).init(0);
@@ -840,6 +844,9 @@ pub fn updatePosixSegfaultHandler(act: ?*std.posix.Sigaction) !void {
var windows_segfault_handle: ?windows.HANDLE = null;
pub fn resetOnPosix() void {
if (disable_at_runtime)
return;
var act = std.posix.Sigaction{
.handler = .{ .sigaction = handleSegfaultPosix },
.mask = std.posix.empty_sigset,
@@ -850,6 +857,9 @@ pub fn resetOnPosix() void {
pub fn init() void {
if (!enable) return;
if (disable_at_runtime)
return;
switch (bun.Environment.os) {
.windows => {
windows_segfault_handle = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows);
@@ -863,6 +873,8 @@ pub fn init() void {
pub fn resetSegfaultHandler() void {
if (!enable) return;
if (disable_at_runtime)
return;
if (bun.Environment.os == .windows) {
if (windows_segfault_handle) |handle| {

View File

@@ -21,6 +21,12 @@ pub extern "c" var _environ: ?*anyopaque;
pub extern "c" var environ: ?*anyopaque;
pub fn main() void {
if (comptime Environment.isPosix) {
if (bun.getRuntimeFeatureFlag("BUN_FEATURE_FLAG_DISABLE_CRASH_HANDLER")) {
bun.crash_handler.disable_at_runtime = true;
}
}
bun.crash_handler.init();
if (Environment.isPosix) {