Crash in NSPR from within LDAP C-SDK - Bad MDOverlapped struct from GetQueuedCompletionStatus?

"Matthew M. DeLoera" <[email protected]> Fri, 05 Feb 2010 12:01:17 -0500
Newsgroups gmane.comp.mozilla.devel.directory
Message-ID <[email protected]>
Hello,

I'm getting a crash down within NSPR (I'm using C-SDK 6.06, and NSPR 
4.6.4.0). I'm running in Windows XP. I saw a crash in my release build, 
and I've been running in VS2003 to try and pinpoint it. I rebuilt NSPR 
as debug to get its PDBs.

Anyway, I saw a crash within PR_MD_PAUSE_CPU. It looks like the 
MDOverlapped struct that comes back from GetQueuedCompletionStatus (line 
301 in ntio.c) is bad. It asserts (PR_ASSERT) down below on line 386, 
where it checks that mdOlp->ioModel == _MD_BlockingIO.

I know next to nothing about NSPR - beyond that the LDAP C-SDK is 
internally using it. I'm only making LDAP calls. But, is it the case 
that LDAP causes some threads to be spun up internally within NSPR? And 
in fact, in VS, I see 3 seemingly identical threads to this one that 
asserted. So, it looks like for some reason, NSPR has at least 4 active 
threads all doing the same thing - handing non-blocking IO.

Where I'm going with this, is - are there always supposed to be NSPR 
threads running in the background? Not knowing NSPR, if I've 
theoretically called ldap_unbind and even ldap_memcache_destroy, 
shouldn't any related NSPR threads or whatnot be stopped also?

I'm testing a failure scenario, where I do a non-blocking bind 
(ldapssl_advclientauth_init, ldapssl_init, ldap_memcache_init, 
ldap_simple_bind), the ldap_simple_bind call fails due to network 
errors, and I call ldap_unbind and ldap_memcache_destroy to clean up. I 
periodically repeat this process.

So, when I would have thought I was all cleaned up, sitting idle, and 
awaiting another change to retry this process, why do I have 5 NSPR 
threads active? Is there something else I should call besides 
ldap_unbind that I just haven't noticed? Is this expected behavior, and 
should I think about this in a different way? I'm wondering if the NSPR 
crash isn't something to do with an internal thread that is in an 
indeterminate state, and hence getting bad IO completion status.

Also, I call ldap_simple_bind in a different, temporary thread. I'm not 
sharing the instance between threads, so shouldn't be any worries there. 
But, could that be related as well?

Hopefully someone can give me a hint of the direction to investigate. 
And, I'm still browsing source for ideas.

Thanks!
- Matthew