Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions backend/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ import { existsSync } from "node:fs";
import { Octokit } from "octokit";
import { join } from "path";
import type { ResolvedCommit } from "../lib/parser";
import { cache_root } from "./debug-store";
import { AsyncMutex } from "./mutex";
import { git } from "./system-deps";

export const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
});

const local_clone_dir = process.env.CI_CLONE_DIR ?? join(cache_root, "bun");
const local_clone_dir = process.env.CI_CLONE_DIR ?? join(import.meta.dir, "..", ".cache", "bun");
const local_clone_git_dir = join(local_clone_dir, ".git");
const commitish_cache = new Map<string, ResolvedCommit>();

Expand Down
2 changes: 1 addition & 1 deletion backend/remap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export async function remapUncached(
parse.os === "windows" ? pdb_addr2line : llvm_symbolizer,
"--exe",
debug_info.file_path,
...(parse.os !== "windows" ? ["--no-inlines", "--relative-address"] : ["--llvm"]),
...(parse.os !== "windows" ? ["--inlines", "--relative-address"] : ["--llvm", "-i"]),
"-f",
...bun_addrs,
];
Expand Down
84 changes: 52 additions & 32 deletions backend/symbolize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,22 @@ const macho_first_offset = 0x100000000;
* should be passed to the symbolizer for `object === "bun"` frames.
*/
export function adjustBunAddresses(addresses: ParsedAddress[], os: Platform): string[] {
return addresses
.filter(a => a.object === "bun")
.map(a => "0x" + (os === "macos" ? macho_first_offset + a.address : a.address).toString(16));
// crash_handler.zig already encodes `addr - 1` on macOS/Linux but emits raw
// return addresses on Windows. Decrement here for Windows only (all bun
// frames after the first — the first is ExceptionAddress, the exact fault
// PC). Doing it server-side retroactively fixes existing traces and avoids
// a wire-format version bump.
let first_bun_seen = false;
const out: string[] = [];
for (const a of addresses) {
if (a.object !== "bun") continue;
let addr = a.address;
if (os === "windows" && first_bun_seen) addr -= 1;
first_bun_seen = true;
if (os === "macos") addr += macho_first_offset;
out.push("0x" + addr.toString(16));
}
return out;
}

/**
Expand All @@ -22,35 +35,37 @@ export function adjustBunAddresses(addresses: ParsedAddress[], os: Platform): st
* process or fetching debug files.
*/
export function processSymbolizerOutput(addresses: ParsedAddress[], stdout: string): Address[] {
const lines = stdout.split("\n").filter(l => l.length > 0);

let mapped_addrs: Address[] = addresses.map(addr => {
if (addr.object === "bun") {
const fn_line = lines.shift();
const source_line = lines.shift();
if (fn_line && source_line) {
const parsed_line = parsePdb2AddrLineFile(source_line);

return {
remapped: true,
src: parsed_line
? {
file: parsed_line.file,
line: parsed_line.line,
}
: null,
function: cleanFunctionName(fn_line),
object: "bun",
} satisfies Address;
}
// llvm-symbolizer outputs one block per input address, blocks separated by a
// blank line. With --inlines a block holds N (function, source) line-pairs,
// innermost first; --no-inlines and pdb-addr2line emit exactly one pair.
const blocks = stdout
.replace(/\n+$/, "")
.split(/\n\n+/)
.map(b => b.split("\n"));
let blockIdx = 0;

let mapped_addrs: Address[] = [];
for (const addr of addresses) {
if (addr.object !== "bun") {
mapped_addrs.push({ remapped: false, object: addr.object, address: addr.address });
continue;
}

return {
remapped: false,
object: addr.object,
address: addr.address,
} satisfies Address;
});
const block = blocks[blockIdx++] ?? [];
let pushed = 0;
for (let i = 0; i + 1 < block.length; i += 2) {
const src = parsePdb2AddrLineFile(block[i + 1]);
mapped_addrs.push({
remapped: true,
src: src ? { file: src.file, line: src.line } : null,
function: cleanFunctionName(block[i]),
object: "bun",
});
pushed++;
}
if (pushed === 0) {
mapped_addrs.push({ remapped: false, object: addr.object, address: addr.address });
}
}

if (mapped_addrs[0]?.function?.includes("WTF::jscSignalHandler")) {
const old = mapped_addrs.slice();
Expand Down Expand Up @@ -131,7 +146,12 @@ export function cleanFunctionName(str: string): string {
}
}
}
return withoutZigAnon(str.slice(0, last_open_paren).replace(/\(.+?\)/g, "(...)"));
const before = str.slice(0, last_open_paren).replace(/\(.+?\)/g, "(...)");
const after = str.slice(last_paren + 1);
// C++ args are the trailing group: `Foo::bar(int, char)` -> drop entirely.
// Zig generic type params sit before the method: `Queue(Job,.next).push` ->
// collapse to `Queue(...).push` so the method name survives.
return withoutZigAnon(after ? before + "(...)" + after : before);
}

export function parsePdb2AddrLineFile(str: string): { file: string; line: number } | null {
Expand Down
2 changes: 1 addition & 1 deletion scripts/capture-fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const cmd = [
parsed.os === "windows" ? pdb_addr2line : llvm_symbolizer,
"--exe",
debug_info.file_path,
...(parsed.os !== "windows" ? ["--no-inlines", "--relative-address"] : ["--llvm"]),
...(parsed.os !== "windows" ? ["--inlines", "--relative-address"] : ["--llvm", "-i"]),
"-f",
...bun_addrs,
];
Expand Down
224 changes: 224 additions & 0 deletions test/__snapshots__/parse.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,187 @@
// Bun Snapshot v1, https://bun.sh/docs/test/snapshots

exports[`parse fixtures linux-http-thread-segfault 1`] = `
{
"addresses": [
{
"address": 86642156,
"object": "bun",
},
{
"address": 106559,
"object": "bun",
},
{
"address": 60096454,
"object": "bun",
},
{
"address": 56911368,
"object": "bun",
},
{
"address": 466707,
"object": "bun",
},
{
"address": 1004331,
"object": "bun",
},
],
"arch": "x86_64_baseline",
"command": "_",
"commitish": "e38b41d",
"cpu_flags": undefined,
"env_flags": undefined,
"features": [
2097155,
1052695,
],
"is_canary": false,
"message": "Segmentation fault at address 0x00000010",
"os": "linux",
"os_version": undefined,
"total_ram_mb": undefined,
"version": "1.3.12",
}
`;

exports[`parse fixtures macos-prev-regression 1`] = `
{
"addresses": [
{
"address": 13083216,
"object": "bun",
},
{
"address": 13083248,
"object": "bun",
},
{
"address": 11617296,
"object": "bun",
},
],
"arch": "aarch64",
"command": "a",
"commitish": "1b55f1d",
"cpu_flags": undefined,
"env_flags": undefined,
"features": [
96,
1048711,
],
"is_canary": false,
"message": "Segmentation fault at address 0xFFFFFFFFFFFFFFFF",
"os": "macos",
"os_version": undefined,
"total_ram_mb": undefined,
"version": "1.3.13",
}
`;

exports[`parse fixtures macos-remap-stack-frames 1`] = `
{
"addresses": [
{
"address": 0,
"object": "?",
},
{
"address": 28143423,
"object": "bun",
},
{
"address": 28166551,
"object": "bun",
},
{
"address": 28166735,
"object": "bun",
},
{
"address": 20078891,
"object": "bun",
},
{
"address": 1242859,
"object": "bun",
},
{
"address": 1253419,
"object": "bun",
},
{
"address": 1245707,
"object": "bun",
},
{
"address": 41056387,
"object": "bun",
},
{
"address": 41056235,
"object": "bun",
},
{
"address": 37586551,
"object": "bun",
},
{
"address": 37422795,
"object": "bun",
},
{
"address": 37440403,
"object": "bun",
},
{
"address": 37434931,
"object": "bun",
},
{
"address": 37596979,
"object": "bun",
},
{
"address": 37650091,
"object": "bun",
},
{
"address": 37450383,
"object": "bun",
},
{
"address": 37420003,
"object": "bun",
},
{
"address": 37421819,
"object": "bun",
},
{
"address": 34221763,
"object": "bun",
},
],
"arch": "aarch64",
"command": "a",
"commitish": "af24e28",
"cpu_flags": undefined,
"env_flags": undefined,
"features": [
3331,
1052695,
],
"is_canary": false,
"message": "Segmentation fault at address 0x00000000",
"os": "macos",
"os_version": undefined,
"total_ram_mb": undefined,
"version": "1.3.11",
}
`;

exports[`parse fixtures real-001-macos-aarch64-1.3.11-segv-lg-unk 1`] = `
{
"addresses": [
Expand Down Expand Up @@ -8709,3 +8891,45 @@ exports[`parse fixtures v2-windows-x86_64_baseline-segfault 1`] = `
"version": "1.1.30",
}
`;

exports[`parse fixtures windows-segfault-neg1 1`] = `
{
"addresses": [
{
"address": 8930599,
"object": "bun",
},
{
"address": 6990411,
"object": "bun",
},
{
"address": 10540979,
"object": "bun",
},
{
"address": 190679,
"object": "KERNEL32.DLL",
},
{
"address": 574780,
"object": "ntdll.dll",
},
],
"arch": "x86_64",
"command": "a",
"commitish": "1b55f1d",
"cpu_flags": undefined,
"env_flags": undefined,
"features": [
96,
1048711,
],
"is_canary": false,
"message": "Segmentation fault at address 0xFFFFFFFFFFFFFFFF",
"os": "windows",
"os_version": undefined,
"total_ram_mb": undefined,
"version": "1.3.13",
}
`;
Loading
Loading