[Lldb-commits] [lldb] r156795 - in /lldb/trunk: include/lldb/Target/Platform.h include/lldb/Target/Target.h source/Plugins/Platform/MacOSX/PlatformDarwin.cpp source/Plugins/Platform/MacOSX/PlatformDarwin.h source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp source/Plugins/Process/gdb-remote/ProcessGDBRemote.h source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h source/Target/Platform.cpp source/Target/Target.cpp

Greg Clayton gclayton at apple.com
Mon May 14 19:33:02 PDT 2012


Author: gclayton
Date: Mon May 14 21:33:01 2012
New Revision: 156795

URL: http://llvm.org/viewvc/llvm-project?rev=156795&view=rev
Log:
<rdar://problem/11240464>

Correctly unique a class' methods when we detect that a class has been uniqued to another.


Modified:
    lldb/trunk/include/lldb/Target/Platform.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/trunk/source/Target/Platform.cpp
    lldb/trunk/source/Target/Target.cpp

Modified: lldb/trunk/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Platform.h?rev=156795&r1=156794&r2=156795&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Platform.h (original)
+++ lldb/trunk/include/lldb/Target/Platform.h Mon May 14 21:33:01 2012
@@ -368,6 +368,15 @@
 
         virtual bool
         GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
+        
+        //------------------------------------------------------------------
+        // Set a breakpoint on all functions that can end up creating a thread
+        // for this platform. This is needed when running expressions and
+        // also for process control.
+        //------------------------------------------------------------------
+        virtual lldb::BreakpointSP
+        SetThreadCreationBreakpoint (Target &target);
+        
 
         const std::string &
         GetRemoteURL () const

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=156795&r1=156794&r2=156795&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Mon May 14 21:33:01 2012
@@ -500,8 +500,8 @@
     lldb::BreakpointSP
     CreateBreakpoint (const FileSpecList *containingModules,
                       const FileSpecList *containingSourceFiles,
-                      std::vector<std::string> func_names,
-                      uint32_t func_name_type_mask, 
+                      const std::vector<std::string> &func_names,
+                      uint32_t func_name_type_mask,
                       bool internal = false,
                       LazyBool skip_prologue = eLazyBoolCalculate);
 

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp?rev=156795&r1=156794&r2=156795&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Mon May 14 21:33:01 2012
@@ -823,3 +823,38 @@
     return NULL;
 }
 
+
+BreakpointSP
+PlatformDarwin::SetThreadCreationBreakpoint (Target &target)
+{
+    BreakpointSP bp_sp;
+    static const char *g_bp_names[] =
+    {
+        "start_wqthread",
+        "_pthread_wqthread",
+        "_pthread_start",
+    };
+
+    static const char *g_bp_modules[] =
+    {
+        "libsystem_c.dylib",
+        "libSystem.B.dylib"
+    };
+
+    FileSpecList bp_modules;
+    for (int i = 0; i < sizeof(g_bp_modules)/sizeof(const char *); i++)
+    {
+        const char *bp_module = g_bp_modules[i];
+        bp_modules.Append(FileSpec(bp_module, false));
+    }
+
+    bp_sp = target.CreateBreakpoint (&bp_modules,
+                                     NULL,
+                                     g_bp_names,
+                                     sizeof(g_bp_names)/sizeof(const char *),
+                                     eFunctionNameTypeFull,
+                                     true);
+
+    return bp_sp;
+}
+

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h?rev=156795&r1=156794&r2=156795&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h Mon May 14 21:33:01 2012
@@ -79,6 +79,9 @@
     GetProcessInfo (lldb::pid_t pid, 
                     lldb_private::ProcessInstanceInfo &proc_info);
     
+    virtual lldb::BreakpointSP
+    SetThreadCreationBreakpoint (lldb_private::Target &target);
+
     virtual uint32_t
     FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info,
                    lldb_private::ProcessInstanceInfoList &process_infos);

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=156795&r1=156794&r2=156795&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Mon May 14 21:33:01 2012
@@ -173,8 +173,9 @@
     m_continue_S_tids (),
     m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS),
     m_max_memory_size (512),
-    m_waiting_for_attach (false),
-    m_thread_observation_bps()
+    m_addr_to_mmap_size (),
+    m_thread_create_bp_sp (),
+    m_waiting_for_attach (false)
 {
     m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit,   "async thread should exit");
     m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue,           "async thread continue");
@@ -2672,51 +2673,33 @@
 bool
 ProcessGDBRemote::StartNoticingNewThreads()
 {
-    static const char *bp_names[] =
-    {
-        "start_wqthread",
-        "_pthread_wqthread",
-        "_pthread_start",
-        NULL
-    };
-    
     LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    size_t num_bps = m_thread_observation_bps.size();
-    if (num_bps != 0)
+    if (m_thread_create_bp_sp)
     {
-        for (int i = 0; i < num_bps; i++)
-        {
-            lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]);
-            if (break_sp)
-            {
-                if (log && log->GetVerbose())
-                    log->Printf("Enabled noticing new thread breakpoint.");
-                break_sp->SetEnabled(true);
-            }
-        }
+        if (log && log->GetVerbose())
+            log->Printf("Enabled noticing new thread breakpoint.");
+        m_thread_create_bp_sp->SetEnabled(true);
     }
-    else 
+    else
     {
-        for (int i = 0; bp_names[i] != NULL; i++)
+        PlatformSP platform_sp (m_target.GetPlatform());
+        if (platform_sp)
         {
-            Breakpoint *breakpoint = m_target.CreateBreakpoint (NULL, NULL, bp_names[i], eFunctionNameTypeFull, true).get();
-            if (breakpoint)
+            m_thread_create_bp_sp = platform_sp->SetThreadCreationBreakpoint(m_target);
+            if (m_thread_create_bp_sp)
             {
                 if (log && log->GetVerbose())
-                     log->Printf("Successfully created new thread notification breakpoint at \"%s\".", bp_names[i]);
-                m_thread_observation_bps.push_back(breakpoint->GetID());
-                breakpoint->SetCallback (ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
+                    log->Printf("Successfully created new thread notification breakpoint %i", m_thread_create_bp_sp->GetID());
+                m_thread_create_bp_sp->SetCallback (ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
             }
             else
             {
                 if (log)
                     log->Printf("Failed to create new thread notification breakpoint.");
-                return false;
             }
         }
     }
-
-    return true;
+    return m_thread_create_bp_sp.get() != NULL;
 }
 
 bool
@@ -2725,19 +2708,10 @@
     LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     if (log && log->GetVerbose())
         log->Printf ("Disabling new thread notification breakpoint.");
-    size_t num_bps = m_thread_observation_bps.size();
-    if (num_bps != 0)
-    {
-        for (int i = 0; i < num_bps; i++)
-        {
-            
-            lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]);
-            if (break_sp)
-            {
-                break_sp->SetEnabled(false);
-            }
-        }
-    }
+
+    if (m_thread_create_bp_sp)
+        m_thread_create_bp_sp->SetEnabled(false);
+
     return true;
 }
     

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=156795&r1=156794&r2=156795&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Mon May 14 21:33:01 2012
@@ -315,9 +315,10 @@
     tid_sig_collection m_continue_S_tids; // 'S' for step with signal
     lldb::addr_t m_dispatch_queue_offsets_addr;
     size_t m_max_memory_size;       // The maximum number of bytes to read/write when reading and writing memory
-    bool m_waiting_for_attach;
-    std::vector<lldb::user_id_t>  m_thread_observation_bps;
     MMapMap m_addr_to_mmap_size;
+    lldb::BreakpointSP m_thread_create_bp_sp;
+    bool m_waiting_for_attach;
+    
     bool
     StartAsyncThread ();
 

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=156795&r1=156794&r2=156795&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Mon May 14 21:33:01 2012
@@ -4858,6 +4858,135 @@
     return type_sp;
 }
 
+bool
+SymbolFileDWARF::CopyUniqueClassMethodTypes (Type *class_type,
+                                             DWARFCompileUnit* src_cu,
+                                             const DWARFDebugInfoEntry *src_class_die,
+                                             DWARFCompileUnit* dst_cu,
+                                             const DWARFDebugInfoEntry *dst_class_die)
+{
+    if (!class_type || !src_cu || !src_class_die || !dst_cu || !dst_class_die)
+        return false;
+    if (src_class_die->Tag() != dst_class_die->Tag())
+        return false;
+    
+    // We need to complete the class type so we can get all of the method types
+    // parsed so we can then unique those types to their equivalent counterparts
+    // in "dst_cu" and "dst_class_die"
+    class_type->GetClangFullType();
+
+    const DWARFDebugInfoEntry *src_die;
+    const DWARFDebugInfoEntry *dst_die;
+    UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die;
+    UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die;
+    for (src_die = src_class_die->GetFirstChild(); src_die != NULL; src_die = src_die->GetSibling())
+    {
+        if (src_die->Tag() == DW_TAG_subprogram)
+        {
+            const char *src_name = src_die->GetMangledName (this, src_cu);
+            if (src_name)
+                src_name_to_die.Append(ConstString(src_name).GetCString(), src_die);
+        }
+    }
+    for (dst_die = dst_class_die->GetFirstChild(); dst_die != NULL; dst_die = dst_die->GetSibling())
+    {
+        if (dst_die->Tag() == DW_TAG_subprogram)
+        {
+            const char *dst_name = dst_die->GetMangledName (this, dst_cu);
+            if (dst_name)
+                dst_name_to_die.Append(ConstString(dst_name).GetCString(), dst_die);
+        }
+    }
+    const uint32_t src_size = src_name_to_die.GetSize ();
+    const uint32_t dst_size = dst_name_to_die.GetSize ();
+    LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION));
+    
+    if (src_size && dst_size)
+    {
+        uint32_t idx;
+        for (idx = 0; idx < src_size; ++idx)
+        {
+            src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
+            dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
+
+            if (src_die->Tag() != dst_die->Tag())
+            {
+                if (log)
+                    log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
+                                src_class_die->GetOffset(),
+                                dst_class_die->GetOffset(),
+                                src_die->GetOffset(),
+                                DW_TAG_value_to_name(src_die->Tag()),
+                                dst_die->GetOffset(),
+                                DW_TAG_value_to_name(src_die->Tag()));
+                return false;
+            }
+            
+            const char *src_name = src_die->GetMangledName (this, src_cu);
+            const char *dst_name = dst_die->GetMangledName (this, dst_cu);
+            
+            // Make sure the names match
+            if (src_name == dst_name || (strcmp (src_name, dst_name) == 0))
+                continue;
+
+            if (log)
+                log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
+                            src_class_die->GetOffset(),
+                            dst_class_die->GetOffset(),
+                            src_die->GetOffset(),
+                            src_name,
+                            dst_die->GetOffset(),
+                            dst_name);
+            
+            return false;
+        }
+
+        for (idx = 0; idx < src_size; ++idx)
+        {
+            src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
+            dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
+            
+            clang::DeclContext *src_decl_ctx = m_die_to_decl_ctx[src_die];
+            if (src_decl_ctx)
+            {
+                if (log)
+                    log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x\n", src_decl_ctx, src_die->GetOffset(), dst_die->GetOffset());
+                LinkDeclContextToDIE (src_decl_ctx, dst_die);
+            }
+            else
+            {
+                if (log)
+                    log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found\n", src_die->GetOffset(), dst_die->GetOffset());
+            }
+            
+            Type *src_child_type = m_die_to_type[src_die];
+            if (src_child_type)
+            {
+                if (log)
+                    log->Printf ("uniquing type %p (uid=0x%llx) from 0x%8.8x for 0x%8.8x\n", src_child_type, src_child_type->GetID(), src_die->GetOffset(), dst_die->GetOffset());
+                m_die_to_type[dst_die] = src_child_type;
+            }
+            else
+            {
+                if (log)
+                    log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found\n", src_die->GetOffset(), dst_die->GetOffset());
+            }
+        }
+        return true;
+    }
+    else
+    {
+        if (log)
+            log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x has %u methods and 0x%8.8x has %u",
+                        src_class_die->GetOffset(),
+                        dst_class_die->GetOffset(),
+                        src_die->GetOffset(),
+                        src_size,
+                        dst_die->GetOffset(),
+                        dst_size);
+    }
+    return false;
+}
 
 TypeSP
 SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
@@ -5745,6 +5874,31 @@
                                 Type *class_type = ResolveType (dwarf_cu, decl_ctx_die);
                                 if (class_type)
                                 {
+                                    if (class_type->GetID() != MakeUserID(decl_ctx_die->GetOffset()))
+                                    {
+                                        // We uniqued the parent class of this function to another class
+                                        // so we now need to associate all dies under "decl_ctx_die" to
+                                        // DIEs in the DIE for "class_type"...
+                                        DWARFCompileUnitSP class_type_cu_sp;
+                                        const DWARFDebugInfoEntry *class_type_die = DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
+                                        if (class_type_die)
+                                        {
+                                            if (CopyUniqueClassMethodTypes (class_type,
+                                                                            class_type_cu_sp.get(),
+                                                                            class_type_die,
+                                                                            dwarf_cu,
+                                                                            decl_ctx_die))
+                                            {
+                                                type_ptr = m_die_to_type[die];
+                                                if (type_ptr)
+                                                {
+                                                    type_sp = type_ptr->shared_from_this();
+                                                    break;
+                                                }
+                                            }
+                                        }
+                                    }
+                                    
                                     if (specification_die_offset != DW_INVALID_OFFSET)
                                     {
                                         // We have a specification which we are going to base our function

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=156795&r1=156794&r2=156795&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Mon May 14 21:33:01 2012
@@ -521,6 +521,13 @@
                            const DWARFDebugInfoEntry *class_die,
                            const lldb_private::ConstString &selector);
 
+    bool
+    CopyUniqueClassMethodTypes (lldb_private::Type *class_type,
+                                DWARFCompileUnit* src_cu,
+                                const DWARFDebugInfoEntry *src_class_die,
+                                DWARFCompileUnit* dst_cu,
+                                const DWARFDebugInfoEntry *dst_class_die);
+
     SymbolFileDWARFDebugMap *       m_debug_map_symfile;
     clang::TranslationUnitDecl *    m_clang_tu_decl;
     lldb_private::Flags             m_flags;

Modified: lldb/trunk/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Platform.cpp?rev=156795&r1=156794&r2=156795&view=diff
==============================================================================
--- lldb/trunk/source/Target/Platform.cpp (original)
+++ lldb/trunk/source/Target/Platform.cpp Mon May 14 21:33:01 2012
@@ -13,6 +13,7 @@
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
+#include "lldb/Breakpoint/BreakpointIDList.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/PluginManager.h"
@@ -673,4 +674,9 @@
     
 }
 
+lldb::BreakpointSP
+Platform::SetThreadCreationBreakpoint (lldb_private::Target &target)
+{
+    return lldb::BreakpointSP();
+}
 

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=156795&r1=156794&r2=156795&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Mon May 14 21:33:01 2012
@@ -291,11 +291,11 @@
 
 lldb::BreakpointSP
 Target::CreateBreakpoint (const FileSpecList *containingModules,
-                  const FileSpecList *containingSourceFiles,
-                  std::vector<std::string> func_names,
-                  uint32_t func_name_type_mask, 
-                  bool internal,
-                  LazyBool skip_prologue)
+                          const FileSpecList *containingSourceFiles,
+                          const std::vector<std::string> &func_names,
+                          uint32_t func_name_type_mask,
+                          bool internal,
+                          LazyBool skip_prologue)
 {
     BreakpointSP bp_sp;
     size_t num_names = func_names.size();





More information about the lldb-commits mailing list