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:
parent
f6d25a3a81
commit
ac9e464b78
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue