[Lldb-commits] [lldb] r194120 - Improve lldb_private::Address to detect when section was deleted and not return bogus values for GetLoadAddress() and GetFileAddress().

Greg Clayton gclayton at apple.com
Tue Nov 5 18:29:13 PST 2013


Author: gclayton
Date: Tue Nov  5 20:29:13 2013
New Revision: 194120

URL: http://llvm.org/viewvc/llvm-project?rev=194120&view=rev
Log:
Improve lldb_private::Address to detect when section was deleted and not return bogus values for GetLoadAddress() and GetFileAddress().


Modified:
    lldb/trunk/include/lldb/Core/Address.h
    lldb/trunk/source/Core/Address.cpp

Modified: lldb/trunk/include/lldb/Core/Address.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Address.h?rev=194120&r1=194119&r2=194120&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Address.h (original)
+++ lldb/trunk/include/lldb/Core/Address.h Tue Nov  5 20:29:13 2013
@@ -540,6 +540,18 @@ protected:
     //------------------------------------------------------------------
     lldb::SectionWP m_section_wp;   ///< The section for the address, can be NULL.
     std::atomic<lldb::addr_t> m_offset;      ///< Offset into section if \a m_section_wp is valid...
+    
+    //------------------------------------------------------------------
+    // Returns true if the m_section_wp once had a reference to a valid
+    // section shared pointer, but no longer does. This can happen if
+    // we have an address from a module that gets unloaded and deleted.
+    // This function should only be called if GetSection() returns an
+    // empty shared pointer and you want to know if this address used to
+    // have a valid section.
+    //------------------------------------------------------------------
+    bool
+    SectionWasDeleted() const;
+
 };
 
 

Modified: lldb/trunk/source/Core/Address.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=194120&r1=194119&r2=194120&view=diff
==============================================================================
--- lldb/trunk/source/Core/Address.cpp (original)
+++ lldb/trunk/source/Core/Address.cpp Tue Nov  5 20:29:13 2013
@@ -280,6 +280,12 @@ Address::GetFileAddress () const
         // address by adding the file base address to our offset
         return sect_file_addr + m_offset;
     }
+    else if (SectionWasDeleted())
+    {
+        // Used to have a valid section but it got deleted so the
+        // offset doesn't mean anything without the section
+        return LLDB_INVALID_ADDRESS;
+    }
     // No section, we just return the offset since it is the value in this case
     return m_offset;
 }
@@ -288,25 +294,33 @@ addr_t
 Address::GetLoadAddress (Target *target) const
 {
     SectionSP section_sp (GetSection());
-    if (!section_sp)
-    {
-        // No section, we just return the offset since it is the value in this case
-        return m_offset;
-    }
-    
-    if (target)
+    if (section_sp)
     {
-        addr_t sect_load_addr = section_sp->GetLoadBaseAddress (target);
-
-        if (sect_load_addr != LLDB_INVALID_ADDRESS)
+        if (target)
         {
-            // We have a valid file range, so we can return the file based
-            // address by adding the file base address to our offset
-            return sect_load_addr + m_offset;
+            addr_t sect_load_addr = section_sp->GetLoadBaseAddress (target);
+
+            if (sect_load_addr != LLDB_INVALID_ADDRESS)
+            {
+                // We have a valid file range, so we can return the file based
+                // address by adding the file base address to our offset
+                return sect_load_addr + m_offset;
+            }
         }
     }
-    // The section isn't resolved or no process was supplied so we can't
-    // return a valid file address.
+    else if (SectionWasDeleted())
+    {
+        // Used to have a valid section but it got deleted so the
+        // offset doesn't mean anything without the section
+        return LLDB_INVALID_ADDRESS;
+    }
+    else
+    {
+        // We don't have a section so the offset is the load address
+        return m_offset;
+    }
+    // The section isn't resolved or an invalid target was passed in
+    // so we can't return a valid load address.
     return LLDB_INVALID_ADDRESS;
 }
 
@@ -766,6 +780,19 @@ Address::Dump (Stream *s, ExecutionConte
     return true;
 }
 
+bool
+Address::SectionWasDeleted() const
+{
+    lldb::SectionWP empty_section_wp;
+
+    // If either call to "std::weak_ptr::owner_before(...) value returns true, this
+    // indicates that m_section_wp once contained (possibly still does) a reference
+    // to a valid shared pointer. This helps us know if we had a valid reference to
+    // a section which is now invalid because the module it was in was unloaded/deleted,
+    // or if the address doesn't have a valid reference to a section.
+    return empty_section_wp.owner_before(m_section_wp) || m_section_wp.owner_before(empty_section_wp);
+}
+
 uint32_t
 Address::CalculateSymbolContext (SymbolContext *sc, uint32_t resolve_scope) const
 {





More information about the lldb-commits mailing list