Skip to content

Commit

Permalink
Add support for anon types in FQN generation
Browse files Browse the repository at this point in the history
This fixes a bug in the fully qualified name generation we encounter a
segment that has no name, such as when a proc is really a C++ lambda
expression, which internally generates an anonymous class to house the
function. In this case, we generate a unique name based on the DIE's
offset to serve as the segment's name.
  • Loading branch information
alexbudfb committed Mar 24, 2023
1 parent a32d920 commit 6fd46e7
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 3 deletions.
20 changes: 18 additions & 2 deletions src/dwarf2pdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,13 +735,29 @@ void CV2PDB::formatFullyQualifiedProcName(const DWARF_InfoData* proc, char* buf,

// Format the parents in reverse order with :: operator in between.
for (int i = segments.size() - 1; i >= 0; --i) {
const int nameLen = strlen(segments[i]->name);
const char* name = segments[i]->name;
char nameBuf[64] = {};
int nameLen = 0;
if (!segments[i]->name) {
// This segment has no name. This could be because it is part of
// an anonymous class, which often happens for lambda expressions.
// Generate a unique anonymous name for it.
nameLen = sprintf_s(nameBuf, "[anon_%x]", segments[i]->entryOff);
if (nameLen < 0) {
// Formatting failed. Try a default name.
assert(false); // crash in debug builds.
name = "[anon]";
}
name = nameBuf;
} else {
nameLen = strlen(name);
}
if (remain < nameLen) {
fprintf(stderr, "unable to fit full proc name: %s\n", proc->name);
return;
}

memcpy(p, segments[i]->name, nameLen);
memcpy(p, name, nameLen);

p += nameLen;
remain -= nameLen;
Expand Down
2 changes: 1 addition & 1 deletion src/readDwarf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ DWARF_InfoData* DIECursor::readNext(DWARF_InfoData* entry, bool stopAtNull)
return nullptr; // root of the tree does not have a null terminator, but we know the length

id.entryPtr = ptr;
entryOff = img->debug_info.sectOff(ptr);
entryOff = id.entryOff = img->debug_info.sectOff(ptr);
id.code = LEB128(ptr);

// If the previously scanned node claimed to have a child, this must be a valid DIE.
Expand Down
2 changes: 2 additions & 0 deletions src/readDwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ struct DWARF_InfoData
// Pointer into the memory-mapped image section where this DIE is located.
byte* entryPtr;

unsigned int entryOff = 0; // the entry offset in the section it is in.

// Code to find the abbrev entry for this DIE, or 0 if it a sentinel marking
// the end of a sibling chain.
int code;
Expand Down

0 comments on commit 6fd46e7

Please sign in to comment.