July 13, 2012 § 16 Comments
Caveat This is a hack. Doing this may void your warranty. Also, if I were reviewing an add-on that depends on this, I would reject it. You have been warned.
Let’s see how. At the time of this writing, the following steps require a recent Nightly build of Firefox/Thunderbird/… but the feature should be available shortly to released versions.
Import js-ctypes and OS.Constants.
Components.utils.import("resource://gre/modules/ctypes.jsm"); Components.classes["@mozilla.org/net/osfileconstantsservice;1"]. getService(Components.interfaces.nsIOSFileConstantsService). init();
If your code is executed in a worker thread, this extract is not required.
If you are running an older version of Firefox (i.e. anything except a recent Nightly), you will need to replace the references to
OS.Constants with more verbose calls to xpcom, and this will work only on the main thread.
libxul is the native library that contains the Gecko internals. To open it,
let libxul = ctypes.open(OS.Constants.Path.libxul);
Play with it!
The definition of
DumpJSStack is the following:
extern "C" void DumpJSStack()
In other words, this function takes no argument, returns nothing and is designed to be called from C (or from js-ctypes). This makes it an ideal candidate to import it with js-ctypes:
let dumpJSStack = libxul.declare("DumpJSStack", ctypes.default_abi, /*return*/ ctypes.void_t);
We can now use the function as if it were a regular JS function:
(prints some information about how you got to this point – works only from the main thread)
Play with it: printf_stderr
We can similarly import function
printf_stderr, which is often quite useful for debugging:
extern "C" void printf_stderr(char* fmt, ...);
To import it:
let printf_stderr = libxul.declare("printf_stderr", ctypes.default_abi, /*return*/ ctypes.void_t, /*fmt*/ ctypes.char.ptr, /* ... */ "...");
There are many more features that can be accessed through libxul and that go beyond the scope of this blog entry. Let us simply list a few of them.
- walking the native stack using
NS_StackWalk? see file nsStackWalk.h for more details;
- interacting with other processes using
PR_KillProcess? see prprocess.h for more details;
- using the built-in cryptographic features of the Mozilla Platform? see nss/* for more details;
and certainly more…
Note that, by opposition to XPCOM-based calls, most js-ctypes based calls work from all threads.