f537d77845
This introduces a new flag --async-stack-traces, which enables zero-cost async stack traces. This enriches the non-standard Error.stack property with async stack frames computed from walking up the promise chains and collecting all the await suspension points along the way. In Error.stack these async frames are marked with "async" to make it possible to distinguish them from regular frames, for example: ``` Error: Some error message at bar (<anonymous>) at async foo (<anonymous>) ``` It's zero-cost because no additional information is collected during the execution of the program, but only the information already present in the promise chains is used to reconstruct an approximation of the async stack in case of an exception. But this approximation is limited to suspension points at await's in async functions. This depends on a recent ECMAScript specification change, flagged behind --harmony-await-optimization and implied the --async-stack-traces flag. Without this change there's no way to get from the outer promise of an async function to the rest of the promise chain, since the link is broken by the indirection introduced by await. For async functions the special outer promise, named .promise in the Parser desugaring, is now forcible allocated to stack slot 0 during scope resolution, to make it accessible to the stack frame construction logic. Note that this first prototype doesn't yet work fully support async generators and might have other limitations. Bug: v8:7522 Ref: nodejs/node#11865 Change-Id: I0cc8e3cdfe45dab56d3d506be2d25907409b01a9 Design-Document: http://bit.ly/v8-zero-cost-async-stack-traces Reviewed-on: https://chromium-review.googlesource.com/c/1256762 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Adam Klein <adamk@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#56363}
32 lines
825 B
JavaScript
32 lines
825 B
JavaScript
// Copyright 2018 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --async-stack-traces
|
|
|
|
// Check that Error.prepareStackTrace doesn't expose strict
|
|
// mode closures, even in the presence of async frames.
|
|
Error.prepareStackTrace = (e, frames) => {
|
|
assertEquals(undefined, frames[0].getFunction());
|
|
assertEquals(two.name, frames[0].getFunctionName());
|
|
assertEquals(undefined, frames[1].getFunction());
|
|
assertEquals(one.name, frames[1].getFunctionName());
|
|
return frames;
|
|
};
|
|
|
|
async function one(x) {
|
|
return await two(x);
|
|
}
|
|
|
|
async function two(x) {
|
|
"use strict";
|
|
try {
|
|
x = await x;
|
|
throw new Error();
|
|
} catch (e) {
|
|
return e.stack;
|
|
}
|
|
}
|
|
|
|
one(1).catch(e => setTimeout(_ => {throw e}, 0));
|