[Lldb-commits] [lldb] r133448 - in /lldb/trunk: include/lldb/Target/DynamicLoader.h lldb.xcodeproj/project.pbxproj source/Expression/ClangUserExpression.cpp source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h source/Plugins/Process/Utility/InferiorCallPOSIX.cpp source/Target/Process.cpp test/types/AbstractBase.py test/types/basic_type.cpp

Jim Ingham jingham at apple.com
Mon Jun 20 10:32:44 PDT 2011


Author: jingham
Date: Mon Jun 20 12:32:44 2011
New Revision: 133448

URL: http://llvm.org/viewvc/llvm-project?rev=133448&view=rev
Log:
Use the dyld_mode, image_infos & image_infos_count passed into the shared library notification function
to update libraries rather than reading the whole all_imaage_infos structure every time we get notified.

Modified:
    lldb/trunk/include/lldb/Target/DynamicLoader.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
    lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/test/types/AbstractBase.py
    lldb/trunk/test/types/basic_type.cpp

Modified: lldb/trunk/include/lldb/Target/DynamicLoader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/DynamicLoader.h?rev=133448&r1=133447&r2=133448&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/DynamicLoader.h (original)
+++ lldb/trunk/include/lldb/Target/DynamicLoader.h Mon Jun 20 12:32:44 2011
@@ -91,6 +91,8 @@
     //------------------------------------------------------------------
     virtual void
     DidLaunch () = 0;
+    
+    
 
     //------------------------------------------------------------------
     /// Get whether the process should stop when images change.

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=133448&r1=133447&r2=133448&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Jun 20 12:32:44 2011
@@ -3292,7 +3292,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_PREPROCESSOR_DEFINITIONS = (
@@ -3324,7 +3324,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					__STDC_CONSTANT_MACROS,
@@ -3616,7 +3616,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					__STDC_CONSTANT_MACROS,

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=133448&r1=133447&r2=133448&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Mon Jun 20 12:32:44 2011
@@ -597,9 +597,9 @@
     Error error;
     ExecutionResults execution_results = eExecutionSetupError;
     
-    if (exe_ctx.process == NULL)
+    if (exe_ctx.process == NULL || exe_ctx.process->GetState() != lldb::eStateStopped)
     {
-        error.SetErrorString ("Must have a process to evaluate expressions.");
+        error.SetErrorString ("Must have a live but stopped process to evaluate expressions.");
             
         result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
         return eExecutionSetupError;

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=133448&r1=133447&r2=133448&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Mon Jun 20 12:32:44 2011
@@ -288,7 +288,7 @@
             }
 
             // Update all image infos
-            UpdateAllImageInfos();
+            InitializeFromAllImageInfos ();
 
             // If we didn't have an executable before, but now we do, then the
             // dyld module shared pointer might be unique and we may need to add
@@ -442,11 +442,79 @@
 // or not (based on global preference).
 //----------------------------------------------------------------------
 bool
-DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
+DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton, 
+                                              StoppointCallbackContext *context, 
+                                              lldb::user_id_t break_id, 
+                                              lldb::user_id_t break_loc_id)
 {
     // Let the event know that the images have changed
+    // DYLD passes three arguments to the notification breakpoint.
+    // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing 
+    // Arg2: uint32_t infoCount        - Number of shared libraries added  
+    // Arg3: dyld_image_info info[]    - Array of structs of the form:
+    //                                     const struct mach_header *imageLoadAddress
+    //                                     const char               *imageFilePath
+    //                                     uintptr_t                 imageFileModDate (a time_t)
+    
     DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton;
-    dyld_instance->UpdateAllImageInfos();
+    
+    // First step is to see if we've already initialized the all image infos.  If we haven't then this function
+    // will do so and return true.  In the course of initializing the all_image_infos it will read the complete
+    // current state, so we don't need to figure out what has changed from the data passed in to us.
+    
+    if (dyld_instance->InitializeFromAllImageInfos())
+        return dyld_instance->GetStopWhenImagesChange(); 
+
+    Process *process = context->exe_ctx.process;
+    const lldb::ABISP &abi = process->GetABI();
+    if (abi != NULL)
+    {
+        // Build up the value array to store the three arguments given above, then get the values from the ABI:
+        
+        ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
+        ValueList argument_values;
+        Value input_value;
+        
+        void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+        void *clang_uint32_type   = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
+        input_value.SetValueType (Value::eValueTypeScalar);
+        input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type);
+        argument_values.PushValue(input_value);
+        argument_values.PushValue(input_value);
+        input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+        argument_values.PushValue (input_value);
+        
+        if (abi->GetArgumentValues (*context->exe_ctx.thread, argument_values))
+        {
+            uint32_t dyld_mode = argument_values.GetValueAtIndex(0)->GetScalar().UInt (-1);
+            if (dyld_mode != -1)
+            {
+                // Okay the mode was right, now get the number of elements, and the array of new elements...
+                uint32_t image_infos_count = argument_values.GetValueAtIndex(1)->GetScalar().UInt (-1);
+                if (image_infos_count != -1)
+                {
+                    // Got the number added, now go through the array of added elements, putting out the mach header 
+                    // address, and adding the image.
+                    // Note, I'm not putting in logging here, since the AddModules & RemoveModules functions do
+                    // all the logging internally.
+                    
+                    lldb::addr_t image_infos_addr = argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
+                    if (dyld_mode == 0)
+                    {
+                        // This is add:
+                        dyld_instance->AddModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
+                    }
+                    else
+                    {
+                        // This is remove:
+                        dyld_instance->RemoveModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
+                    }
+                    
+                }
+            }
+        }
+    }
+    
     // Return true to stop the target, false to just let the target run
     return dyld_instance->GetStopWhenImagesChange();
 }
@@ -571,229 +639,297 @@
     return false;
 }
 
-//----------------------------------------------------------------------
-// If we have found where the "_dyld_all_image_infos" lives in memory,
-// read the current info from it, and then update all image load
-// addresses (or lack thereof).
-//----------------------------------------------------------------------
-uint32_t
-DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
+
+bool
+DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
 {
+    DYLDImageInfo::collection image_infos;
     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-    ModuleList& target_images = m_process->GetTarget().GetImages();
+    if (log)
+        log->Printf ("Adding %d modules.\n");
+        
+    Mutex::Locker locker(m_mutex);
+    if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
+        return true;
 
-    if (ReadAllImageInfosStructure ())
+    if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
+        return false;
+        
+    UpdateImageInfosHeaderAndLoadCommands (image_infos, image_infos_count, false);
+    bool return_value = AddModulesUsingImageInfos (image_infos);
+    m_dyld_image_infos_stop_id = m_process->GetStopID();
+    return return_value;
+}
+
+// Adds the modules in image_infos to m_dyld_image_infos.  
+// NB don't call this passing in m_dyld_image_infos.
+
+bool
+DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos)
+{
+    // Now add these images to the main list.
+    ModuleList loaded_module_list;
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    
+    for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
     {
-        Mutex::Locker locker(m_mutex);
-        if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
-            m_dyld_image_infos.size();
-
-        uint32_t idx;
-        uint32_t i = 0;
-        // Since we can't downsize a vector, we must do this using the swap method
-        DYLDImageInfo::collection old_dyld_all_image_infos;
-        old_dyld_all_image_infos.swap(m_dyld_image_infos);
-
-        // If we made it here, we are assuming that the all dylib info data should
-        // be valid, lets read the info array.
-        const ByteOrder endian = m_dyld.GetByteOrder();
-        const uint32_t addr_size = m_dyld.GetAddressByteSize();
+        if (log)
+        {
+            log->Printf ("Adding new image at address=0x%16.16llx.", image_infos[idx].address);
+            image_infos[idx].PutToLog (log.get());
+        }
+        
+        m_dyld_image_infos.push_back(image_infos[idx]);
+        
+        ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], true, NULL));
 
-        if (m_dyld_all_image_infos.dylib_info_count > 0)
+        if (image_module_sp)
         {
-            if (m_dyld_all_image_infos.dylib_info_addr == 0)
-            {
-                // DYLD is updating the images right now...
-            }
-            else
+            if (image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
+                image_module_sp->SetIsDynamicLinkEditor (true);
+
+            ObjectFile *objfile = image_module_sp->GetObjectFile ();
+            if (objfile)
             {
-                m_dyld_image_infos.resize(m_dyld_all_image_infos.dylib_info_count);
-                const size_t count = m_dyld_image_infos.size() * 3 * addr_size;
-                DataBufferHeap info_data(count, 0);
-                Error error;
-                const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos.dylib_info_addr, 
-                                                                 info_data.GetBytes(), 
-                                                                 info_data.GetByteSize(),
-                                                                 error);
-                if (bytes_read == count)
+                SectionList *sections = objfile->GetSectionList();
+                if (sections)
                 {
-                    uint32_t info_data_offset = 0;
-                    DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
-                    for (i = 0; i < m_dyld_image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
+                    ConstString commpage_dbstr("__commpage");
+                    Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
+                    if (commpage_section)
                     {
-                        m_dyld_image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
-                        lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
-                        m_dyld_image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
-
-                        char raw_path[PATH_MAX];
-                        m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path));
-                        // don't resolve the path
-                        const bool resolve_path = false;
-                        m_dyld_image_infos[i].file_spec.SetFile(raw_path, resolve_path);
+                        ModuleList& target_images = m_process->GetTarget().GetImages();
+                        const FileSpec objfile_file_spec = objfile->GetFileSpec();
+                        ArchSpec arch (image_infos[idx].GetArchitecture ());
+                        ModuleSP commpage_image_module_sp(target_images.FindFirstModuleForFileSpec (objfile_file_spec, 
+                                                                                                    &arch, 
+                                                                                                    &commpage_dbstr));
+                        if (!commpage_image_module_sp)
+                        {
+                            commpage_image_module_sp 
+                                    = m_process->GetTarget().GetSharedModule (image_infos[idx].file_spec,
+                                                                              arch,
+                                                                              NULL,
+                                                                              &commpage_dbstr,
+                                                                              objfile->GetOffset() + commpage_section->GetFileOffset());
+                        }
+                        if (commpage_image_module_sp)
+                            UpdateCommPageLoadAddress (commpage_image_module_sp.get());
                     }
-
-                    UpdateAllImageInfosHeaderAndLoadCommands();
-                }
-                else
-                {
-                    DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
-                    m_dyld_image_infos.clear();
                 }
             }
-        }
 
-        // If our new list is smaller than our old list, we have unloaded
-        // some shared libraries
-        if (m_dyld_image_infos.size() != old_dyld_all_image_infos.size())
+            // UpdateImageLoadAddress will return true if any segments
+            // change load address. We need to check this so we don't
+            // mention that all loaded shared libraries are newly loaded
+            // each time we hit out dyld breakpoint since dyld will list all
+            // shared libraries each time.
+            if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
+            {
+                loaded_module_list.AppendIfNeeded (image_module_sp);
+            }
+        }
+    }
+    
+    if (loaded_module_list.GetSize() > 0)
+    {
+        // FIXME: This should really be in the Runtime handlers class, which should get
+        // called by the target's ModulesDidLoad, but we're doing it all locally for now 
+        // to save time.
+        // Also, I'm assuming there can be only one libobjc dylib loaded...
+        
+        ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
+        if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
         {
-            ModuleList unloaded_module_list;
-            if (old_dyld_all_image_infos.size() == 0)
+            size_t num_modules = loaded_module_list.GetSize();
+            for (int i = 0; i < num_modules; i++)
             {
-                // This is the first time we are loading shared libraries,
-                // we need to make sure to trim anything that isn't in the
-                // m_dyld_image_infos out of the target module list since
-                // we might have shared libraries that got loaded from
-                // elsewhere due to DYLD_FRAMEWORK_PATH, or DYLD_LIBRARY_PATH
-                // environment variables...
-                const size_t num_images = target_images.GetSize();
-                for (idx = 0; idx < num_images; ++idx)
+                if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
                 {
-                    ModuleSP module_sp (target_images.GetModuleAtIndex (idx));
-                    
-                    if (GetImageInfo (module_sp.get()) == NULL)
-                        unloaded_module_list.AppendIfNeeded (module_sp);
+                    objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
+                    break;
                 }
             }
-            else
+        }
+        if (log)
+            loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
+        m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+    }
+    return true;
+}
+
+bool
+DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
+{
+    DYLDImageInfo::collection image_infos;
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    
+    Mutex::Locker locker(m_mutex);
+    if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
+        return true;
+
+    // First read in the image_infos for the removed modules, and their headers & load commands.
+    if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
+    {
+        if (log)
+            log->PutCString ("Failed reading image infos array.");
+        return false;
+    }
+    
+    if (log)
+        log->Printf ("Removing %d modules.", image_infos_count);
+    
+    ModuleList unloaded_module_list;
+    for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
+    {        
+        if (log)
+        {
+            log->Printf ("Removing module at address=0x%16.16llx.", image_infos[idx].address);
+            image_infos[idx].PutToLog (log.get());
+        }
+            
+        // Remove this image_infos from the m_all_image_infos.  We do the comparision by address
+        // rather than by file spec because we can have many modules with the same "file spec" in the
+        // case that they are modules loaded from memory.
+        //
+        // Also copy over the uuid from the old entry to the removed entry so we can 
+        // use it to lookup the module in the module list.
+        
+        DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
+        for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
+        {
+            if (image_infos[idx].address == (*pos).address)
             {
-                uint32_t old_idx;
-                for (idx = 0; idx < old_dyld_all_image_infos.size(); ++idx)
+                image_infos[idx].uuid = (*pos).uuid;
+
+                // Add the module from this image_info to the "unloaded_module_list".  We'll remove them all at
+                // one go later on.
+                
+                ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], false, NULL));
+                if (unload_image_module_sp.get())
                 {
-                    for (old_idx = idx; old_idx < old_dyld_all_image_infos.size(); ++old_idx)
-                    {
-                        if (m_dyld_image_infos[idx].file_spec == old_dyld_all_image_infos[old_idx].file_spec)
-                        {
-                            old_dyld_all_image_infos[old_idx].address = LLDB_INVALID_ADDRESS;
-                            break;
-                        }
-                    }
+                    UnloadImageLoadAddress (unload_image_module_sp.get(), image_infos[idx]);
+                    unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
                 }
-
-                for (old_idx = 0; old_idx < old_dyld_all_image_infos.size(); ++old_idx)
+                else
                 {
-                    if (old_dyld_all_image_infos[old_idx].address != LLDB_INVALID_ADDRESS)
+                    if (log)
                     {
-                        if (log)
-                            old_dyld_all_image_infos[old_idx].PutToLog (log.get());
-                        ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (old_dyld_all_image_infos[old_idx], false, NULL));
-                        if (unload_image_module_sp.get())
-                        {
-                            if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[old_idx]))
-                                unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
-                        }
+                        log->Printf ("Could not find module for unloading info entry:");
+                        image_infos[idx].PutToLog(log.get());
                     }
                 }
+                
+                // Then remove it from the m_dyld_image_infos:
+                
+                m_dyld_image_infos.erase(pos);
+                break;
             }
-
-            if (unloaded_module_list.GetSize() > 0)
+        }
+        
+        if (pos == end)
+        {
+            if (log)
             {
-                if (log)
-                {
-                    log->PutCString("Unloaded:");
-                    unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
-                }
-                m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
+                log->Printf ("Could not find image_info entry for unloading image:");
+                image_infos[idx].PutToLog(log.get());            
             }
         }
-        else
+    }
+    if (unloaded_module_list.GetSize() > 0)
+    {
+        if (log)
         {
-            if (log)
-                PutToLog(log.get());
+            log->PutCString("Unloaded:");
+            unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
+        }
+        m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
+    }
+    m_dyld_image_infos_stop_id = m_process->GetStopID();
+    return true;
+}
+
+bool
+DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr, 
+                                         uint32_t image_infos_count, 
+                                         DYLDImageInfo::collection &image_infos)
+{
+    const ByteOrder endian = m_dyld.GetByteOrder();
+    const uint32_t addr_size = m_dyld.GetAddressByteSize();
+
+    image_infos.resize(image_infos_count);
+    const size_t count = image_infos.size() * 3 * addr_size;
+    DataBufferHeap info_data(count, 0);
+    Error error;
+    const size_t bytes_read = m_process->ReadMemory (image_infos_addr, 
+                                                     info_data.GetBytes(), 
+                                                     info_data.GetByteSize(),
+                                                     error);
+    if (bytes_read == count)
+    {
+        uint32_t info_data_offset = 0;
+        DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
+        for (int i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
+        {
+            image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
+            lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
+            image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
+
+            char raw_path[PATH_MAX];
+            m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path));
+            // don't resolve the path
+            const bool resolve_path = false;
+            image_infos[i].file_spec.SetFile(raw_path, resolve_path);
         }
-        m_dyld_image_infos_stop_id = m_process->GetStopID();
+        return true;
     }
     else
     {
-        m_dyld_image_infos.clear();
+        return false;
     }
+}
 
-    const uint32_t num_dylibs = m_dyld_image_infos.size();
-    if (num_dylibs > 0)
+//----------------------------------------------------------------------
+// If we have found where the "_dyld_all_image_infos" lives in memory,
+// read the current info from it, and then update all image load
+// addresses (or lack thereof).  Only do this if this is the first time
+// we're reading the dyld infos.  Return true if we actually read anything,
+// and false otherwise.
+//----------------------------------------------------------------------
+bool
+DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
+{
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    
+    Mutex::Locker locker(m_mutex);
+    if (m_process->GetStopID() == m_dyld_image_infos_stop_id
+          || m_dyld_image_infos.size() != 0)
+        return false;
+
+    if (ReadAllImageInfosStructure ())
     {
-        ModuleList loaded_module_list;
-        for (uint32_t idx = 0; idx<num_dylibs; ++idx)
+        if (m_dyld_all_image_infos.dylib_info_count > 0)
         {
-            ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[idx], true, NULL));
-
-            if (image_module_sp)
+            if (m_dyld_all_image_infos.dylib_info_addr == 0)
             {
-                if (m_dyld_image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
-                    image_module_sp->SetIsDynamicLinkEditor (true);
-
-                ObjectFile *objfile = image_module_sp->GetObjectFile ();
-                if (objfile)
-                {
-                    SectionList *sections = objfile->GetSectionList();
-                    if (sections)
-                    {
-                        ConstString commpage_dbstr("__commpage");
-                        Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
-                        if (commpage_section)
-                        {
-                            const FileSpec objfile_file_spec = objfile->GetFileSpec();
-                            ArchSpec arch (m_dyld_image_infos[idx].GetArchitecture ());
-                            ModuleSP commpage_image_module_sp(target_images.FindFirstModuleForFileSpec (objfile_file_spec, &arch, &commpage_dbstr));
-                            if (!commpage_image_module_sp)
-                            {
-                                commpage_image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
-                                                                                                   arch,
-                                                                                                   NULL,
-                                                                                                   &commpage_dbstr,
-                                                                                                   objfile->GetOffset() + commpage_section->GetFileOffset());
-                            }
-                            if (commpage_image_module_sp)
-                                UpdateCommPageLoadAddress (commpage_image_module_sp.get());
-                        }
-                    }
-                }
-
-                // UpdateImageLoadAddress will return true if any segments
-                // change load address. We need to check this so we don't
-                // mention that all loaded shared libraries are newly loaded
-                // each time we hit out dyld breakpoint since dyld will list all
-                // shared libraries each time.
-                if (UpdateImageLoadAddress (image_module_sp.get(), m_dyld_image_infos[idx]))
-                {
-                    loaded_module_list.AppendIfNeeded (image_module_sp);
-                }
+                // DYLD is updating the images now.  So we should say we have no images, and then we'll 
+                // figure it out when we hit the added breakpoint.
+                return false;
             }
-        }
-        if (loaded_module_list.GetSize() > 0)
-        {
-            // FIXME: This should really be in the Runtime handlers class, which should get
-            // called by the target's ModulesDidLoad, but we're doing it all locally for now 
-            // to save time.
-            // Also, I'm assuming there can be only one libobjc dylib loaded...
-            
-            ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
-            if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
+            else
             {
-                size_t num_modules = loaded_module_list.GetSize();
-                for (int i = 0; i < num_modules; i++)
+                if (!AddModulesUsingImageInfosAddress (m_dyld_all_image_infos.dylib_info_addr, 
+                                                       m_dyld_all_image_infos.dylib_info_count))
                 {
-                    if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
-                    {
-                        objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
-                        break;
-                    }
+                    DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
+                    m_dyld_image_infos.clear();
                 }
             }
-            if (log)
-                loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
-            m_process->GetTarget().ModulesDidLoad (loaded_module_list);
         }
+        return true;
     }
-    return m_dyld_image_infos.size();
+    else
+        return false;
 }
 
 //----------------------------------------------------------------------
@@ -968,40 +1104,41 @@
 // Read the mach_header and load commands for each image that the
 // _dyld_all_image_infos structure points to and cache the results.
 //----------------------------------------------------------------------
+
 void
-DynamicLoaderMacOSXDYLD::UpdateAllImageInfosHeaderAndLoadCommands()
+DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos, 
+                                                               uint32_t infos_count, 
+                                                               bool update_executable)
 {
     uint32_t exe_idx = UINT32_MAX;
     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
     // Read any UUID values that we can get
-    for (uint32_t i = 0; i < m_dyld_all_image_infos.dylib_info_count; i++)
+    for (uint32_t i = 0; i < infos_count; i++)
     {
-        if (!m_dyld_image_infos[i].UUIDValid())
+        if (!image_infos[i].UUIDValid())
         {
             DataExtractor data; // Load command data
-            if (!ReadMachHeader (m_dyld_image_infos[i].address, &m_dyld_image_infos[i].header, &data))
+            if (!ReadMachHeader (image_infos[i].address, &image_infos[i].header, &data))
                 continue;
 
-            ParseLoadCommands (data, m_dyld_image_infos[i], NULL);
+            ParseLoadCommands (data, image_infos[i], NULL);
 
-            if (m_dyld_image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable)
+            if (image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable)
                 exe_idx = i;
             
-            if (log)
-                m_dyld_image_infos[i].PutToLog (log.get());
         }
     }
 
-    if (exe_idx < m_dyld_image_infos.size())
+    if (exe_idx < image_infos.size())
     {
-        ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[exe_idx], false, NULL));
+        ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], false, NULL));
 
         if (!exe_module_sp)
         {
-            ArchSpec exe_arch_spec (m_dyld_image_infos[exe_idx].GetArchitecture ());
-            exe_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[exe_idx].file_spec,
+            ArchSpec exe_arch_spec (image_infos[exe_idx].GetArchitecture ());
+            exe_module_sp = m_process->GetTarget().GetSharedModule (image_infos[exe_idx].file_spec,
                                                                     exe_arch_spec,
-                                                                    &m_dyld_image_infos[exe_idx].uuid);
+                                                                    &image_infos[exe_idx].uuid);
         }
         
         if (exe_module_sp)

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h?rev=133448&r1=133447&r2=133448&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Mon Jun 20 12:32:44 2011
@@ -103,19 +103,11 @@
     bool
     ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr);
 
-    uint32_t
-    UpdateAllImageInfos ();
-
     static bool
     NotifyBreakpointHit (void *baton,
                          lldb_private::StoppointCallbackContext *context,
                          lldb::user_id_t break_id,
                          lldb::user_id_t break_loc_id);
-    void
-    UpdateAllImageInfosHeaderAndLoadCommands ();
-
-    bool
-    UpdateCommPageLoadAddress (lldb_private::Module *module);
 
     uint32_t
     AddrByteSize()
@@ -380,8 +372,42 @@
     bool
     SetNotificationBreakpoint ();
 
+    // There is a little tricky bit where you might initially attach while dyld is updating
+    // the all_image_infos, and you can't read the infos, so you have to continue and pick it
+    // up when you hit the update breakpoint.  At that point, you need to run this initialize
+    // function, but when you do it that way you DON'T need to do the extra work you would at
+    // the breakpoint.
+    // So this function will only do actual work if the image infos haven't been read yet.
+    // If it does do any work, then it will return true, and false otherwise.  That way you can
+    // call it in the breakpoint action, and if it returns true you're done.
+    bool
+    InitializeFromAllImageInfos ();
+
     bool
     ReadAllImageInfosStructure ();
+    
+    bool
+    AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
+    
+    bool
+    AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos);
+    
+    bool
+    RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
+
+    void
+    UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos, 
+                                          uint32_t infos_count, 
+                                          bool update_executable);
+
+    bool
+    UpdateCommPageLoadAddress (lldb_private::Module *module);
+
+    bool
+    ReadImageInfos (lldb::addr_t image_infos_addr, 
+                    uint32_t image_infos_count, 
+                    DYLDImageInfo::collection &image_infos);
+
 
     DYLDImageInfo m_dyld;               // Info about the current dyld being used
     lldb::addr_t m_dyld_all_image_infos_addr;

Modified: lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp?rev=133448&r1=133447&r2=133448&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp Mon Jun 20 12:32:44 2011
@@ -27,6 +27,8 @@
     Thread *thread = process->GetThreadList().GetSelectedThread().get();
     if (thread == NULL)
         thread = process->GetThreadList().GetThreadAtIndex(0).get();
+    if (thread == NULL)
+        return false;
 
     const bool append = true;
     const bool include_symbols = true;

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=133448&r1=133447&r2=133448&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Mon Jun 20 12:32:44 2011
@@ -1897,6 +1897,9 @@
 addr_t
 Process::AllocateMemory(size_t size, uint32_t permissions, Error &error)
 {
+    if (GetPrivateState() != eStateStopped)
+        return LLDB_INVALID_ADDRESS;
+        
 #if defined (USE_ALLOCATE_MEMORY_CACHE)
     return m_allocated_memory_cache.AllocateMemory(size, permissions, error);
 #else

Modified: lldb/trunk/test/types/AbstractBase.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/types/AbstractBase.py?rev=133448&r1=133447&r2=133448&view=diff
==============================================================================
--- lldb/trunk/test/types/AbstractBase.py (original)
+++ lldb/trunk/test/types/AbstractBase.py Mon Jun 20 12:32:44 2011
@@ -44,8 +44,13 @@
         # Bring the program to the point where we can issue a series of
         # 'frame variable -T' command.
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
-        self.runCmd("breakpoint set --name Puts")
-        self.runCmd("run", RUN_SUCCEEDED)
+        puts_line = line_number ("basic_type.cpp", "// Here is the line we will break on before stepping out")
+        self.expect("breakpoint set -f basic_type.cpp -l %d" % puts_line,
+                    BREAKPOINT_CREATED,
+            startstr = "Breakpoint created: 1: file ='basic_type.cpp', line = %d, locations = 1" %
+                        puts_line)
+
+        self.expect("run", RUN_SUCCEEDED, patterns = [".*"])
         self.runCmd("thread step-out", STEP_OUT_SUCCEEDED)
 
         #self.runCmd("frame variable -T")
@@ -104,8 +109,16 @@
         # Bring the program to the point where we can issue a series of
         # 'expr' command.
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
-        self.runCmd("breakpoint set --name Puts")
-        self.runCmd("run", RUN_SUCCEEDED)
+        #self.runCmd("breakpoint set --name Puts")
+        #self.runCmd("run", RUN_SUCCEEDED)
+        puts_line = line_number ("basic_type.cpp", "// Here is the line we will break on before stepping out")
+        self.expect("breakpoint set -f basic_type.cpp -l %d" % puts_line,
+                    BREAKPOINT_CREATED,
+            startstr = "Breakpoint created: 1: file ='basic_type.cpp', line = %d, locations = 1" %
+                        puts_line)
+        self.expect("run", RUN_SUCCEEDED, patterns = [".*"])
+        self.runCmd ("process status")
+
         self.runCmd("thread step-out", STEP_OUT_SUCCEEDED)
 
         #self.runCmd("frame variable -T")

Modified: lldb/trunk/test/types/basic_type.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/types/basic_type.cpp?rev=133448&r1=133447&r2=133448&view=diff
==============================================================================
--- lldb/trunk/test/types/basic_type.cpp (original)
+++ lldb/trunk/test/types/basic_type.cpp Mon Jun 20 12:32:44 2011
@@ -84,7 +84,7 @@
 
 void Puts(char const *msg)
 {
-    puts(msg);
+    puts(msg);  // Here is the line we will break on before stepping out
 }
 
 int 





More information about the lldb-commits mailing list