【问题标题】:How does V8 reconstruct async stacktraces with requestAnimationFrame?V8 如何使用 requestAnimationFrame 重构异步堆栈跟踪?
【发布时间】:2022-01-23 01:11:31
【问题描述】:

根据Zero-cost async stack traces V8 使用微任务中的 Promise 引用来重构“异步堆栈跟踪”。我假设调试器中也使用了类似的技术,它也显示了“异步堆栈”。但是,在调试“伪递归函数”时,例如这个使用requestAnimationFrame:

(function tick() { requestAnimationFrame(tick); })();

然后 Chrome 还显示了一些“异步堆栈”,如 this question 所示,尽管不存在 Promise。 V8 如何恢复这个堆栈?它是否收集有关如何安排微任务的信息?如果是这样,是什么阻止了它泄露内存?

【问题讨论】:

  • 这不是 rAF 特有的,“递归”setTimeout 也会发生同样的情况
  • here 是一些相关信息。现在没有时间给出正确的答案,但基本上,它们象征着每个异步事件的新堆栈当开发工具打开时。您可以通过在命令菜单中输入 Do not capture async stack traces 来控制此行为(开发工具中的 ctrl + shift + P)。
  • @Kaiido 非常有趣的发现,谢谢!

标签: javascript google-chrome-devtools v8


【解决方案1】:

它基本上是作弊的。当 devtools 打开时,调试器会说 chrome devtools 协议连接到 v8。

它反过来调用setAsyncCallStackDepth,每当异步调用完成时,它将“缝合”堆栈(您可以在 chromium 存储库中的 v8/src/inspector/v8-debugger.cc 中查看如何)。

它很贵,这就是为什么你只能在 devtools 中获得它。

你可以这样想:

  • 每当调用异步函数时,通过堆栈跟踪来跟踪它。
  • 抛出错误时,获取其堆栈跟踪并将两者“缝合”在一起。

请注意,这是以前在用户空间库中完成的(如 bluebird),非常有用,但在生产应用程序中依赖并不好,因为它仅适用于连接的调试器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-05
    • 2021-02-25
    • 2018-02-21
    • 2011-01-05
    • 2017-08-06
    • 2010-09-13
    • 2015-05-14
    相关资源
    最近更新 更多