Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

[CEF 2171] Crash on quit. #7683

Closed
RaymondLim opened this issue Apr 29, 2014 · 47 comments
Closed

[CEF 2171] Crash on quit. #7683

RaymondLim opened this issue Apr 29, 2014 · 47 comments

Comments

@RaymondLim
Copy link
Contributor

Launch Brackets and press Ctrl+Q to quit. You will get a crash with the message saying "Brackets has stopped working."

Workaround: click on 'X' button in the title bar to quit.

@RaymondLim
Copy link
Contributor Author

Below is the call stack from the release build

libcef.dll!521241f6()   
[Frames below may be incorrect and/or missing, no symbols loaded for libcef.dll]    
libcef.dll!51444e5c()   
libcef.dll!51444fab()   
libcef.dll!5143b667()   
libcef.dll!514dbf29()   
libcef.dll!5143ca90()   
libcef.dll!5143c61e()   
libcef.dll!5142853b()   
libcef.dll!514263d1()   
libcef.dll!513f2e67()   
ntdll.dll!_bsearch()  + 0x66 bytes  
Brackets.exe!CefCToCpp<CefV8ValueCToCpp,CefV8Value,_cef_v8value_t>::Release()  Line 79  C++
Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::erase(std::_Tree_const_iterator<std::_Tree_val<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> > > _First, std::_Tree_const_iterator<std::_Tree_val<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> > > _Last)  Line 1382 + 0xb bytes    C++
Brackets.exe!ClientApp::`scalar deleting destructor'()  + 0x1c bytes    C++
Brackets.exe!ClientApp::Release()  Line 138 + 0x2e bytes    C++
Brackets.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)  Line 277    C++
Brackets.exe!__tmainCRTStartup()  Line 275 + 0x1c bytes C
kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes    
ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

@JeffryBooher
Copy link
Contributor

@RaymondLim Does File > Exit crash as well?

@RaymondLim
Copy link
Contributor Author

I didn't try it and now I'm back to master. But I did debug it yesterday and it is our exit command that is quitting immediately instead of waiting for JS callback's return. I believe message handling/routing changes in cef 1750 are causing this behavior.

@JeffryBooher
Copy link
Contributor

I don't know much about the message handling/routing. I do know that the PreKeyEvent gets called twice for keys. One of those calls the os_event is NULL which caused a crash. Do you know of other such places in the code? I was unable to reproduce this.

Can you try to dSym the stack? The CEF functions are nameless.

@RaymondLim
Copy link
Contributor Author

I was wrong in guessing the possible cause to message handling/routing changes in cef 1750. I debug it in the old cef and I got the same breakpoints and Brackets still quit without a crash. When I debug the issue with some more breakpoints in cef 1750 shell, I got the following call stack when it crashes, but the main thread seems to be still alive. So the crash seems to be in the helper thread (or JS side).
crashonquit

@RaymondLim
Copy link
Contributor Author

After realizing the crash is in JS side, I used bisect to locate between sprint-36 and sprint-37. It turns out that it is my commit 4eee5ea that implements the new view states migration from the old pref. Apparently, the crash is the result of the shell code tearing down everything while the pref manager is still handling some fileIO by writing out some view states. @dangoor Can you suggest how we can return a promise from pref manager to the code that handles the quit command?

@redmunds redmunds added the cef label May 4, 2014
@dangoor
Copy link
Contributor

dangoor commented May 5, 2014

@RaymondLim PreferencesBase.PreferencesSystem.save would seem to hold the key. I'm thinking that adding a _finalize method to PreferencesSystem might make sense. That would:

  1. return the promise for the _nextSaveDeferred if there is one. If there isn't, return the promise for the current save operation (if there is one). If there isn't one of those, return a resolved promise.
  2. set a flag that disallows any additional save operations. calls to save() after that point should either throw, reject the promise or just silently fail. I don't know what else happens on quit, so it's hard for me to say which is the best choice there. My guess is that rejecting the promise is likely the best choice.

How does that sound?

@redmunds
Copy link
Contributor

@dangoor I am unable to trap this crash in debugger, so I have attempted to implement your suggestion in PR #7930 . Please take a look and let me know if I understood correctly -- it seems to prevent crash sometimes, but not always.

Reminder: this is a CEF 1750 bug, so be sure to use the jeff/cef_1750 branch on brackets-shell. This is a Windows-only bug and has only been reproduced on Win7, so may be Win7-only.

cc @RaymondLim @JeffryBooher

@RaymondLim
Copy link
Contributor Author

@redmunds I tried in your branch and still crash on exit with Ctrl+Q all the time if I made no changes in any document. If I made a change in a document, then your code seems to work correctly, but not in the build w/o your changes. As you said, I can't trap the crash in debugger. If I do, then I won't be able to use File > Exit or Ctrl+Q to quit any more. It seems like we have dangling promises after debugging.
Note that if I have the same breakpoints in a build before your changes, I can quit without a crash though.

@njx njx added this to the Release #41 milestone Jun 2, 2014
@njx
Copy link

njx commented Jun 2, 2014

Marking Release 41

@redmunds
Copy link
Contributor

redmunds commented Jun 5, 2014

With PR #7930, the problem is greatly reduced and then seems to be a problem with Quiting while JS Code Hints engine is still initializing. See my notes here.

@redmunds
Copy link
Contributor

@JeffryBooher Here's the callstack from the remaining crash:

>   libcef.dll!v8::internal::GlobalHandles::Node::DecreaseBlockUses()  Line 439 + 0x3 bytes C++
    libcef.dll!CefV8ValueImpl::Handle::~Handle()  Line 1062 + 0xd bytes C++
    libcef.dll!CefV8ValueImpl::Handle::`scalar deleting destructor'()  + 0xb bytes  C++
    libcef.dll!CefV8DeleteOnMessageLoopThread::Destruct<CefV8HandleBase>(const CefV8HandleBase * x)  Line 77 + 0x8 bytes    C++
    libcef.dll!CefV8ValueImpl::~CefV8ValueImpl()  Line 1274 + 0x39 bytes    C++
    libcef.dll!CefV8ValueImpl::`scalar deleting destructor'()  + 0x10 bytes C++
    libcef.dll!CefV8ValueImpl::Release()  Line 346 + 0x2d bytes C++
    libcef.dll!CefCppToC<CefV8ValueCppToC,CefV8Value,_cef_v8value_t>::Release()  Line 109   C++
    libcef.dll!CefCppToC<CefV8ValueCppToC,CefV8Value,_cef_v8value_t>::struct_release(_cef_base_t * base)  Line 142 + 0xb bytes  C++
    Brackets.exe!CefCToCpp<CefV8ValueCToCpp,CefV8Value,_cef_v8value_t>::Release()  Line 79  C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617 + 0x1a bytes  C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Erase(std::_Tree_nod<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::_Node * _Rootnode)  Line 1617   C++
    Brackets.exe!std::_Tree<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> >::erase(std::_Tree_const_iterator<std::_Tree_val<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> > > _First, std::_Tree_const_iterator<std::_Tree_val<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> >,std::less<int>,std::allocator<std::pair<int const ,std::pair<CefRefPtr<CefV8Context>,CefRefPtr<CefV8Value> > > >,0> > > _Last)  Line 1382 + 0xb bytes    C++
    Brackets.exe!ClientApp::`scalar deleting destructor'()  + 0x1c bytes    C++
    Brackets.exe!ClientApp::Release()  Line 138 + 0x2e bytes    C++
    Brackets.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)  Line 277    C++
    Brackets.exe!__tmainCRTStartup()  Line 275 + 0x1c bytes C
    kernel32.dll!76ba338a()     
    [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
    ntdll.dll!7724bf32()    
    ntdll.dll!7724bf05()    

@JeffryBooher
Copy link
Contributor

Thanks I'll pass it on

On Jun 16, 2014, at 8:24 PM, "Randy Edmunds" <[email protected]mailto:[email protected]> wrote:

@JeffryBooherhttps://github.com/JeffryBooher Here's the callstack from the remaining crash:

libcef.dll!v8::internal::GlobalHandles::Node::DecreaseBlockUses() Line 439 + 0x3 bytes C++
libcef.dll!CefV8ValueImpl::Handle::~Handle() Line 1062 + 0xd bytes C++
libcef.dll!CefV8ValueImpl::Handle::scalar deleting destructor'() + 0xb bytes C++ libcef.dll!CefV8DeleteOnMessageLoopThread::Destruct<CefV8HandleBase>(const CefV8HandleBase * x) Line 77 + 0x8 bytes C++ libcef.dll!CefV8ValueImpl::~CefV8ValueImpl() Line 1274 + 0x39 bytes C++ libcef.dll!CefV8ValueImpl::scalar deleting destructor'() + 0x10 bytes C++
libcef.dll!CefV8ValueImpl::Release() Line 346 + 0x2d bytes C++
libcef.dll!CefCppToC<CefV8ValueCppToC,CefV8Value,_cef_v8value_t>::Release() Line 109 C++
libcef.dll!CefCppToC<CefV8ValueCppToC,CefV8Value,_cef_v8value_t>::struct_release(_cef_base_t * base) Line 142 + 0xb bytes C++
Brackets.exe!CefCToCpp<CefV8ValueCToCpp,CefV8Value,_cef_v8value_t>::Release() Line 79 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 + 0x1a bytes C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Erase(std::_Tree_nodstd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::_Node * _Rootnode) Line 1617 C++
Brackets.exe!std::_Treestd::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> >::erase(std::_Tree_const_iteratorstd::_Tree_val<std::_Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> > > _First, std::Tree_const_iteratorstd::Tree_val<std::Tmap_traits<int,std::pair<CefRefPtr<CefV8Context,CefRefPtr >,std::less,std::allocator<std::pair<int const ,std::pair<CefRefPtr,CefRefPtr > > >,0> > > Last) Line 1382 + 0xb bytes C++
Brackets.exe!ClientApp::`scalar deleting destructor'() + 0x1c bytes C++
Brackets.exe!ClientApp::Release() Line 138 + 0x2e bytes C++
Brackets.exe!wWinMain(HINSTANCE
* hInstance, HINSTANCE
* hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 277 C++
Brackets.exe!__tmainCRTStartup() Line 275 + 0x1c bytes C
kernel32.dll!76ba338a()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
ntdll.dll!7724bf32()
ntdll.dll!7724bf05()

Reply to this email directly or view it on GitHubhttps://github.com//issues/7683#issuecomment-46263517.

@JeffryBooher
Copy link
Contributor

@JeffryBooher
Copy link
Contributor

Needs Review. If this only occurs on shutdown after startup it doesn't feel like a case that we should hold up the release for. I suggest Medium. Added Tracking and removed Fix in Progress labels.

@redmunds redmunds removed this from the Release 0.41 milestone Jun 20, 2014
@redmunds
Copy link
Contributor

It's a little broader than that -- it can also happen if you shutdown after switching projects or selecting a file in a new folder (that JS Code Hints has not yet processed files for).

@RaymondLim
Copy link
Contributor Author

@peterflynn My comment above should answer your question #1 and I'll be closing the terminate tern worker pull request. For question #2, I think the answer is yes. I did replace PreferencesManager.finalize().always(postCloseHandler); with postCloseHandler(); and still not getting any crash. But I don't think we need to back out the changes in #7930 as it is the right thing to do even if it is not for the crash. We should always ensure all changes in the preferences are saved on quit.

@nethip
Copy link
Contributor

nethip commented Dec 2, 2014

@peterflynn @RaymondLim About the web worker crash, when we were looking at the crash on quit we got a callstack different than the one reported above. And that is why we were proposing two fixes. If the crash(or set of crashes) goes out with clearing callback_maps_, then there is no need for us to terminate the web worker explicitly.

We figured that not terminating the web worker and quitting crashes only with Brackets. Instead of loading Brackets index.html we loaded a web page which starts a webworker. Now without terminating this web worker if we quit Brackets, Brackets was crashing. However we could not repro the same with cefclient.

nethip added a commit to adobe/brackets-shell that referenced this issue Dec 2, 2014
This change involves some code changes got from code review comments
from (#487) pull request.
@RaymondLim
Copy link
Contributor Author

Removing cef and tracking labels since we're not waiting any fix from CEF.

@peterflynn
Copy link
Member

Setting to FBNC since the fix has been merged

@RaymondLim
Copy link
Contributor Author

This crash is driving me crazy. Now I can still reproduce it with jeff/cef-2171 branch and below is the call stack.

    kernel32.dll!_InterlockedDecrement@4()  + 0x9 bytes 
    libcef.dll!blink::Scheduler::MainThreadPendingTaskRunner::`scalar deleting destructor'()  + 0x18 bytes  C++
    libcef.dll!base::internal::BindState<base::internal::RunnableAdapter<void (__thiscall v8::Task::*)(void)>,void __cdecl(v8::Task *),void __cdecl(base::internal::OwnedWrapper<v8::Task>)>::`scalar deleting destructor'()  + 0x19 bytes  C++
    libcef.dll!scoped_refptr<net::WrappedIOBuffer>::~scoped_refptr<net::WrappedIOBuffer>()  Line 295 + 0x1f bytes   C++
    libcef.dll!base::PendingTask::~PendingTask()  Line 34 + 0x8 bytes   C++
>   libcef.dll!base::MessageLoop::DeletePendingTasks()  Line 474    C++
    libcef.dll!base::MessageLoop::~MessageLoop()  Line 177  C++
    libcef.dll!content::RendererMain(const content::MainFunctionParams & parameters)  Line 236 + 0x16 bytes C++
    libcef.dll!content::RunNamedProcessTypeMain(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & process_type, const content::MainFunctionParams & main_function_params, content::ContentMainDelegate * delegate)  Line 420 + 0xd bytes C++
    libcef.dll!content::ContentMainRunnerImpl::Run()  Line 769 + 0x6 bytes  C++
    libcef.dll!content::ContentMain(const content::ContentMainParams & params)  Line 19 + 0x7 bytes C++
    libcef.dll!CefExecuteProcess(const CefMainArgs & args, CefRefPtr<CefApp> application, void * windows_sandbox_info)  Line 94 + 0xc bytes C++
    libcef.dll!cef_execute_process(const _cef_main_args_t * args, _cef_app_t * application, void * windows_sandbox_info)  Line 133 + 0x11 bytes C++
    Brackets.exe!CefExecuteProcess(const CefMainArgs & args, CefRefPtr<CefApp> application, void * windows_sandbox_info)  Line 138  C++
    Brackets.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)  Line 129 + 0x28 bytes   C++
    Brackets.exe!__tmainCRTStartup()  Line 275 + 0x1c bytes C
    kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes    
    ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
    ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

@nethip Do you want to take a look and see you can figure out what's causing this? You may need to try several times to get one crash though. I got this call stack on the sixth try.

@peterflynn
Copy link
Member

@RaymondLim I guess one relatively "cheap" test we could try now would be similar to what we were looking at before:

  • Replace the Tern thread with an empty 'sample' thread -- does crash still happen?
  • Disable JS Code Hints completely -- does crash still happen?

@redmunds
Copy link
Contributor

redmunds commented Dec 6, 2014

@Raymond That's a different crash than this one.

@redmunds redmunds added the cef label Dec 6, 2014
@redmunds
Copy link
Contributor

redmunds commented Dec 6, 2014

I got 2 more crashes today with same call stack as @RaymondLim

@RaymondLim
Copy link
Contributor Author

@peterflynn Can't get any crash after disabling JS Code Hints. So @nethip claim of tern worker crash seems to be right. So I ran his simple worker thread and got the following call stack.

>   libcef.dll!content::NetworkListObserver::`vcall'{4}'()  C++
    libcef.dll!base::debug::TaskAnnotator::RunTask(const char * queue_function, const char * run_function, const base::PendingTask & pending_task)  Line 62 + 0x8 bytes C++
    libcef.dll!base::MessageLoop::RunTask(const base::PendingTask & pending_task)  Line 448 C++
    libcef.dll!base::MessageLoop::DoDelayedWork(base::TimeTicks * next_delayed_work_time)  Line 602 + 0xb bytes C++
    libcef.dll!base::MessagePumpDefault::Run(base::MessagePump::Delegate * delegate)  Line 36 + 0xa bytes   C++
    libcef.dll!base::MessageLoop::RunHandler()  Line 414 + 0x9 bytes    C++
    libcef.dll!base::RunLoop::Run()  Line 55    C++
    libcef.dll!base::MessageLoop::Run()  Line 308   C++
    libcef.dll!base::Thread::Run(base::MessageLoop * message_loop)  Line 175    C++
    libcef.dll!base::Thread::ThreadMain()  Line 232 C++
    libcef.dll!base::`anonymous namespace'::ThreadFunc(void * params)  Line 80  C++
    kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes    
    ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
    ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

@nethip I'll be restoring my pull request to terminate tern worker and see whether I still can reproduce the crash or not.

@nethip
Copy link
Contributor

nethip commented Dec 6, 2014

@peterflynn @redmunds @RaymondLim As @RaymondLim mentioned, we fixed this crash by terminating the tern worker. I am sure this will go off with tern worker shutdown. We could consistently reproduce this crash on my Win laptop.

@peterflynn Spawning any web worker is causing this crash on quit. Like what @RaymondLim did, We also spawned a sample web worker instead of tern-worker.js and even then Brackets was crashing on quit. In fact instead of loading index.html we loaded a sample HTML which spawns a web worker. Even for that case Brackets was crashing. I will see if I can get any more pointers from CEF side as we could very well have an extension which might spawn a web worker and not explicitly terminate the same on quit.. For now we can go with the tern-worker terminate solution.

@RaymondLim
Copy link
Contributor Author

I had restored pull request #10020 and tried to crash it on quit for a long while with no success. So I think we should go with it in order to update to the newer cef.

@nethip
Copy link
Contributor

nethip commented Dec 8, 2014

@RaymondLim This CL looks fine to me.

@nethip
Copy link
Contributor

nethip commented Dec 8, 2014

Merged #10020

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants