【问题标题】:Debugging Firefox extension - How to see all JS and XUL files contained in the XPI?调试 Firefox 扩展 - 如何查看 XPI 中包含的所有 JS 和 XUL 文件?
【发布时间】:2014-06-05 07:41:42
【问题描述】:

我正在尝试使用 Firefox 28.0 调试 Firefox 扩展。

我已经按照https://developer.mozilla.org/en-US/Add-ons/Setting_up_extension_development_environment 中的建议设置了开发环境(实际上我只是采取了偷懒的方式并安装了 DevPrefs 扩展来设置所有必要的 about:configs)

然后我打开 Firefox 并进入调试环境(工具 > Web 开发人员 > 浏览器工具箱)。

然后我转到“调试器”选项卡。

但是,在 Sources 窗格下,在我的扩展程序(例如 chrome://myextension)下,我只能看到我的扩展程序 XPI 中包含的一些 JS 和 XUL 文件。

如何在调试器中手动“加载文件”,以便设置断点并跟踪扩展程序的运行时间?

【问题讨论】:

    标签: javascript debugging firefox firefox-addon xpi


    【解决方案1】:

    调试器没有任何允许“手动”加载文件的功能,而是向您显示当前由 JavaScript 引擎加载的每个文件。如果您深入了解细节,这意味着每当 JavaScript 引擎编译一个新脚本时,调试器都会收到通知并将相应的文件添加到其列表中。所以通常你需要做的就是打开一个使用该脚本的页面或对话框,它将在调试器中可见。我说“通常”是因为在我的测试中这似乎不能可靠地工作 - 似乎有一些错误使调试器错过了一些脚本,也许这就是你提出问题的原因。

    现在您当然可以考虑伪造通知以强制调试器加载特定文件 - 例如如果要在文件实际加载之前设置断点。我试过了,这确实是可能的,但它需要你弄乱 Firefox 的内部结构,并且它依赖于许多可能在未来的 Firefox 版本中改变的实现细节。特别是,您需要获取用于与调试器通信的DebuggerServer 实例。虽然进程内调试器总是使用相同的实例,这很容易获得,但会为每个远程调试器创建一个新实例。据我所知,只有通过在 bug 993029 中实现的更改才能访问该实例,这意味着它仅适用于 Firefox 32(目前可从 Firefox Aurora channel 获得)及更高版本。

    问题在于DebuggerServer 实例是由ToolboxProcess.jsm 中声明的BrowserToolboxProcess 类创建的。在错误 993029 引入的更改之前,将创建一个 BrowserToolboxProcess 对象,并且不会保留对它的引用——这意味着事后将无法访问它和相应的连接。从 Firefox 32 开始,所有创建的 BrowserToolboxProcess 对象都存储在 processes set 中,并且可以枚举。

    此代码可用于伪造Debugger.onNewScript() call,该Debugger.onNewScript() call 将被转发到远程调试器:

    (function()
    {
      // Iterate over existing processes
      const {processes} = Cu.import("resource:///modules/devtools/ToolboxProcess.jsm", null);
      for (var process of processes)
      {
        // Iterate over connections associated with each process
        var debuggerServer = process.debuggerServer;
        for (var connID in debuggerServer._connections)
        {
          if (!debuggerServer._connections.hasOwnProperty(connID))
            continue;
          var conn = debuggerServer._connections[connID];
    
          // Get ChromeDebuggerActor instance for the connection
          var chromeDebugger = conn._getOrCreateActor(conn.rootActor._extraActors.chromeDebugger.actorID);
    
          // Fake new script call
          chromeDebugger.onNewScript({
            url: "chrome://myextension/content/script.js", // CHANGE THAT LINE
            source: {text:""},
            getChildScripts: () => []
          });
        }
      }
    })();
    

    如上所述,此代码只能从 Firefox 32 开始工作,我在 Firefox 33.0a1 上对其进行了测试。您可以从 Scratchpad 运行它,请确保使用 switch environment to "Browser"。无法保证它会在未来的 Firefox 版本中继续工作,这里使用的几个实现细节可能随时更改。

    【讨论】:

    • 不是我希望的明确答案,但确实告诉了我需要了解的技术细节,以及调试器为何会以这种方式运行。而且我认为它应该得到赏金。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多