[Lldb-commits] [lldb] r176067 - Fixed several problems with class uniq'ing in the
Sean Callanan
scallanan at apple.com
Mon Feb 25 17:12:25 PST 2013
Author: spyffe
Date: Mon Feb 25 19:12:25 2013
New Revision: 176067
URL: http://llvm.org/viewvc/llvm-project?rev=176067&view=rev
Log:
Fixed several problems with class uniq'ing in the
SymbolFileDWARF code:
- If a class is being uniqued to another copy of itself
and the method lists don't match exactly, take a slow
path and at least unique the methods that they have
in common.
- Sort name_to_die maps before querying them. This
would otherwise result in uniquing failures because
looking up a name in a map that contains it would
often fail.
- Tolerate classes in other symbol files in the case
of debugging with .o files rather than with a
.dSYM. We used to assume that the classes being
uniqued were in the same symbol file, causing
unpredictable results.
This will dramatically reduce the number of cases where
a function does not have a valid DeclContext.
<rdar://problem/12153915>
Modified:
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
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=176067&r1=176066&r2=176067&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Mon Feb 25 19:12:25 2013
@@ -5184,11 +5184,13 @@ SymbolFileDWARF::FindDefinitionTypeForDW
}
bool
-SymbolFileDWARF::CopyUniqueClassMethodTypes (Type *class_type,
+SymbolFileDWARF::CopyUniqueClassMethodTypes (SymbolFileDWARF *class_symfile,
+ Type *class_type,
DWARFCompileUnit* src_cu,
const DWARFDebugInfoEntry *src_class_die,
DWARFCompileUnit* dst_cu,
- const DWARFDebugInfoEntry *dst_class_die)
+ const DWARFDebugInfoEntry *dst_class_die,
+ llvm::SmallVectorImpl <const DWARFDebugInfoEntry *> &failures)
{
if (!class_type || !src_cu || !src_class_die || !dst_cu || !dst_class_die)
return false;
@@ -5214,13 +5216,13 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
// for DW_AT_declaration set to 1. Sometimes concrete function instances
// are placed inside the class definitions and shouldn't be included in
// the list of things are are tracking here.
- if (src_die->GetAttributeValueAsUnsigned(this, src_cu, DW_AT_declaration, 0) == 1)
+ if (src_die->GetAttributeValueAsUnsigned(class_symfile, src_cu, DW_AT_declaration, 0) == 1)
{
- const char *src_name = src_die->GetMangledName (this, src_cu);
+ const char *src_name = src_die->GetMangledName (class_symfile, src_cu);
if (src_name)
{
ConstString src_const_name(src_name);
- if (src_die->GetAttributeValueAsUnsigned(this, src_cu, DW_AT_artificial, 0))
+ if (src_die->GetAttributeValueAsUnsigned(class_symfile, src_cu, DW_AT_artificial, 0))
src_name_to_die_artificial.Append(src_const_name.GetCString(), src_die);
else
src_name_to_die.Append(src_const_name.GetCString(), src_die);
@@ -5253,10 +5255,29 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
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));
+
+ // Is everything kosher so we can go through the members at top speed?
+ bool fast_path = true;
+
+ if (src_size != dst_size)
+ {
+ if (src_size != 0 && dst_size != 0)
+ {
+ if (log)
+ log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)",
+ src_class_die->GetOffset(),
+ dst_class_die->GetOffset(),
+ src_size,
+ dst_size);
+ }
+
+ fast_path = false;
+ }
+
+ uint32_t idx;
- if (src_size == dst_size)
+ if (fast_path)
{
- uint32_t idx;
for (idx = 0; idx < src_size; ++idx)
{
src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
@@ -5272,10 +5293,10 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
DW_TAG_value_to_name(src_die->Tag()),
dst_die->GetOffset(),
DW_TAG_value_to_name(src_die->Tag()));
- return false;
+ fast_path = false;
}
- const char *src_name = src_die->GetMangledName (this, src_cu);
+ const char *src_name = src_die->GetMangledName (class_symfile, src_cu);
const char *dst_name = dst_die->GetMangledName (this, dst_cu);
// Make sure the names match
@@ -5291,15 +5312,21 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
dst_die->GetOffset(),
dst_name);
- return false;
+ fast_path = false;
}
+ }
+ // Now do the work of linking the DeclContexts and Types.
+ if (fast_path)
+ {
+ // We can do this quickly. Just run across the tables index-for-index since
+ // we know each node has matching names and tags.
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];
+ clang::DeclContext *src_decl_ctx = class_symfile->m_die_to_decl_ctx[src_die];
if (src_decl_ctx)
{
if (log)
@@ -5325,11 +5352,71 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
}
}
+ }
+ else
+ {
+ // We must do this slowly. For each member of the destination, look
+ // up a member in the source with the same name, check its tag, and
+ // unique them if everything matches up. Report failures.
- const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize ();
+ if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty())
+ {
+ src_name_to_die.Sort();
- UniqueCStringMap<const DWARFDebugInfoEntry *> name_to_die_artificial_not_in_src;
+ for (idx = 0; idx < dst_size; ++idx)
+ {
+ const char *dst_name = dst_name_to_die.GetCStringAtIndex(idx);
+ dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
+ src_die = src_name_to_die.Find(dst_name, NULL);
+
+ if (src_die && (src_die->Tag() == dst_die->Tag()))
+ {
+ clang::DeclContext *src_decl_ctx = class_symfile->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", 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", 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%" PRIx64 ") from 0x%8.8x for 0x%8.8x", 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", src_die->GetOffset(), dst_die->GetOffset());
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die->GetOffset());
+
+ failures.push_back(dst_die);
+ }
+ }
+ }
+ }
+
+ const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize ();
+ const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize ();
+
+ UniqueCStringMap<const DWARFDebugInfoEntry *> name_to_die_artificial_not_in_src;
+ if (src_size_artificial && dst_size_artificial)
+ {
+ dst_name_to_die_artificial.Sort();
+
for (idx = 0; idx < src_size_artificial; ++idx)
{
const char *src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx);
@@ -5366,30 +5453,22 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
}
}
}
- const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize ();
+ }
- if (dst_size_artificial)
+ if (dst_size_artificial)
+ {
+ for (idx = 0; idx < dst_size_artificial; ++idx)
{
- for (idx = 0; idx < dst_size_artificial; ++idx)
- {
- const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx);
- dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
- if (log)
- log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die->GetOffset(), dst_name_artificial);
- }
+ const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx);
+ dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
+ if (log)
+ log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die->GetOffset(), dst_name_artificial);
+
+ failures.push_back(dst_die);
}
- return true;
- }
- else if (src_size != 0 && dst_size != 0)
- {
- if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)",
- src_class_die->GetOffset(),
- dst_class_die->GetOffset(),
- src_size,
- dst_size);
}
- return false;
+
+ return (failures.size() != 0);
}
TypeSP
@@ -6358,22 +6437,43 @@ SymbolFileDWARF::ParseType (const Symbol
// 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"...
+ SymbolFileDWARF *class_symfile;
DWARFCompileUnitSP class_type_cu_sp;
- const DWARFDebugInfoEntry *class_type_die = DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
+ const DWARFDebugInfoEntry *class_type_die;
+
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ {
+ class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
+ class_type_die = class_symfile->DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
+ }
+ else
+ {
+ class_symfile = this;
+ 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))
+ llvm::SmallVector<const DWARFDebugInfoEntry *, 0> failures;
+
+ CopyUniqueClassMethodTypes (class_symfile,
+ class_type,
+ class_type_cu_sp.get(),
+ class_type_die,
+ dwarf_cu,
+ decl_ctx_die,
+ failures);
+
+ // FIXME do something with these failures that's smarter than
+ // just dropping them on the ground. Unfortunately classes don't
+ // like having stuff added to them after their definitions are
+ // complete...
+
+ type_ptr = m_die_to_type[die];
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
{
- type_ptr = m_die_to_type[die];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
- {
- type_sp = type_ptr->shared_from_this();
- break;
- }
+ type_sp = type_ptr->shared_from_this();
+ break;
}
}
}
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=176067&r1=176066&r2=176067&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Mon Feb 25 19:12:25 2013
@@ -22,6 +22,7 @@
#include "clang/AST/ExternalASTSource.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "lldb/lldb-private.h"
#include "lldb/Core/ClangForward.h"
@@ -532,11 +533,13 @@ protected:
const lldb_private::ConstString &selector);
bool
- CopyUniqueClassMethodTypes (lldb_private::Type *class_type,
+ CopyUniqueClassMethodTypes (SymbolFileDWARF *class_symfile,
+ lldb_private::Type *class_type,
DWARFCompileUnit* src_cu,
const DWARFDebugInfoEntry *src_class_die,
DWARFCompileUnit* dst_cu,
- const DWARFDebugInfoEntry *dst_class_die);
+ const DWARFDebugInfoEntry *dst_class_die,
+ llvm::SmallVectorImpl <const DWARFDebugInfoEntry *> &failures);
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap * m_debug_map_symfile;
More information about the lldb-commits
mailing list