We were accessing the ModuleList in the target without locking it for tasks like
setting breakpoints.  That's dangerous, since while we are setting a breakpoint,
the target might hit the dyld load notification, and start removing modules from
the list.  This change adds a GetMutex accessor to the ModuleList class, and
uses it whenever we are accessing the target's ModuleList (as returned by GetImages().)

<rdar://problem/11552372>


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@157668 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index a38f143..c5987ee 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -1882,6 +1882,7 @@
             if (command.GetArgumentCount() == 0)
             {
                 // Dump all sections for all modules images
+                Mutex::Locker modules_locker(target->GetImages().GetMutex());
                 const uint32_t num_modules = target->GetImages().GetSize();
                 if (num_modules > 0)
                 {
@@ -1894,7 +1895,10 @@
                             result.GetOutputStream().EOL();
                         }
                         num_dumped++;
-                        DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
+                        DumpModuleSymtab (m_interpreter,
+                                          result.GetOutputStream(),
+                                          target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
+                                          m_options.m_sort_order);
                     }
                 }
                 else
@@ -2179,13 +2183,15 @@
             if (command.GetArgumentCount() == 0)
             {
                 // Dump all sections for all modules images
-                const uint32_t num_modules = target->GetImages().GetSize();
+                ModuleList &target_modules = target->GetImages();
+                Mutex::Locker modules_locker (target_modules.GetMutex());
+                const uint32_t num_modules = target_modules.GetSize();
                 if (num_modules > 0)
                 {
                     result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
                     {
-                        if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
+                        if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
                             num_dumped++;
                     }
                 }
@@ -2288,7 +2294,10 @@
                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
                 {
                     FileSpec file_spec(arg_cstr, false);
-                    const uint32_t num_modules = target->GetImages().GetSize();
+                    
+                    ModuleList &target_modules = target->GetImages();
+                    Mutex::Locker modules_locker(target_modules.GetMutex());
+                    const uint32_t num_modules = target_modules.GetSize();
                     if (num_modules > 0)
                     {
                         uint32_t num_dumped = 0;
@@ -2296,7 +2305,7 @@
                         {
                             if (DumpCompileUnitLineTable (m_interpreter,
                                                           result.GetOutputStream(),
-                                                          target->GetImages().GetModulePointerAtIndex(i),
+                                                          target_modules.GetModulePointerAtIndexUnlocked(i),
                                                           file_spec,
                                                           exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive()))
                                 num_dumped++;
@@ -2807,9 +2816,6 @@
                 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
             }
             // Dump all sections for all modules images
-            uint32_t num_modules = 0;
-            Mutex::Locker locker;
-            
             Stream &strm = result.GetOutputStream();
             
             if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
@@ -2845,6 +2851,11 @@
                 return result.Succeeded();
             }
             
+            uint32_t num_modules = 0;
+            Mutex::Locker locker;      // This locker will be locked on the mutex in module_list_ptr if it is non-NULL.
+                                       // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
+                                       // the global module list directly.
+            
             ModuleList module_list;
             ModuleList *module_list_ptr = NULL;
             const size_t argc = command.GetArgumentCount();
@@ -2858,7 +2869,6 @@
                 else
                 {
                     module_list_ptr = &target->GetImages();
-                    num_modules = target->GetImages().GetSize();
                 }
             }
             else
@@ -2879,9 +2889,14 @@
                     }
                 }
                 
-                num_modules = module_list.GetSize();
                 module_list_ptr = &module_list;
             }
+            
+            if (module_list_ptr != NULL)
+            {
+                locker.Lock(module_list_ptr->GetMutex());
+                num_modules = module_list_ptr->GetSize();
+            }
 
             if (num_modules > 0)
             {                
@@ -2891,7 +2906,7 @@
                     Module *module;
                     if (module_list_ptr)
                     {
-                        module_sp = module_list_ptr->GetModuleAtIndex(image_idx);
+                        module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
                         module = module_sp.get();
                     }
                     else
@@ -3414,12 +3429,14 @@
             if (command.GetArgumentCount() == 0)
             {
                 // Dump all sections for all modules images
-                const uint32_t num_modules = target->GetImages().GetSize();
+                ModuleList &target_modules = target->GetImages();
+                Mutex::Locker modules_locker(target_modules.GetMutex());
+                const uint32_t num_modules = target_modules.GetSize();
                 if (num_modules > 0)
                 {
                     for (i = 0; i<num_modules && syntax_error == false; ++i)
                     {
-                        if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
+                        if (LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
                         {
                             result.GetOutputStream().EOL();
                             num_successful_lookups++;