Add a function to make a mutex-protected copy of a breakpoint site's
authorJim Ingham <jingham@apple.com>
Wed, 29 Jul 2015 17:51:36 +0000 (17:51 +0000)
committerJim Ingham <jingham@apple.com>
Wed, 29 Jul 2015 17:51:36 +0000 (17:51 +0000)
owners list, so the StopInfo machinery can get the list of owners without
some other thread being able to mess up the list by deleting/disabline one of its
locations in the process of doing so.

<rdar://problem/18685197>

llvm-svn: 243541

lldb/include/lldb/Breakpoint/BreakpointSite.h
lldb/source/Breakpoint/BreakpointSite.cpp
lldb/source/Target/StopInfo.cpp

index d67fc8b..59bc54d 100644 (file)
@@ -187,6 +187,20 @@ public:
     GetOwnerAtIndex (size_t idx);
     
     //------------------------------------------------------------------
+    /// This method copies the breakpoint site's owners into a new collection.
+    /// It does this while the owners mutex is locked.
+    ///
+    /// @param[out] out_collection
+    ///    The BreakpointLocationCollection into which to put the owners
+    ///    of this breakpoint site.
+    ///
+    /// @return
+    ///    The number of elements copied into out_collection.
+    //------------------------------------------------------------------
+    size_t
+    CopyOwnersList (BreakpointLocationCollection &out_collection);
+    
+    //------------------------------------------------------------------
     /// Check whether the owners of this breakpoint site have any
     /// thread specifiers, and if yes, is \a thread contained in any
     /// of these specifiers.
index 95b67b0..27e56d3 100644 (file)
@@ -254,3 +254,14 @@ BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size, lldb::addr_t *in
     }
     return false;
 }
+
+size_t
+BreakpointSite::CopyOwnersList (BreakpointLocationCollection &out_collection)
+{
+    Mutex::Locker locker(m_owners_mutex);
+    for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations())
+    {
+        out_collection.Add(loc_sp);
+    }
+    return out_collection.GetSize();
+}
index 4f6ef7a..64bbe80 100644 (file)
@@ -350,7 +350,10 @@ protected:
 
             if (bp_site_sp)
             {
-                size_t num_owners = bp_site_sp->GetNumberOfOwners();
+                // Let's copy the owners list out of the site and store them in a local list.  That way if
+                // one of the breakpoint actions changes the site, then we won't be operating on a bad list.
+                BreakpointLocationCollection site_locations;
+                size_t num_owners = bp_site_sp->CopyOwnersList(site_locations);
 
                 if (num_owners == 0)
                 {
@@ -416,20 +419,16 @@ protected:
 
                     StoppointCallbackContext context (event_ptr, exe_ctx, false);
 
-                    // Let's copy the breakpoint locations out of the site and store them in a local list.  That way if
-                    // one of the breakpoint actions changes the site, then we won't be operating on a bad list.
                     // For safety's sake let's also grab an extra reference to the breakpoint owners of the locations we're
                     // going to examine, since the locations are going to have to get back to their breakpoints, and the
                     // locations don't keep their owners alive.  I'm just sticking the BreakpointSP's in a vector since
-                    // I'm only really using it to locally increment their retain counts.
+                    // I'm only using it to locally increment their retain counts.
 
-                    BreakpointLocationCollection site_locations;
                     std::vector<lldb::BreakpointSP> location_owners;
 
                     for (size_t j = 0; j < num_owners; j++)
                     {
-                        BreakpointLocationSP loc(bp_site_sp->GetOwnerAtIndex(j));
-                        site_locations.Add(loc);
+                        BreakpointLocationSP loc(site_locations.GetByIndex(j));
                         location_owners.push_back(loc->GetBreakpoint().shared_from_this());
 
                     }