a life of coding

Thursday, May 29, 2008

XPCOM nsISupports Proxy Crashes

In building an application based on XULRunner, we've uncovered a number of bugs in the Mozilla codebase. One that really bothers me is the implementation of asynchronous object proxies. First, here's a brief overview of nsISupports proxies.

XPCOM

XPCOM is a generalized system for calling methods on objects. These objects can be implemented in C++, JavaScript, or Python (using a 3rd party library called PyXPCOM). XPCOM is the mechanism for defining Firefox extensions and writing applications that use XULRunner.

Working With Threads

One handy feature of XPCOM is the ability to have your method call execute in another thread. One example of this is a background thread that wants to do something to the UI, such as update a progress bar. Similarly to Java, Cocoa, and some Windows programming, UI access in Mozilla has to happen on the main thread. Another common situation is sending commands to a worker thread from the main thread. In both cases, we have a simple command to issue, but a direct method call is the wrong way to accomplish this.

So XPCOM has a mechanism for defining proxy objects that look identical to the original object, but executes your request in another thread. There are two flavors of this, synchronous (PROXY_SYNC) which will block your thread, and asynchronous (PROXY_ASYNC) which queues a request in the other thread and continues on. One implication of asynchronous dispatch is that there will be no return value, since you don't wait for the method to finish.

The Async Warning

The page describing proxies contains a very specific warning: if you pass variables by reference and those variables are on the stack, bad things will happen. It turns out that this is a bit understated, and doesn't convey some of the subtleties, so I will try to clarify.

Asynchronous XPCOM Proxies Are Fundamentally Broken

Using them will likely cause you nothing but pain. This pain will be in the form of totally random crashes, with meaningless (but seemingly useful) stack traces. You will ask people for help, and they will have no idea where to start. Unless you are intimately familiar with the XPCOM message dispatch and QueryInterface source code, PROXY_ASYNC should be a keyword which in your mind expands to Bad Bad Evil Crashing.

Why? Well, it turns out that return values are implemented as "out" parameters, which is a fancy way of saying references on the stack, which you may have recently learned is something that you should never mix with PROXY_ASYNC. So, if you were to call any method on an asynchronous proxy that could return a value, it will corrupt memory. There's actually no uncertainty here, XPCOM will write over some random memory address which is probably on some poor thread's stack.

The Workaround

"Ah!" you say, I can use PROXY_ASYNC and still sleep at night as long as I only call methods that return "void". Well, you might sleep a night or two, but soon you'll realize that bad things are still happening. The reality is, there is no workaround (sorry!). Even if you avoid methods with "out" or "in out" parameters, and ones that return values, Mozilla will still punish you by calling exactly these sorts of methods internally. If you're using a scripting language (generally JavaScript), things are even worse for you, because it makes a bunch more of these calls to set up your script object.

The Documentation

This bug is currently documented in buzilla. Unfortunately, there seems to be no workable solution to the situation. On top of that, the people responsible for the code base don't know why anyone would even want to use asynchronous dispatch. So, that doesn't sound good. The only real fix is to find a way to remove any mention of PROXY_ASYNC from your code. Depending on your application, this may be an easy fix. So far for us, this has not been the case. (Mozilla was never intended to do what we're doing)

1 Comments:

  • XPCOM! I remember when I was building the ChucK firefox plugin

    though you seem to have encountered subtleties that I did not, I remember also of the crashing

    Maybe I should graduate from monkey school. or just release it?

    By Blogger Graham, At 5/29/08 7:13 PM  

Post a Comment



<$I18N$LinksToThisPost>:

Create a Link

<< Home