Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: f8a073dfbecfa286cca236c7053f3b2e72591f9d
https://github.com/WebKit/WebKit/commit/f8a073dfbecfa286cca236c7053f3b2e72591f9d
Author: Sosuke Suzuki <[email protected]>
Date: 2025-09-02 (Tue, 02 Sep 2025)
Changed paths:
A JSTests/stress/async-stack-trace-basic.js
A JSTests/stress/async-stack-trace-bound-functions-basic.js
A JSTests/stress/async-stack-trace-nested-deep.js
A JSTests/stress/async-stack-trace-nested.js
A JSTests/stress/async-stack-trace-switch.js
A JSTests/stress/never-inlined-functions.js
M Source/JavaScriptCore/builtins/PromiseOperations.js
M Source/JavaScriptCore/interpreter/Interpreter.cpp
M Source/JavaScriptCore/interpreter/Interpreter.h
M Source/JavaScriptCore/runtime/JSGlobalObject.cpp
M Source/JavaScriptCore/runtime/JSGlobalObject.h
M Source/JavaScriptCore/runtime/OptionsList.h
M Source/JavaScriptCore/runtime/StackFrame.cpp
M Source/JavaScriptCore/runtime/StackFrame.h
M Source/JavaScriptCore/tools/JSDollarVM.cpp
Log Message:
-----------
[JSC] Add async stack traces behind the flag
https://bugs.webkit.org/show_bug.cgi?id=296261
Reviewed by Yusuke Suzuki.
JSC cannot obtain sufficient async stack traces. For example, this code:
async function one(x) {
await two(x);
}
async function two(x) {
await x;
throw new Error("error from two");
}
one(1).catch((err) => { print(err.stack); });
prints this stack trace:
two@./test.js:6:20
When an error occurs within an async function, the stack trace is cut off
at the most recent await point, so higher-level functions in the async call
chain are not displayed. This happens because when an async function is
suspended at an await statement and later resumed from the microtask queue,
the original call stack is lost.
While this behavior is correct from the semantics of call stacks and microtask
queues, it is inconvenient for users.
This patch builds async stack traces through the following approach (only when
the --useAsyncStackTrace flag is enabled):
- Detect calls to `@promiseReactionJob` and `@promiseReactionJobWithoutPromise`
during stack trace construction and retrieve the JSGenerator object hidden
behind async-await from its arguments
- Obtain references to awaited Promises held in each generator's Context field
- Trace async context (parent generators recorded as @context fields) from the
Promise's reaction chain
- Walk up the chain of parent generators and construct stack frames from
function
information stored in each async function's Next field
After this patch, the previous code outputs this stack trace:
two@./WebKitBuild/Debug/test.js:6:20
one@./WebKitBuild/Debug/test.js:2:14
V8 constructs async stack traces using a similar approach [1][2].
[1]:
https://docs.google.com/document/d/13Sy_kBIJGP0XT34V1CV3nkWya4TwYx9L3Yv45LdGB6Q/edit?tab=t.0#heading=h.9ss45aibqpw2
[2]: https://issues.chromium.org/issues/42210758
* JSTests/stress/async-stack-trace-basic.js: Added.
* JSTests/stress/async-stack-trace-bound-functions-basic.js: Added.
* JSTests/stress/async-stack-trace-nested-deep.js: Added.
* JSTests/stress/async-stack-trace-nested.js: Added.
* JSTests/stress/async-stack-trace-switch.js: Added.
* JSTests/stress/never-inlined-functions.js: Added.
* Source/JavaScriptCore/builtins/PromiseOperations.js:
* Source/JavaScriptCore/interpreter/Interpreter.cpp:
* Source/JavaScriptCore/interpreter/Interpreter.h:
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
* Source/JavaScriptCore/runtime/OptionsList.h:
* Source/JavaScriptCore/runtime/StackFrame.cpp:
* Source/JavaScriptCore/runtime/StackFrame.h:
* Source/JavaScriptCore/tools/JSDollarVM.cpp:
Canonical link: https://commits.webkit.org/299482@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes