如何获取“无效的chrome URI”异常的堆栈跟踪?

时间:2016-05-04 07:51:13

标签: debugging firefox-addon stack-trace

我正在调试基于XUL的Firefox扩展,该扩展已被Firefox 46版本打破。

当我运行扩展程序时,Browser console显示:

Invalid chrome URI: /

既没有行号也没有堆栈跟踪。

在网络论坛上,I've read可以使用ChromeBug。然后,我尝试了最新的稳定版ChromeBug(1.7.2),但自从oct以来它还没有更新。 2014年,似乎与最近的Firefox版本不兼容。

由于扩展程序是“旧式”扩展程序,因此我无法使用Add-on debugger,因此我使用了Browser toolbox,但它没有显示异常。

考虑到扩展的行数,在代码中徘徊不是一种选择。知道如何获得堆栈跟踪吗?

1 个答案:

答案 0 :(得分:3)

在浏览器控制台中收到此类错误时,如果没有提供导致错误的信息,则可能是错误不在JavaScript中,甚至可能在代码内部。在这种情况下,不可能获得JavaScript堆栈跟踪,因为它不存在。

这样的事情通常是由打开的弹出窗口或选项卡中使用的XUL或HTML中的问题引起的。您的加载项会打开一个包含 chrome://restclient/content/restclient.html 内容的标签。将该文件替换为没有内容的HTML文档会使错误消失。

使用二进制搜索该文件的内容(一次注释/删除文件的渐进半部分并测试错误是否仍然存在)到A)确认错误是否存在并且B)导致错误的原因导致确定以下行导致错误显示在浏览器控制台中(第197行):

<input class="span5" style="width:-moz-calc(100% - 1em) !important;" type="password" name="password" autocomplete="on" placeholder="Password">

稍微进行一些测试表明,type不是password时问题就会消失。将原始HTML文档复制到我可以使用file: URL轻松访问的位置,在打开文档时,浏览器控制台中不会出现此类错误。

因此,结论是当从<input type="password"> URI加载时,它是chrome:的Mozilla代码中的错误。

在没有堆栈跟踪的代码中查找无效的chrome: URI:
如果在HTML或XUL文件中找不到问题,则需要查看附加组件中使用的chrome: URI以查找可能的原因。

chrome: URI有一些我们可以利用的属性来追踪这样的问题:

  • chrome: URI 通常是静态。
  • chrome: URI通常采用chrome:\\packageName\{content,skin,locale}
  • 格式
  • 您的 chrome.manifest 文件定义了chrome: URI对您的附加组件/包有效。
  • 其他 chrome.manifest 文件定义了chrome: URI在您的加载项/包之外可以有效。

首先看一下你的 chrome.manifest 文件:

content   restclient                content/
resource  restclient                ./

overlay chrome://browser/content/browser.xul chrome://restclient/content/overlay.xul
overlay chrome://navigator/content/navigator.xul    chrome://restclient/content/overlay.xul
style chrome://global/content/customizeToolbar.xul chrome://restclient/content/css/overlay.css

这告诉我们,在您的包中,唯一有效的内部chrome: URI将采用chrome://restclient/content/格式,并将引用根目录中的 content 目录。你的附加组件。

因此,我们现在查找加载项中使用的所有chrome: URI。为此,grep -nri chrome: *的命令行是一种简单的方法。 grep可作为多个操作系统下的标准实用程序使用。在Windows中,我通常从Cygwin获取它。从那个命令我们得到:

chrome.manifest:4:overlay chrome://browser/content/browser.xul chrome://restclient/content/overlay.xul
chrome.manifest:5:overlay       chrome://navigator/content/navigator.xul        chrome://restclient/content/overlay.xul
chrome.manifest:6:style chrome://global/content/customizeToolbar.xul chrome://restclient/content/css/overlay.css
content/css/overlay.css:30:  list-style-image: url("chrome://restclient/content/images/icon16.png") !important;
content/css/overlay.css:33:  list-style-image: url("chrome://restclient/content/images/icon16.png") !important;
content/js/restclient.js:51:        i18nStrings = new restclient.StringBundle("chrome://restclient/locale/restclient.properties");
content/js/restclient.main.js:1040:      xslDocument.load("chrome://restclient/content/xsl/XMLPrettyPrint.xsl");
content/js/restclient.main.js:1053:      xslDoc.load("chrome://restclient/content/xsl/XMLIndent.xsl");*/
content/js/restclient.overlay.js:68:    browser.selectedTab = browser.addTab("chrome://restclient/content/restclient.html");
content/overlay.xul:2:<?xml-stylesheet href="chrome://restclient/content/css/overlay.css" type="text/css"?>
content/overlay.xul:7:  <script type="application/x-javascript" src="chrome://restclient/content/js/restclient.js" />
content/overlay.xul:8:  <script type="application/x-javascript" src="chrome://restclient/content/js/restclient.overlay.js" />
content/overlay.xul:23:                    image="chrome://restclient/content/images/icon16.png"
content/overlay.xul:35:              image="chrome://restclient/content/images/icon16.png"
content/overlay.xul:46:              image="chrome://restclient/content/images/icon16.png"
content/overlay.xul:58:              image="chrome://restclient/content/images/icon16.png"/>
modules/StringBundle.js:59: *     new StringBundle("chrome://example/locale/strings.properties");

现在,我们可以并且可能应该手动查看问题,但我们可以快速缩短列表以查找命令的明显问题:grep -nri chrome: * | grep -v chrome://restclient/content/。这将为我们提供任何chrome: URI,这些URI不在引用加载项content的格式中。获得的列表可以轻松包含引用加载项外部文件的有效chrome: URI。所以,我们可能需要做更多的检查。从上面的命令我们得到:

content/js/restclient.js:51:        i18nStrings = new restclient.StringBundle("chrome://restclient/locale/restclient.properties");
modules/StringBundle.js:59: *     new StringBundle("chrome://example/locale/strings.properties");

第一个是locale chrome: URI。您未在 chrome.manifest 中指定locale。因此,它肯定是无效的。查看 content / js / restclient.js 的第51行,它处于活动代码中。实际使用时,它将无效。

第二种可能性是典型的chrome: URI示例。该行以*开头暗示它可能是评论。检查 modules / StringBundle.js 的第59行显示它是一条评论。

下一步,如果尚未找到问题,则将解析已知的无效chrome: URI并测试是否解决了问题。在这种情况下,我们已经知道问题所在,因此无需检查。

但是,鉴于chrome://restclient/locale/restclient.properties无效且A)您的插件中没有此类文件且B) chrome.manifest 中未定义locale这意味着如果该代码被执行,它将失败。基本上,似乎函数restclient.i18n是死/坏代码,应该删除。鉴于该函数是 modules / StringBundle.js 文件的唯一用途,它也可以被删除。显然,如果这是你正在积极研究的东西,那么这是一个不同的故事。

在处理此问题时,我还注意到浏览器控制台中的其他一些错误,您可能应该看一下:

21:26:37.975 SyntaxError: test for equality (==) mistyped as assignment (=)?1 chrome://restclient/content/js/bootstrap.js:1557:33
21:26:37.989 TypeError: variable url redeclares argument1 chrome://restclient/content/js/restclient.main.js:376:8

虽然这些本身并不是错误,但通常希望在加载项的正常操作期间浏览器控制台中不显示任何内容。虽然,鉴于jquery.js中报告的各种错误,还有几个呢?