crash with ASAN and libjingle in WebRTC thread |
||||
Issue descriptionUserAgent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 Steps to reproduce the problem: Compile chromium with ASAN activated. The unittest libjingle_xmpp_unittests.exe is failing What is the expected behavior? What went wrong? stack corrupt Did this work before? N/A Does this work in other browsers? N/A Chrome version: 55.0.2883.87 Channel: n/a OS Version: 6.1 (Windows 7, Windows Server 2008 R2) Flash Version: Shockwave Flash 24.0 r0
,
Jan 31 2017
FYI: https://msdn.microsoft.com/en-us/library/aa964928(v=vs.110).aspx typedef DWORD (__stdcall *LPTHREAD_START_ROUTINE) ( [in] LPVOID lpThreadParameter ); The correct calling convention on windows is __stdcall.
,
Jan 31 2017
,
Feb 1 2017
,
Feb 1 2017
,
Feb 1 2017
Sorry for lack of communication; I fixed this here: https://codereview.webrtc.org/2668693005/ I'm not sure why the bugbot didn't automatically post a comment.
,
Feb 1 2017
No worries. If it's landed, I'm fine. Let move forward. |
||||
►
Sign in to add a comment |
||||
Comment 1 by etienneb@chromium.org
, Jan 31 2017For an ASAN instrumented chromium build, there is a unittest failing: D:\src\chromium\src>out\ninja\libjingle_xmpp_unittests.exe --gtest_filter=XmlElementTest.TestMultithread Note: Google Test filter = XmlElementTest.TestMultithread [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from XmlElementTest [ RUN ] XmlElementTest.TestMultithread ================================================================= AddressSanitizer: nested bug in the same thread, aborting. The stack got corrupt within the asan_thread.cc file (a thread wrapper) when calling the start routine. ASAN needs to insert itself before the thread start routine. [asan_thread.cc] thread_return_t res = start_routine_(arg_); 014A7444 FF 77 08 push dword ptr [edi+8] 014A7447 FF D0 call eax The WebRTC framework is also adding a wrapper around the thread. The PreRun function is the one called by the previous code. But, the calling convention is incorrect. void* Thread::PreRun(void* pv) { 0143F896 55 push ebp 0143F897 89 E5 mov ebp,esp 0143F899 53 push ebx 0143F89A 57 push edi 0143F89B 56 push esi [...] return NULL; 0143F9BE 31 C0 xor eax,eax 0143F9C0 5E pop esi 0143F9C1 5F pop edi 0143F9C2 5B pop ebx 0143F9C3 5D pop ebp 0143F9C4 C3 ret The compiler warnings was hidden behind a incorrect cast. #if defined(WEBRTC_WIN) thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PreRun, init, 0, &thread_id_); if (thread_) { running_.Set(); } else { return false; } This following patch is fixing the problem: index b7d4486..3afb5f1 100644 --- a/base/thread.cc +++ b/base/thread.cc @@ -308,7 +308,7 @@ void Thread::AssertBlockingIsAllowedOnCurrentThread() { #endif } -void* Thread::PreRun(void* pv) { +void* THREAD_CALLING_CONV Thread::PreRun(void* pv) { ThreadInit* init = static_cast<ThreadInit*>(pv); ThreadManager::Instance()->SetCurrentThread(init->thread); rtc::SetCurrentThreadName(init->thread->name_.c_str()); diff --git a/base/thread.h b/base/thread.h index 97e6941..be400f9 100644 --- a/base/thread.h +++ b/base/thread.h @@ -28,6 +28,12 @@ #include "webrtc/base/win32.h" #endif +#if defined(WEBRTC_WIN) +# define THREAD_CALLING_CONV __stdcall +#else // WEBRTC_WIN +# define THREAD_CALLING_CONV +#endif // WEBRTC_WIN + namespace rtc { class Thread; @@ -238,7 +244,7 @@ class LOCKABLE Thread : public MessageQueue { friend class ScopedDisallowBlockingCalls; private: - static void *PreRun(void *pv); + static void* THREAD_CALLING_CONV PreRun(void *pv); // ThreadManager calls this instead WrapCurrent() because // ThreadManager::Instance() cannot be used while ThreadManager is