Chrome 开发工具:来自 javascript 的 [VM] 文件

Posted

技术标签:

【中文标题】Chrome 开发工具:来自 javascript 的 [VM] 文件【英文标题】:Chrome Development Tool: [VM] file from javascript 【发布时间】:2013-06-26 09:29:24 【问题描述】:

我在我的 javascript 文件 (jaydata.js) 中添加了一个断点,并按下了“跳到下一个函数调用”。 当它到达一行时:

,

弹出另一个名为“[VM] (8312)”的文件。我一直点击“跳到下一个函数调用”,现在我的屏幕是:

这些名为“[VM](XXXX”的奇怪而神秘的脚本是什么?它们来自哪里?

【问题讨论】:

这些 VM 文件也会在您同时编辑正在调试的文件时出现。 Chrome 会失去同步,当在文件上放置断点时,它会将代码停止在内存中文件的某个其他位置。例如test.html 将允许一个断点,但当 Chrome 停止时,它会在 VM99:test.html 的某个其他位置这样做。解决方案是关闭 Chrome 重命名文件,例如test2.html,然后重新开始。 (清除历史记录、缓存等不起作用,如果您尝试这样做,Chrome 将继续加载 VM99:test.html。 @QuentinUK 如果任何浏览器都发生这种情况怎么办? 【参考方案1】:

[VM] (scriptId) 没有特殊含义。这是一个虚拟名称,可以帮助我们区分与文件名没有直接关联的代码,例如使用eval 和朋友创建的代码。

过去,所有这些脚本都只是标记为(program)

如果您有兴趣,只需look up "[VM]"in the source code of Chromium,您会发现这些数字在开发者工具之外没有任何意义。

2015-06-25 更新

[VM] (scriptId) 重命名为VMscriptId a while ago,这里是direct link to search result,以防值再次更改。

【讨论】:

Chrome 会点击 [VM] 文件而不是 live js 文件吗?如果有,为什么? @Matt “点击 [VM] 文件而不是实时 js 文件”是什么意思? @RobW 无视;我的浏览器正在缓存 js 文件(尽管更新了我的缓存破坏器)。 [VM] (scriptId) 已重命名为 VMscriptId a while ago,但我将答案保持在当前状态,以免问题无效。最新的codesearch链接是:cs.chromium.org/%22VM%5C%22%20+%22(直接链接到搜索结果,以防值再次更改:chromium.googlesource.com/chromium/blink/+/…) 我最近在没有任何评估的情况下遇到了这个问题 - 它似乎与使用 iFrames 有关。我的证据是,当我在 iFrame 中的代码上设置断点时,我会遇到 [VM] 问题,但是当我在自己的窗口中打开 iFrame 时,我会很好地命中断点。只需确定这是否符合答案中所述的 eval 的“朋友”之一。【参考方案2】:

使用 eval 时,javascript 会被扔进 Chrome 调试器 VM。为了在 Chrome Debugger Sources 下查看使用 eval 创建的 js,请在 js 的末尾设置此属性(感谢 Splaktar):

//@ sourceURL=dynamicScript.js

Is possible to debug dynamic loading JavaScript by some debugger like WebKit, FireBug or IE8 Developer Tool?

【讨论】:

语法已经改变,现在是://# sourceURL=dynamicScript.js 它也应该在 JavaScript 的末尾,而不是开头。 一直在寻找这样的东西。谢谢 该技巧也适用于通过document.createElement('script');注入的脚本 在 Firefox 调试工具上,它说 Using //@ to indicate sourceURL pragmas is deprecated. Use //# instead【参考方案3】:

只要您通过 AJAX 加载 HTML 内容,并且该内容包含 <script> 标记,脚本将使用 eval() 进行评估,并被 Chrome 的 Sources 视图识别为以“VM”开头的新文件。您始终可以转到“网络”选项卡,找到 AJAX 请求,并查看整个 HTML 响应,包括您的脚本。

【讨论】:

这对于调试来说很糟糕。如果我使用带有src=/test.js 的脚本标记然后导致错误回溯到test.js,回溯包含正确的文件名,但此后,堆栈跟踪包含VM 魔法。这使得无法多次获取堆栈跟踪中文件的源代码[来自同一来源],并且您无法缓存它们,因为您不知道将来的堆栈跟踪中哪个文件是哪个文件。这在开发工具中已修复,但在 webapps 中未修复。 这可能是它在现代 Web 应用程序中发生的最常见原因,也是我们应该将代码与内容分离的另一个很好的例子。【参考方案4】:

我发现 VM 是从一些 Chrome 扩展程序生成的 - 它们将 CSS/JS 插入页面,Chrome 使用 VM 文件来运行它。

【讨论】:

【参考方案5】:

当您调试随后卸载的子窗口 (iframe) 源时,您的源文件也将获得 VM 前缀和黄色背景。

【讨论】:

【参考方案6】:

我遇到了同样的问题。问题是我的应用程序代码被意外地视为黑盒。当我尝试进入代码时,它不断打开这些VMXXXX 选项卡。

为我的应用程序的 js 文件删除黑盒设置后,我可以成功单步执行我的代码。

【讨论】:

我也有同样的问题,你到底是怎么做的? 抱歉@sTx,我完全不记得这些了。 没问题,在我的例子中是我的代码中有一个空引用错误。【参考方案7】:

我在调试 Angular 应用程序时遇到了同样的问题。看到太多无法黑盒化的 VM 脚本确实需要很长时间才能调试。 我宁愿选择 mozilla/IE explorer 来调试。

【讨论】:

Firefox 中没有 VMxxx。这是迄今为止唯一可行的解​​决方案。【参考方案8】:

如果您想在 chrome 中调试以编程方式注入的 JS 文件,可以使用 debugger; 语句,这比查找脚本所在位置更快,也比使用 sourceurl 生成文件更快。

它就像一个断点一样工作,并在您使用 debugger; 语句的任何位置自动在 chrome 源选项卡中精确定位您的代码。

请注意,脚本的来源是 VMXXX 文件。

【讨论】:

这似乎无法回答问题。 我的错,我放弃了这个问题的其他答案。 超级!这正是我所寻求的。无需查找JS引擎将代码插入到哪个VM中。 这个答案和问题有什么联系? 通过debugger; 声明,如果他愿意,他可以揭开神秘的“奇怪而神秘的名为“[VM](XXXX””的脚本的来源。【参考方案9】:

为了防止这种情况

(function ()
 
  var originalEval = eval;
  eval =
   function (script)
   
    return originalEval(script + "\n//# sourceURL=blackbox-this.js");
   
 ());

然后是黑盒^.*blackbox-this.js$

setInterval/setTimeout 在获取字符串时也是如此(但这无论如何都是不好的做法,对吧?;))

这对你有用吗?

【讨论】:

以上是关于Chrome 开发工具:来自 javascript 的 [VM] 文件的主要内容,如果未能解决你的问题,请参考以下文章

来自 javascript 控制台 Chrome 的输入表单

chrome扩展中popup.html和popup.js之间的函数JavaScript(考虑到来自后台的消息)[重复]

我可以从外部 javascript 访问控制台命令行 API(例如来自 Firebug 或 Chrome Inspector 控制台的 $$ 和 traceAll)吗?

Safari已默认支持WebAssembly!JavaScript执行速度比Chrome快80%

调试来自 chrome 开发工具的 firestore 网络请求

未知的 iOS Chrome Javascript 错误 - fillForm