Debugger: Fix various issues in the DWARF subsystem.

AttributeClasses:
- Fix typo in get_attribute_name_classes which resulted in us not
  handling DW_AT_linkage_name properly.
- Fix incorrect class specification for DW_AT_default_value due
  to inconsistencies in the DWARF documentation (the table of attribute
  classes indicates it is only a reference, but the detailed description
  indicates it also being possible to be a flag or constant, both of
  which gcc outputs).

DebugInfoEntries:
- Add accessor for DIEClassBaseType's inner types.

DwarfImageDebugInfo:
- When looking up types, create a basic target interface to pass on
  to the type context. Otherwise, type lookups that required DWARF
  expression evaluation would crash.
- When building the type name table, we now recursively walk a class's
  inner types, and add them to the list as well. This omission would
  cause the debugger to lack the type description for such classes,
  and consequently be unable to display their details in the variables
  view.
This commit is contained in:
Rene Gollent 2018-01-12 22:15:11 -05:00
parent f6d25a3a81
commit ac9e464b78
4 changed files with 83 additions and 33 deletions

View File

@ -1,6 +1,6 @@
/*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2012-2016, Rene Gollent, rene@gollent.com.
* Copyright 2012-2018, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
@ -554,9 +554,33 @@ DwarfImageDebugInfo::GetType(GlobalTypeCache* cache, const BString& name,
continue;
}
int32 registerCount = fArchitecture->CountRegisters();
const Register* registers = fArchitecture->Registers();
// get the DWARF <-> architecture register maps
RegisterMap* toDwarfMap;
RegisterMap* fromDwarfMap;
status_t error = fArchitecture->GetDwarfRegisterMaps(&toDwarfMap,
&fromDwarfMap);
if (error != B_OK)
return error;
BReference<RegisterMap> toDwarfMapReference(toDwarfMap, true);
BReference<RegisterMap> fromDwarfMapReference(fromDwarfMap, true);
// create the target interface
BasicTargetInterface* targetInterface
= new(std::nothrow) BasicTargetInterface(registers, registerCount,
fromDwarfMap, fArchitecture, fDebuggerInterface);
if (targetInterface == NULL)
return B_NO_MEMORY;
BReference<BasicTargetInterface> targetInterfaceReference(
targetInterface, true);
DwarfTypeContext* typeContext = new(std::nothrow)
DwarfTypeContext(fArchitecture, fImageInfo.ImageID(), fFile,
info->unit, NULL, 0, 0, fRelocationDelta, NULL, NULL);
info->unit, NULL, 0, 0, fRelocationDelta, targetInterface, NULL);
if (typeContext == NULL)
return B_NO_MEMORY;
BReference<DwarfTypeContext> typeContextReference(typeContext, true);
@ -564,7 +588,7 @@ DwarfImageDebugInfo::GetType(GlobalTypeCache* cache, const BString& name,
// create the type
DwarfType* type;
DwarfTypeFactory typeFactory(typeContext, fTypeLookup, cache);
status_t error = typeFactory.CreateType(typeEntry, type);
error = typeFactory.CreateType(typeEntry, type);
if (error != B_OK)
continue;
@ -1378,32 +1402,54 @@ DwarfImageDebugInfo::_BuildTypeNameTable()
for (DebugInfoEntryList::ConstIterator it
= unit->UnitEntry()->Types().GetIterator();
DIEType* typeEntry = dynamic_cast<DIEType*>(it.Next());) {
if (typeEntry->IsDeclaration())
continue;
BString typeEntryName;
DwarfUtils::GetFullyQualifiedDIEName(typeEntry, typeEntryName);
TypeNameEntry* entry = fTypeNameTable->Lookup(typeEntryName);
if (entry == NULL) {
entry = new(std::nothrow) TypeNameEntry(typeEntryName);
if (entry == NULL)
return B_NO_MEMORY;
error = fTypeNameTable->Insert(entry);
if (error != B_OK)
return error;
}
TypeEntryInfo* info = new(std::nothrow) TypeEntryInfo(typeEntry,
unit);
if (info == NULL)
if (_RecursiveAddTypeNames(typeEntry, unit) != B_OK)
return B_NO_MEMORY;
if (!entry->types.AddItem(info)) {
delete info;
return B_NO_MEMORY;
}
}
}
return B_OK;
}
status_t
DwarfImageDebugInfo::_RecursiveAddTypeNames(DIEType* type, CompilationUnit* unit)
{
if (type->IsDeclaration())
return B_OK;
BString typeEntryName;
DwarfUtils::GetFullyQualifiedDIEName(type, typeEntryName);
status_t error = B_OK;
TypeNameEntry* entry = fTypeNameTable->Lookup(typeEntryName);
if (entry == NULL) {
entry = new(std::nothrow) TypeNameEntry(typeEntryName);
if (entry == NULL)
return B_NO_MEMORY;
error = fTypeNameTable->Insert(entry);
if (error != B_OK)
return error;
}
TypeEntryInfo* info = new(std::nothrow) TypeEntryInfo(type, unit);
if (info == NULL)
return B_NO_MEMORY;
if (!entry->types.AddItem(info)) {
delete info;
return B_NO_MEMORY;
}
DIEClassBaseType* classType = dynamic_cast<DIEClassBaseType*>(type);
if (classType != NULL) {
for (DebugInfoEntryList::ConstIterator it
= classType->InnerTypes().GetIterator();
DIEType* innerType = dynamic_cast<DIEType*>(it.Next());) {
error = _RecursiveAddTypeNames(innerType, unit);
if (error != B_OK)
return error;
}
}

View File

@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2010-2016, Rene Gollent, rene@gollent.com.
* Copyright 2010-2018, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef DWARF_IMAGE_DEBUG_INFO_H
@ -131,6 +131,8 @@ private:
const;
status_t _BuildTypeNameTable();
status_t _RecursiveAddTypeNames(DIEType* type,
CompilationUnit* unit);
private:
BLocker fLock;

View File

@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2013-2014, Rene Gollent, rene@gollent.com.
* Copyright 2013-2018, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
@ -61,7 +61,7 @@ static const attribute_name_info_entry kAttributeNameInfos[] = {
{ ENTRY(comp_dir), AC_STRING },
{ ENTRY(const_value), AC_BLOCK | AC_CONSTANT | AC_STRING },
{ ENTRY(containing_type), AC_REFERENCE },
{ ENTRY(default_value), AC_REFERENCE },
{ ENTRY(default_value), AC_REFERENCE | AC_CONSTANT | AC_FLAG },
{ ENTRY(inline), AC_CONSTANT },
{ ENTRY(is_optional), AC_FLAG },
{ ENTRY(lower_bound), AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
@ -213,7 +213,7 @@ static struct InitAttributeInfos {
uint16
get_attribute_name_classes(uint32 name)
{
if (name < DW_AT_linkage_name)
if (name <= DW_AT_linkage_name)
return sAttributeNameInfos[name].classes;
else if (name >= DW_AT_call_site_value
&& name <= DW_AT_all_source_call_sites) {
@ -252,7 +252,7 @@ get_attribute_class(uint32 name, uint32 form)
const char*
get_attribute_name_name(uint32 name)
{
if (name < DW_AT_linkage_name)
if (name <= DW_AT_linkage_name)
return sAttributeNameInfos[name].name;
else if (name >= DW_AT_call_site_value
&& name <= DW_AT_all_source_call_sites) {

View File

@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2013-2014, Rene Gollent, rene@gollent.com.
* Copyright 2013-2018, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef DEBUG_INFO_ENTRIES_H
@ -366,6 +366,8 @@ public:
const DebugInfoEntryList& BaseTypes() const
{ return fBaseTypes; }
const DebugInfoEntryList& InnerTypes() const
{ return fInnerTypes; }
const DebugInfoEntryList& TemplateParameters() const
{ return fTemplateParameters; }