We are using XPConnect with Spidermonkey for a "standalone" application. 
The build is ff1.5 final release.  Unfortunately, we are getting an access 
violation on shutdown of the GRE in JS_HashTableEnumerateEntries, or the 
application hangs in what seems to be an infinite loop in a related piece of 
code.   At the end, I have included call stacks.  Oddly, the crash seems 
tobe reproducable only while running outside the MSVC++ (7.1) debugger. 
However, sometimes it does not crash at all.  If I comment out the 
AddFunction method below, then it seems to work, but we need that 
functionality.  I have narrowed it down to the 
myXPConnectService->WrapNative call that is causing the problem, but I don't 
know how it does that.  (If I leave it commented in it crashes.  Otherwise 
it does not.)  For the records, the functionality of the code works fine, 
when all of the code is commented in.

In an older thread I posted to mozilla.dev.tech.js-engine, I thought the 
problem might be some of the Spidermonkey calls, but I now doubt that is the 
case. 
http://groups.google.ca/group/mozilla.dev.tech.js-engine/browse_frm/thread/72c0dea3a5533b4e/8b8fc13b3b4ba862?lnk=st&q=crash+JS_HashTableEnumerateEntries&rnum=1#8b8fc13b3b4ba862


Does anyone have any insight into how we can fix these crashes?  Thanks.

// For reference only.
NS_IMETHODIMP
JSEngine::StartScriptEngine(PRBool *_retval)
{
  nsresult result;

  isWorldLoaded = false;

  // get the JSRuntime from the runtime svc
  result =
myServiceManager->GetServiceByContractID("@mozilla.org/js/xpc/RuntimeService;1",
                                      NS_GET_IID(nsIJSRuntimeService),
                                      getter_AddRefs(myRuntimeService));

  if(NS_FAILED(result) ||
NS_FAILED(myRuntimeService->GetRuntime(&myRuntime)) || !myRuntime)
  {
    return NS_ERROR_FAILURE;
  }

  result =
myServiceManager->GetServiceByContractID("@mozilla.org/js/xpc/ContextStack;1",
                                      NS_GET_IID(nsIJSContextStack),
                                      getter_AddRefs(myContextStack));

  // get a safe context and push it on the stack
  //setup js context
  myContext = JS_NewContext(myRuntime, gStackSize);
  if(!myContext)
  {
    return NS_ERROR_FAILURE;
  }

  myContextStack->Push(myContext);

  //get xpconnect
  result = myServiceManager->GetService(nsIXPConnect::GetCID(),
                                      NS_GET_IID(nsIXPConnect),
                                      getter_AddRefs(myXPConnectService));

  if(!myXPConnectService)
  {
    return NS_ERROR_FAILURE;
  }

  // set up the global object, make it the wrapped native VOM Viewer xpcom
object
  myGlobal = JS_NewObject(myContext, &global_class, NULL, NULL);

  if (!JS_InitStandardClasses(myContext, myGlobal))
  {
    return NS_ERROR_FAILURE;
  }

  if (!JS_DefineFunctions(myContext, myGlobal, glob_functions))
  {
    return NS_ERROR_FAILURE;
  }

  if (NS_FAILED(myXPConnectService->InitClasses(myContext, myGlobal)))
  {
    return NS_ERROR_FAILURE;
  }

  myXPConnectService->SetSafeJSContextForCurrentThread( myContext );

  //setup the security manager
  mySecurityManager = new ScriptSecurityManager();
  if(!mySecurityManager)
  {
    return NS_ERROR_FAILURE;
  }
  if(!NS_SUCCEEDED(myXPConnectService->SetSecurityManagerForJSContext(
                     myContext,
                     mySecurityManager,
                     nsIXPCSecurityManager::HOOK_ALL)))
  {
    return NS_ERROR_FAILURE;
  }

  //setup error reporting
  JS_SetErrorReporter(myContext, myErrorCallback);
  // set the branch callback for GC
  JS_SetBranchCallback(myContext, myBranchCallback);

  return NS_OK;
}


NS_IMETHODIMP
JSEngine::AddFunction( nsIDOMEventTarget *target,
                                               const nsAString & eventName,
                                               const nsAString &
jsEventHandlerName,
                                               PRBool capture,
                                               PRBool *_retval )
{
  NS_ENSURE_ARG_POINTER( target );
  NS_ENSURE_ARG_POINTER( _retval );
  NS_ENSURE_STATE( myContext );
  NS_ENSURE_STATE( myXPConnectService );

  *_retval = PR_FALSE; // be pessimistic.
  nsEmbedString name( eventName );
  nsEmbedString handlerName( jsEventHandlerName );

  nsCOMPtr< nsIXPConnectJSObjectHolder > holder;
  NS_ENSURE_SUCCESS( myXPConnectService->WrapNative( myContext,
                                                     myGlobal,
                                                     target,
                                                     NS_GET_IID(
nsISupports ),
                                                     getter_AddRefs(
holder ) ),
                     NS_ERROR_UNEXPECTED );

  JSObject* jsTarget = nsnull;
  NS_ENSURE_SUCCESS( holder->GetJSObject( &jsTarget ),
NS_ERROR_UNEXPECTED );
  NS_ENSURE_STATE( jsTarget );

  universal_string eventNameStr( name.get() );  // Converts to wstring.
  const char *argList[] = { "event" };
  JSFunction* function =
      ::JS_CompileUCFunction( myContext,
                              jsTarget,
                              universal_string_val< TCHAR >(
eventNameStr ).c_str(),
                              1,
                              argList,
                              (jschar*) handlerName.get(),
                              handlerName.Length(),
                              __FUNCTION__,
                              __LINE__ );
  if ( function == NULL )
  {
      return NS_ERROR_FAILURE;
  }

  boost::shared_ptr< JSObject* > functionObject( new JSObject* );
  NS_ENSURE_TRUE( functionObject, NS_ERROR_OUT_OF_MEMORY );
  *functionObject = ::JS_GetFunctionObject( function );

  NS_ENSURE_TRUE( ::JS_AddNamedRootRT( myRuntime, &(*functionObject),
                                       "JScriptEngine::AddEventListener" ),
                  NS_ERROR_OUT_OF_MEMORY );
  myGCRootsToRemove.push_back( functionObject );  // just a std::vector
member variable.

  // Now that the event handler was compiled and assigned as a property to
the target,
  //  we can go about wrapping it in an event listener and add it as a
listener to the target.
  nsCOMPtr< vIJavaScriptable > jsListener;
  // This is our own listener implementation.  We are not using it with the
Mozilla DOM, but a similar event
  // handling structure instead.
  componentManager->CreateInstanceByContractID( JSEVENTLISTENER_CONTRACTID,
                                        NULL,
                                        NS_GET_IID( vIJavaScriptable ),
                                        getter_AddRefs( jsListener ) );
  NS_ENSURE_SUCCESS( jsListener->SetJsContext( myContext ),
NS_ERROR_UNEXPECTED );
  NS_ENSURE_SUCCESS( jsListener->SetScope( myGlobal ),
NS_ERROR_UNEXPECTED );
  nsCOMPtr< nsIDOMEventListener > listener( do_QueryInterface(
jsListener ) );

  nsresult result = target->AddEventListener( eventName, listener,
capture );
  NS_ENSURE_SUCCESS( result, NS_ERROR_UNEXPECTED );

  *_retval = PR_TRUE;
  return NS_OK;
}

class RemoveGCRoot : public std::unary_function< JSObject*, void >
{
public:
  RemoveGCRoot( JSRuntime* runtime ) : myRuntime( runtime ) {}
  void operator()( boost::shared_ptr< JSObject* > gcRoot ) const
  {
    if ( gcRoot == NULL ) return;
    JSBool success = ::JS_RemoveRootRT( myRuntime, reinterpret_cast< void*
 >( &(*gcRoot) ) );
    assert( success );
  }

private:
  JSRuntime*        myRuntime;
};

NS_IMETHODIMP
JSEngine::StopScriptEngine(PRBool *_retval)
{
  std::for_each( myGCRootsToRemove.begin(), myGCRootsToRemove.end(),
RemoveGCRoot( myRuntime ) );
  myGCRootsToRemove.clear();

  // Prevent use of myContext after it is deleted.
  myXPConnectService->SetSafeJSContextForCurrentThread( NULL );
  // Take out the trash.
  JS_ClearScope( myContext, myGlobal );
  JS_GC( myContext );
  // Clear our entry in the JSContext, bugzilla bug 66413
  JS_SetContextPrivate(myContext, nsnull);
  // Clear the branch callback, bugzilla bug 238218
  JS_SetBranchCallback(myContext, nsnull);
  myErrorCallback = 0;
  myBranchCallback = 0;
  myGlobal = 0;
  myContextStack->Pop(&myContext);

  myXPConnectService->SyncJSContexts();

  // This calls JS_DestroyContext for us.
  myXPConnectService->ReleaseJSContext(myContext, false);

  // Do not call JS_DestroyRuntime(myRuntime);  It will be called in
NS_ShutdownXPCOM, because
  //  XPConnect still has a context which references it.
  // Do not call JS_ShutDown();  It will be called in NS_ShutdownXPCOM.

  delete mySecurityManager;
  myRuntime = 0;
  myContext = 0;
  myContextStack   = nsnull;
  myXPConnectService = nsnull;
  myRuntimeService = nsnull;

  myLogManager = nsnull;

  return NS_OK;
}

  [EMAIL PROTECTED]()  + 0x283bd
  ntdll.dll!_DbgPrint()  + 0x1a
  [EMAIL PROTECTED]()  + 0x12
  [EMAIL PROTECTED]()  + 0x2b8e2
  msvcr71.dll!free(void * pBlock=0x00360198)  Line 103 C
  js3250.dll!js_free_atom(void * priv=0x01f753dc, JSHashEntry *
he=0x00360198, unsigned int flag=1)  Line 252 + 0x11 C
> js3250.dll!JS_HashTableRawRemove(JSHashTable * ht=0x01f5dfd0, JSHashEntry
> * * hep=0x0012f53c, JSHashEntry * he=0x00360198)  Line 280 + 0x13 C
  js3250.dll!JS_HashTableEnumerateEntries(JSHashTable * ht=0x01f5dfd0, int
(JSHashEntry *, int, void *)* f=0x020a862e, void * arg=0x01f753dc)  Line 382
+ 0x11 C
  js3250.dll!js_SweepAtomState(JSAtomState * state=0x01f753dc)  Line 494 +
0xc C
  js3250.dll!js_GC(JSContext * cx=0x01f187e0, unsigned int gcflags=2)  Line
1821 C
  js3250.dll!js_ForceGC(JSContext * cx=0x01f187e0, unsigned int gcflags=2)
Line 1510 + 0x1f C
  js3250.dll!js_DestroyContext(JSContext * cx=0x01f187e0, JSGCMode
gcmode=JS_FORCE_GC)  Line 266 C
  js3250.dll!JS_DestroyContext(JSContext * cx=0x01f187e0)  Line 932 + 0xb C
  xpc3250.dll!XPCJSContextStack::~XPCJSContextStack()  Line 62 C++
  xpc3250.dll!XPCJSContextStack::`scalar deleting destructor'()  + 0x8 C++
  xpc3250.dll!XPCPerThreadData::CleanupAllThreads()  Line 544 + 0xe C++
  xpc3250.dll!nsXPConnect::~nsXPConnect()  Line 150 C++
  xpc3250.dll!nsXPConnect::`scalar deleting destructor'()  + 0x8 C++
  xpc3250.dll!nsXPConnect::Release()  Line 48 + 0x23 C++
  xpc3250.dll!nsXPConnect::ReleaseXPConnectSingleton()  Line 244 C++
  xpc3250.dll!xpcModuleDtor(nsIModule * self=0x01f51fd8)  Line 133 C++
  xpcom_core.dll!nsGenericModule::Shutdown()  Line 339 + 0x3 C++
  xpcom_core.dll!nsGenericModule::`scalar deleting destructor'()  + 0xe C++
  xpcom_core.dll!nsGenericModule::Release()  Line 244 + 0x20 C++
  xpcom_core.dll!nsDll::Shutdown()  Line 271 + 0x6 C++
  xpcom_core.dll!nsFreeLibrary(nsDll * dll=0x7c93040c, nsIServiceManager *
serviceMgr=0x0012f710, int when=3)  Line 291 C++
  xpcom_core.dll!nsFreeLibraryEnum(nsHashKey * aKey=0x01f51fc0, void *
aData=0x01f2a710, void * closure=0x00000000)  Line 360 + 0x28 C++
  xpcom_core.dll!hashEnumerate(PLDHashTable * table=0x0036efe4,
PLDHashEntryHdr * hdr=0x0036f028, unsigned int i=0, void * arg=0x0012f770)
Line 131 + 0x13 C++
  xpcom_core.dll!PL_DHashTableEnumerate(PLDHashTable * table=0x00000000,
PLDHashOperator (PLDHashTable *, PLDHashEntryHdr *, unsigned int, void *)*
etor=0x0037665a, void * arg=0x0012f770)  Line 621 + 0xb C
  xpcom_core.dll!nsHashtable::Enumerate(int (nsHashKey *, void *, void *)*
aEnumFunc=0x0039865f, void * aClosure=0x0012f788)  Line 319 + 0x16 C++
  xpcom_core.dll!nsNativeComponentLoader::UnloadAll(int aWhen=3)  Line 978
C++
  xpcom_core.dll!nsComponentManagerImpl::UnloadLibraries(nsIServiceManager *
serviceMgr=0x00000000, int aWhen=3)  Line 3122 C++
  xpcom_core.dll!nsComponentManagerImpl::Shutdown()  Line 900 C++
  xpcom_core.dll!NS_ShutdownXPCOM_P(nsIServiceManager * servMgr=0x00000000)
Line 842 + 0x5 C++
  foo.exe!_GRE_Shutdown()  Line 515 + 0x7



Or to "unpin pinned atoms":

 js3250.dll!JS_HashTableEnumerateEntries(JSHashTable * ht=0x01f23840, int
(JSHashEntry *, int, void *)* f=0x020a8677, void * arg=0x00000000)  Line 363
C
  js3250.dll!js_UnpinPinnedAtoms(JSAtomState * state=0x01f753dc)  Line 511 +
0xd C
  js3250.dll!js_DestroyContext(JSContext * cx=0x01f188d0, JSGCMode
gcmode=JS_FORCE_GC)  Line 227 C
  js3250.dll!JS_DestroyContext(JSContext * cx=0x01f188d0)  Line 932 + 0xb C
  xpc3250.dll!nsXPConnect::ReleaseJSContext(JSContext *
aJSContext=0x01f188d0, int noGC=0)  Line 1205 C++
  ScriptEngine.dll!JScriptEngine::StopScriptEngine(int * _retval=0x0012ee68)
Line 419 C++
  Controls.dll!ViewWin32::WndProcess(HWND__ * hWnd=0x000406f8, unsigned int
message=2, unsigned int wParam=0, long lParam=0)  Line 1876 C++
  Controls.dll!WndProc(HWND__ * hWnd=0x000406f8, unsigned int message=2,
unsigned int wParam=0, long lParam=0)  Line 47 C++
  [EMAIL PROTECTED]()  + 0x28
  [EMAIL PROTECTED]()  + 0xb7
  [EMAIL PROTECTED]()  + 0x4d
  [EMAIL PROTECTED]()  + 0x24
  [EMAIL PROTECTED]()  + 0x13
  [EMAIL PROTECTED]()  + 0xc
  [EMAIL PROTECTED]()  + 0x27
  [EMAIL PROTECTED]()  + 0x57
  Controls.dll!MainFrameWin32::WndProcess(HWND__ * hWnd=0x000406ea, unsigned
int message=16, unsigned int wParam=0, long lParam=0)  Line 323 + 0x16 C++
  [EMAIL PROTECTED]()  + 0x28
  [EMAIL PROTECTED]()  + 0xb7
  [EMAIL PROTECTED]()  + 0x4d
  [EMAIL PROTECTED]()  + 0x24
  [EMAIL PROTECTED]()  + 0x13
  [EMAIL PROTECTED]()  + 0xc
  [EMAIL PROTECTED]()  + 0x27
  uxtheme.dll!DoMsgDefault()  + 0x29
  uxtheme.dll!OnDwpSysCommand()  + 0x2b
  uxtheme.dll!_ThemeDefWindowProc()  + 0x103
  [EMAIL PROTECTED]()  + 0x18
  [EMAIL PROTECTED]()  + 0x11c46
  Controls.dll!MainFrameWin32::WndProcess(HWND__ * hWnd=0x000406ea, unsigned
int message=274, unsigned int wParam=61536, long lParam=16320066)  Line 323
+ 0x16 C++
  [EMAIL PROTECTED]()  + 0x28
  [EMAIL PROTECTED]()  + 0xb7
  [EMAIL PROTECTED]()  + 0xc8
  [EMAIL PROTECTED]()  + 0x49
  uxtheme.dll!OnDwpNcLButtonDown()  + 0xa8
  uxtheme.dll!_ThemeDefWindowProc()  + 0x103
  [EMAIL PROTECTED]()  + 0x18
  [EMAIL PROTECTED]()  + 0x11c46
  Controls.dll!MainFrameWin32::WndProcess(HWND__ * hWnd=0x000406ea, unsigned
int message=161, unsigned int wParam=20, long lParam=16320066)  Line 323 +
0x16 C++
  [EMAIL PROTECTED]()  + 0x28
  [EMAIL PROTECTED]()  + 0xb7
  [EMAIL PROTECTED]()  + 0xdc
  [EMAIL PROTECTED]()  + 0xf
  Controls.dll!MainFrameWin32::run()  Line 126 C++
  Controls.dll!MainFrame::Run()  Line 68 C++


Hangs in an infinite (?) while loop in this call stack

> js3250.dll!JS_HashTableEnumerateEntries(JSHashTable * ht=0x046e7318, int
> (JSHashEntry *, int, void *)* f=0x04868677, void * arg=0x00000000)  Line
> 362 + 0x3 C
  js3250.dll!js_UnpinPinnedAtoms(JSAtomState * state=0x046ebaac)  Line 511 +
0xd C
  js3250.dll!js_DestroyContext(JSContext * cx=0x046e9760, JSGCMode
gcmode=JS_FORCE_GC)  Line 227 C
  js3250.dll!JS_DestroyContext(JSContext * cx=0x046e9760)  Line 932 + 0xb C
  xpc3250.dll!nsXPConnect::ReleaseJSContext(JSContext *
aJSContext=0x046e9760, int noGC=0)  Line 1205 C++
  SEngine.dll!JScriptEngine::StopScriptEngine(int * _retval=0x0013e474)
Line 418 C++




_______________________________________________
dev-tech-xpcom mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-xpcom

Reply via email to