Fixed a crasher that has been borking out heap for a long time.
authorGreg Clayton <gclayton@apple.com>
Thu, 8 Dec 2016 20:38:19 +0000 (20:38 +0000)
committerGreg Clayton <gclayton@apple.com>
Thu, 8 Dec 2016 20:38:19 +0000 (20:38 +0000)
ThreadList had an assignment operator that didn't lock the "rhs" thread list object. This means a thread list can be mutated while it is being copied.

The copy constructor calls the assignment operator as well. So this fixes the unsafe threaded access to ThreadList which we believe is responsible for a lot of crashes.

<rdar://problem/28075793>

llvm-svn: 289100

lldb/include/lldb/Target/ThreadCollection.h
lldb/include/lldb/Target/ThreadList.h
lldb/source/Target/ThreadList.cpp

index 5b0267d..e3965b5 100644 (file)
@@ -48,11 +48,11 @@ public:
     return ThreadIterable(m_threads, GetMutex());
   }
 
-  virtual std::recursive_mutex &GetMutex() { return m_mutex; }
+  virtual std::recursive_mutex &GetMutex() const { return m_mutex; }
 
 protected:
   collection m_threads;
-  std::recursive_mutex m_mutex;
+  mutable std::recursive_mutex m_mutex;
 };
 
 } // namespace lldb_private
index d0779d8..9e3c940 100644 (file)
@@ -135,7 +135,7 @@ public:
 
   void SetStopID(uint32_t stop_id);
 
-  std::recursive_mutex &GetMutex() override;
+  std::recursive_mutex &GetMutex() const override;
 
   void Update(ThreadList &rhs);
 
index 15388a5..1e47451 100644 (file)
@@ -44,6 +44,7 @@ const ThreadList &ThreadList::operator=(const ThreadList &rhs) {
     // Lock both mutexes to make sure neither side changes anyone on us
     // while the assignment occurs
     std::lock_guard<std::recursive_mutex> guard(GetMutex());
+    std::lock_guard<std::recursive_mutex> rhs_guard(rhs.GetMutex());
 
     m_process = rhs.m_process;
     m_stop_id = rhs.m_stop_id;
@@ -749,7 +750,7 @@ void ThreadList::Flush() {
     (*pos)->Flush();
 }
 
-std::recursive_mutex &ThreadList::GetMutex() {
+std::recursive_mutex &ThreadList::GetMutex() const {
   return m_process->m_thread_mutex;
 }