我正在尝试调试Firefox扩展,使用Firefox 28.0。
我已经按照https://developer.mozilla.org/en-US/Add-ons/Setting_up_extension_development_environment中的建议设置了开发环境(实际上我只是采取了懒惰的方式并安装了DevPrefs扩展来设置所有必要的about:configs)
然后打开Firefox,进入调试环境(Tools> Web Developer> Browser Toolbox)。
然后转到Debugger选项卡。
然而,在源窗格下,在我的扩展名(例如chrome://myextension)下,我只看到一些JS和XUL文件包含在我的扩展名XPI中。
我如何在调试器中手动"加载文件",以便我可以设置断点并跟踪扩展的运行时?
调试器没有任何允许"手动"加载文件的功能,相反,它会显示当前由JavaScript引擎加载的每个文件。如果您深入了解细节,这意味着每当JavaScript引擎编译新脚本时,调试器都会收到通知,并将相应的文件添加到其列表中。通常你需要做的就是打开一个使用那个脚本的页面或对话框它就会在调试器中可见。我说"正常"是因为在我的测试中,这似乎没有可靠地工作-似乎有一些错误,使调试器错过了一些脚本,也许这就是提示你的问题。
当然,现在你可以考虑伪造通知来强制调试器加载一个特定的文件——例如,如果你想在文件实际加载之前设置断点。我尝试了一下,它确实是可行的,但它需要你对Firefox的内部进行修改,而且它依赖于许多实现细节,这些细节在未来的Firefox版本中可能会发生变化。特别是,您需要获得用于与调试器通信的DebuggerServer
实例。虽然进程内调试器总是使用相同的实例(获取实例很简单),但是为每个远程调试器创建一个新实例。据我所知,只有在bug 993029中实现的更改才能实现该实例,这意味着它只适用于Firefox 32(目前可从Firefox Aurora通道获得)及以上版本。
问题是DebuggerServer
实例是由在ToolboxProcess.jsm中声明的BrowserToolboxProcess
类创建的。在bug 993029引入的更改之前,将创建BrowserToolboxProcess
对象并且不保留对它的引用-这意味着在事实之后不可能访问它和相应的连接。从Firefox 32开始,所有创建的BrowserToolboxProcess
对象都存储在processes
集合中,并且可以枚举。
这段代码可以用来伪造一个debuger . onnewscript()调用,该调用将被转发到远程调试器:
(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上运行它,确保将环境切换到"浏览器"。不能保证它在未来的Firefox版本中会继续工作,这里使用的几个实现细节可以随时更改。