Debugging a XULRunner Application

The easiest way to debug a XULRunner application is to get the system to tell you what's wrong! There are two different consoles available and various preferences which will ensure that the information you need to know is displayed on them.

See also

Debugging JavaScript

Prefs

Setting the following prefs will make your debugging life much easier!

Preferences should be in a .js file in the directory %appname%/defaults/preferences/. It doesn't matter what the file is called (as long as the extension is .js), so debug.js is as good as any!

/* debugging prefs */
pref("browser.dom.window.dump.enabled", true);
pref("javascript.options.showInConsole", true);
pref("javascript.options.strict", true);
pref("nglayout.debug.disable_xul_cache", true);
pref("nglayout.debug.disable_xul_fastload", true);

Don't forget to change these preferences back to their defaults when you've finished debugging; leaving them as-is can significantly harm performance and usability.

See: Preference reference for more information about these preferences.

Console

To enable a console on windows, start XULRunner with the -console argument. Note that -console goes after the application.ini argument: e.g. xulrunner.exe /path/to/application.ini -console

To output text to the console, use dump("my text here\n");. This will only work if the pref pref("browser.dom.window.dump.enabled", true) is enabled.

To output dump calls instead to a file, set browser.dom.window.dump.file to the file destination where the log should be created and restart the application.

If you would like the console messages to appear in the console you used to launch the application, you can use the Gecko Console Redirector. Precompiled binaries are available in the zipped archive https://github.com/matthewkastor/Redirector/archive/master.zip under Redirector-master\Gecko\Console Redirector\bin\Release Copy all the dll's and the exe to wherever you want. Then run Console Redirector.exe /?

JavaScript Console

To enable the JS console, start XULRunner with the -jsconsole argument.

Note: If you are not using the stub executable to launch the application, the -jsconsole argument is after the application.ini argument: e.g. xulrunner.exe /path/to/application.ini -jsconsole

By default the JS console only shows errors from web content. To show errors in chrome JavaScript, the pref pref("javascript.options.showInConsole", true) must be set.

To log JS errors to disk, set the environment variable XRE_CONSOLE_LOG to the path to the filename. i.e. export XRE_CONSOLE_LOG=/path/to/logfile or set XRE_CONSOLE_LOG=C:\path\to\logfile.

To output messages to the JavaScript console

There are two ways to output messages to the JS console:

  • Components.utils.reportError(str) will output str as an "error" (i.e. with the red stop icon next to it).
  • jsdump(str) (function defined below) will output str as a "message" with a speech bubble icon next to it:
function jsdump(str) {
  Components.classes['@mozilla.org/consoleservice;1']
            .getService(Components.interfaces.nsIConsoleService)
            .logStringMessage(str);
}

For more information about the error console see the Error Console and Browser Console article.

Browser Debugger

As of Gecko 44, it is no longer possible to start the DevTools server from XUL apps. See bug 1244163.

Starting with XULRunner 24, you should use the Firefox Browser Debugger to debug your XULRunner apps. Add the following code to your XUL app:

Components.utils.import('resource://gre/modules/devtools/dbg-server.jsm');
if (!DebuggerServer.initialized) {
  DebuggerServer.init();
  // Don't specify a window type parameter below if "navigator:browser"
  // is suitable for your app.
  DebuggerServer.addBrowserActors("myXULRunnerAppWindowType");
}
DebuggerServer.openListener(6000);

For XULRunner version 37+ the code to enable the debugger has changed:

Components.utils.import('resource://gre/modules/devtools/dbg-server.jsm');
if (!DebuggerServer.initialized) {
  DebuggerServer.init();
  DebuggerServer.addBrowserActors();
  DebuggerServer.allowChromeProcess = true;
}

let dbgListener=DebuggerServer.createListener();
dbgListener.portOrPath=6000;
dbgListener.open();

Add the following to your prefs.js: (in recent ffox, edit about:config instead)

pref("devtools.debugger.remote-enabled", true);

In Firefox, go to Tools > Web Developer > Connect... and you should be able to point the debugger to your app. Happy debugging :)

Venkman

Follow these instructions to install Venkman into your XULRunner application (XULRunner 1.9 and later):

  1. Get Venkman from addons.mozilla.org (v0.9.87 at the time of writing). To download the package, right-click the install link and save the package locally.
  2. Create a directory <application>/distribution/bundles/venkman. Unzip the package into that directory.
  3. Add <script src="chrome://venkman/content/venkman-overlay.js" /> to one of your XUL windows.
  4. Add UI to open Venkman to your window (it could be a menu item or a toolbar button). Make it call start_venkman() when activated.

Troubleshooting

x-jsd is not a registered protocol

If the message "x-jsd is not a registered protocol" appears when trying to open *.js files in Venkman, then add an empty file called .autoreg in the same directory as your XULRunner binary. If .autoreg already exists, then edit it to force the last modified time to be updated. XULRunner will then notice the new components file.

When adding a component to a XULRunner application, change the BuildID in application.ini.

function toOpenWindowByType is not defined

If you get an error that "function toOpenWindowByType is not defined" you may add the following function to your scripts (doesn't seem to be in the venkman overlay):

function toOpenWindowByType(inType, uri) {
  var winopts = "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar";
  window.open(uri, "_blank", winopts);
}
I can't see my pages, functions ...

If your pages are not in the loaded script window, uncheck the menu item "debug\exclude Browser Files" and find them in open windows tab

When opening a JS file in Venkman, the code is unformatted and I get the following error in the jsconsole...

Security Error: Content at x-jsd:source?location=chrome%3A%2F%2Fvenkman%2Fcontent%2Fvenkman-overlay.js&instance=12
may not load or link to chrome://venkman/skin/venkman-source.css.

Note the "New in Firefox 3" attribute "contentaccessible" on https://developer.mozilla.org/En/Chrome_Registration so as per http://markmail.org/message/ezbomhkw3bgqjllv#query:x-jsd+page:1+mid:xvlr7odilbyhn6v7+state:results change the manifest to have this line:

content venkman jar:venkman.jar!/content/venkman/ contentaccessible=yes
I get errors about not being able to open contentAreaUtils.js, contentAreaDD.js, findUtils.js, or contentAreaUtils.js...

Inspired by http://article.gmane.org/gmane.comp.mozilla.devel.jsdebugger/859 I extracted venkman.jar, opened venkman\content\venkman\venkman-scripts.xul and changed:

@@ -54,11 +54,11 @@
     <script src="chrome://global/content/nsTransferable.js"    />
     <script src="chrome://global/content/nsClipboard.js"    />
     <script src="chrome://global/content/nsDragAndDrop.js"    />
-    <script src="chrome://communicator/content/contentAreaUtils.js"    />
-    <script src="chrome://communicator/content/contentAreaDD.js"    />
-    <script src="chrome://communicator/content/findUtils.js"    />
-    <script src="chrome://browser/content/contentAreaUtils.js"    />
+    <script src="chrome://global/content/contentAreaUtils.js"    />
+    <script src="chrome://global/content/contentAreaDD.js"    />
     <script src="chrome://global/content/findUtils.js"    />
+    <script src="chrome://global/content/contentAreaUtils.js"    />
+    <script src="chrome://global/content/findUtils.js"    />
     <script src="chrome://global/content/strres.js"    />