Re: nsIBadCertListener and JVM death

Greg Bowyer <[email protected]> Tue, 12 Jun 2007 23:48:58 +0100
Newsgroups gmane.comp.mozilla.devel.java
Message-ID <uNWdnflyusHfvvLbnZ2dnUVZ_syunZ2d__33497.3555909984$1181688917$gmane$org@mozilla.org>
Michal Ceresna wrote:
> On Tuesday 12 June 2007, Greg Bowyer wrote:
> Hello,
> 
>> A bug that came to my attention today is that when the thing hits a
>> broken secure certificate, it presents the (not present) end user with a
>> confirmation dialog asking them what to do.
>> Since the thing is headless, I need to automatically handle this myself,
>> the code that I have implemented for this is nsIBadCertListener which I
>> then register with the componentRegistrar like so
> Isn't it possible to implement that using nsIPromptService?  
> This is what we do to solve the same problem as you have.
Already implemented nsIPromptService, it doesn't allow to override this 
behavior (unfortunately). :(
>> However when this code runs I get the lovely world of VM death, and
>> hence a h_pid_err_xxx.log.
>> Running this on my 1.9 build (which has debug info on) I get the
>> following information from XPCom / XULRunner which leads me to believe
>> that this is a fault in JavaXPCom's handling of threads. I assume that
>> whatever invokes the security prompt (Necko / libnspr prehaps ?!?!?) is
>> spawning a thread for it, which appears to confuse things.
> 
> Most of the code in Mozilla is not thread-safe. 
> 
> I mean, not multi-threaded in the sense as you know from java.
> Mozilla mostly uses the concept of event queues to break
> execution into smaller blocks.
> E.g. all page rendering code, gui, mouse and key handling, 
> JS execution run on the same (GUI) thread.
> 
> Therefore, there are several mechanisms in mozilla code
> that check that xpcom components are accessed in
> a tread-safe way.

I was under this impression, that it was a event queue / pump system, to 
be honest I seriously dislike threading in general and the entire design 
of that is done so far puts the control in the hands of xpcom / 
xulrunner (once the thread on which I create the mozilla embedding 
blocks) I don't access anything from another thread.

>> ###!!! ASSERTION: nsJavaXPTCStub not thread-safe:
>> '_mOwningThread.GetThread() == PR_GetCurrentThread()', file
> For example, this check is implemented in AddRef and tests that 
> the method (current code) is executing on the same thread 
> that created instance of the xpcom component.

This is whats slightly got me, my chain of events is like so:
  1) Java starts up, does the setup work for embedding
  2) XPCom and moz embedding fires up, java blocks its thread as xpcom 
runs the event loop
  3) XPCom does some initial setup (on the xulrunner side)
  4) All accesses are now done from XPCom to java, e.g. xpcom calls java
  5) The work finishes, XPCom terminates itself, java does some minor 
cleanup and the process ends

So during the setup I register creation factories for several things 
including the nsIBadCertListener (but also an implementation of 
nsIPromptService, which works correctly)

So once XPCom needs an instance of these components, surly that same 
thread (inside xulrunner) obtains the factory from the component 
registrar, creates the instance and then uses it.

So any thread change is happening inside xpcom / xulrunner and is out of 
my control.

 > So, my estimate is that you have created an instance of XPCOM
 > object on a java thread A and then you try to access it on thread B.
Yup I thought the same, :(

>> ###!!! ASSERTION: Current thread not attached to given JVM instance: 'rc
>> == JNI_OK && env != nsnull', file
>> /home/greg/projects/xulrunner/mozilla/extensions/java/xpcom/src/nsJavaXPCOM
>> BindingUtils.cpp, line 975
> This error occurs when a native thread tries to do a callback to java,
> but because it is not attached to the jvm, it can not obtain
> the jvm pointer.
> This simplest solution without changes in javaxpcom is 
> 1) implement your code in a way, that the callback occurs on GUI thread
> 2) reimplement this particular part of code as a native xpcom/c++ component

1) I think my code is already organised in a way which is most friendly 
to XPCom, especially since the creation and useage of the 
nsIBadCertListener should be being performed by it, rather than by myself.
However since I have avoided the dreaded threading question, by putting 
the control into the hands of the C side, are there any pointers as to 
slightly better organization.

2) Humm I was kind of afraid of this as an approach, I already have a 
small amount of native code involved and would rather not have any more, 
if this still turns out to be a requirement I would go with it, but it 
raises the question of how to register the C++ implementation, since the 
embedding setup is in the hands of java (novice question I know but one 
I cant find any answers to)

I might take a snoop into the JavaXPCom code that is called inside 
xulrunner / xpcom to see if I can work out whats wrong.

> best regards,
> Michal

Cheers
	Greg