Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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 src/jsc/modules/BunJSCModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,9 +499,8 @@ JSC_DEFINE_HOST_FUNCTION(functionSamplingProfilerStackTraces,
createError(globalObject, "Sampling profiler was never started"_s)));

WTF::String jsonString = vm.samplingProfiler()->stackTracesAsJSON()->toJSONString();
JSC::EncodedJSValue result = JSC::JSValue::encode(JSONParse(globalObject, jsonString));
scope.releaseAssertNoException();
return result;
RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSONParse(globalObject, jsonString)));
Comment thread
robobun marked this conversation as resolved.
}

JSC_DECLARE_HOST_FUNCTION(functionGetRandomSeed);
Expand Down
29 changes: 29 additions & 0 deletions test/js/bun/jsc/bun-jsc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -567,3 +567,32 @@ it("deserialize applies the same nesting depth limit to arrays as to objects", a
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect({ stdout, exitCode }).toEqual({ stdout: "rejected\n65\n", exitCode: 0 });
});

it("samplingProfilerStackTraces returns parsed traces and survives BUN_JSC_validateExceptionChecks", async () => {
// samplingProfilerStackTraces JSON-parses the profiler's stack traces, and
// JSONParse can throw (OOM on a large profile), so the enclosing throw scope
// must release before returning instead of asserting no exception after the
// parse. With validateExceptionChecks enabled the process aborts on unchecked
// scopes; on release builds the option is a no-op and this just exercises the
// stack-trace path.
const script = `
const jsc = require("bun:jsc");
jsc.startSamplingProfiler();
let j = 0;
for (let i = 0; i < 999999; i++) j += i % 7;
const traces = jsc.samplingProfilerStackTraces();
console.log("ok", typeof traces, Array.isArray(traces.traces));
`;
await using proc = Bun.spawn({
cmd: [bunExe(), "-e", script],
env: { ...bunEnv, BUN_JSC_validateExceptionChecks: "1" },
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
const uncheckedScopes = stderr
.split("\n")
.map(line => line.trim())
.filter(line => line.startsWith("This scope can throw") || line.startsWith("But the exception was unchecked"));
expect({ stdout, uncheckedScopes, exitCode }).toEqual({ stdout: "ok object true\n", uncheckedScopes: [], exitCode: 0 });
});