Showing posts with label xpcom. Show all posts
Showing posts with label xpcom. Show all posts

Wednesday, September 8, 2010

iX script

I wrote a small script for investigating xpconnect objects at runtime, iX (investigate Xpconnect).

If you paste that code in a JavaScript file, and run iX(something), it will dump all the info it can find about the object: all regular JavaScript properties, as well as all valid interfaces that you can QueryInterface and GetInferface on that object, and also the node hierarchy. And it tries not to crash when doing so.

(There is probably already something to do this that I am not aware of.)

Friday, May 7, 2010

Lesson #1: Improper XPCOM definitions can lead to silent failure

I've been tasked with implementing electrolysis (e10s) support for FTP. That means letting child processes (content) send requests to the parent process (chrome), which actually does the networking - while from the perspective of the child process, the interface to an FTP channel is the same.

As this is just my second week at Mozilla, I am still learning the build process, fundamental technologies like XPCOM, and other stuff about the codebase. So I ran into some problems, which I'll mention here on the blog in hopes that they help other people that search for the same keywords.

So, lesson #1 is: Improper XPCOM definitions can lead to silent failure.

Specifically, the issue was that this:

  NS_IMPL_ADDREF_INHERITED(FTPChannelChild, FTPBaseChannel)
  NS_IMPL_RELEASE_INHERITED(FTPChannelChild, FTPBaseChannel)

  NS_INTERFACE_MAP_BEGIN(FTPChannelChild)
    NS_INTERFACE_MAP_ENTRY(nsIRequest)
    NS_INTERFACE_MAP_ENTRY(nsIChannel) 
    NS_INTERFACE_MAP_ENTRY(nsIFTPChannel)
  NS_INTERFACE_MAP_END_INHERITING(FTPBaseChannel)

was needed, and I was missing the nsIRequest line. I missed it because nsIRequest is a parent interface, and I didn't realize it was also necessary. And, indeed, when sent through JavaScript to a function that expects to receive an object with that interface, it fails. What was tricky was it silently failed - I called a JavaScript function, which was known to work, and it simply returned a failure code, without even starting the function. Only by stepping through all the JS embedding code did it eventually become clear to me that a call to QueryInterface was failing, so the JS embedding code was failing to set up the parameters for the JS function, and not even calling it.