New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 687251 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Feb 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 2
Type: Bug



Sign in to add a comment

crash with ASAN and libjingle in WebRTC thread

Project Member Reported by etienneb@google.com, Jan 31 2017

Issue description

UserAgent: 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

 
Cc: r...@chromium.org chrisha@chromium.org
For 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



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.
Owner: deadbeef@chromium.org
Status: Assigned (was: Unconfirmed)
Status: Fixed (was: Assigned)
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.
No worries. If it's landed, I'm fine.
Let move forward.

Sign in to add a comment