Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heap corruption/Access Violation with unreachable replication endpoint on Windows x86 #1051

Closed
borrrden opened this issue Aug 9, 2018 · 4 comments
Assignees
Milestone

Comments

@borrrden
Copy link
Member

borrrden commented Aug 9, 2018

From @borrrden on August 7, 2018 1:55

Noticed while using the mobile training todo app. If the URL is not a valid sync gateway, then a heap corruption will occur in the BLIPConnection _closed method regarding reference counting (free after free?). This does not seem to occur on x64, but happens on x86 for both desktop and UWP. Stack trace in the next comment.

Copied from original issue: couchbase/couchbase-lite-core#547

@borrrden
Copy link
Member Author

borrrden commented Aug 9, 2018

Exception thrown at 0x7786F762 (ntdll.dll) in Training.UWP.exe: 0xC0000005: Access violation reading location 0x1EC00008.

[Inline Frame] LiteCore.dll!litecore::RefCounted::_release() Line 48	C++
[Inline Frame] LiteCore.dll!litecore::release(litecore::RefCounted *) Line 65	C++
[Inline Frame] LiteCore.dll!litecore::Retained<litecore::websocket::WebSocket>::operator=(litecore::websocket::WebSocket *) Line 86	C++
 LiteCore.dll!litecore::blip::BLIPIO::_closed(litecore::websocket::CloseStatus status) Line 216	C++
[Inline Frame] LiteCore.dll!std::_Invoker_pmf_pointer::_Call(void(litecore::websocket::LoopbackWebSocket::Driver::*)(litecore::websocket::CloseStatus) _Pmf, litecore::websocket::LoopbackWebSocket::Driver * &) Line 1340	C++
[Inline Frame] LiteCore.dll!std::invoke(void(litecore::websocket::LoopbackWebSocket::Driver::*)(litecore::websocket::CloseStatus) &) Line 1443	C++
[Inline Frame] LiteCore.dll!std::_Invoke_ret(std::_Forced<std::_Unforced,0>) Line 1475	C++
[Inline Frame] LiteCore.dll!std::_Call_binder(std::_Forced<std::_Unforced,0>) Line 825	C++
[Inline Frame] LiteCore.dll!std::_Binder<std::_Unforced,void (__thiscall litecore::websocket::LoopbackWebSocket::Driver::*&)(litecore::websocket::CloseStatus),litecore::websocket::LoopbackWebSocket::Driver *,litecore::websocket::CloseStatus &>::operator()() Line 881	C++
[Inline Frame] LiteCore.dll!std::_Invoker_functor::_Call(std::_Binder<std::_Unforced,void (__thiscall litecore::websocket::LoopbackWebSocket::Driver::*&)(litecore::websocket::CloseStatus),litecore::websocket::LoopbackWebSocket::Driver *,litecore::websocket::CloseStatus &> &) Line 1375	C++
[Inline Frame] LiteCore.dll!std::invoke(std::_Binder<std::_Unforced,void (__thiscall litecore::websocket::LoopbackWebSocket::Driver::*&)(litecore::websocket::CloseStatus),litecore::websocket::LoopbackWebSocket::Driver *,litecore::websocket::CloseStatus &> &) Line 1443	C++
[Inline Frame] LiteCore.dll!std::_Invoke_ret(std::_Forced<void,1>) Line 1461	C++
LiteCore.dll!std::_Func_impl<std::_Binder<std::_Unforced,void (__thiscall litecore::websocket::LoopbackWebSocket::Driver::*&)(litecore::websocket::CloseStatus),litecore::websocket::LoopbackWebSocket::Driver *,litecore::websocket::CloseStatus &>,std::allocator<int>,void>::_Do_call() Line 214	C++
[Inline Frame] LiteCore.dll!std::_Func_class<void>::operator()() Line 279	C++
LiteCore.dll!litecore::actor::ThreadedMailbox::performNextMessage() Line 193	C++
void _closed(websocket::CloseStatus status) {
     _onWebSocketMessages(); // process any pending incoming frames

     >> _webSocket = nullptr; <<
     if (_connection) {
         Retained<BLIPIO> holdOn (this);
         if (_closingWithError) {
             status.reason = kException;
             status.code = _closingWithError->code;
             status.message = alloc_slice(_closingWithError->what());
         }
         _connection->closed(status);
         _connection = nullptr;
         cancelAll(_outbox);
         cancelAll(_icebox);
         cancelAll(_pendingRequests);
         cancelAll(_pendingResponses);
         _requestHandlers.clear();
         release(this); // webSocket is done calling delegate now (balances retain in ctor)
     }
 }

The marked line is where the crash is. _webSocket is already invalid at this point it seems (ref count is a garbageish 117506060) Disregard this part.

@borrrden
Copy link
Member Author

borrrden commented Aug 9, 2018

This irritatingly also only happens in Release mode, not Debug mode...at least for UWP.

@borrrden
Copy link
Member Author

borrrden commented Aug 9, 2018

The flow goes like this:

  • c4repl_new triggers a socket open callback
  • Socket attempts to establish connection but times out because no valid sync gateway is running
  • c4socket_closed is called

The last part triggers a cleanup of various things including the C4SocketImpl, which is the one somehow causing problems. The odd part is that I can step through the entire destructor and it is not until the very end when it attempts to free the heap memory that it fails.

@borrrden borrrden added the bug label Aug 9, 2018
@borrrden borrrden added this to the 2.1.0 milestone Aug 9, 2018
@borrrden
Copy link
Member Author

borrrden commented Aug 9, 2018

Turns out it was a case of missing UnmanagedFunctionPointer attribute on one of the marshalled callbacks to C.

borrrden added a commit that referenced this issue Aug 9, 2018
@borrrden borrrden closed this as completed Aug 9, 2018
@pasin pasin removed the ready label Aug 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants