Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
fix Issue 18068 - Account for DSO-relative DWARF addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
kinke committed May 3, 2018
1 parent 7c2ea83 commit d109d53
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/rt/backtrace/dwarf.d
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ int traceHandlerOpApplyImpl(const void*[] callstack, scope int delegate(ref size
foreach(size_t i; 0 .. callstack.length)
locations[i].address = cast(size_t) callstack[i];

resolveAddresses(debugLineSectionData, locations[]);
resolveAddresses(debugLineSectionData, image.baseAddress, locations[]);
}
}

Expand Down Expand Up @@ -123,7 +123,7 @@ int traceHandlerOpApplyImpl(const void*[] callstack, scope int delegate(ref size
private:

// the lifetime of the Location data is the lifetime of the mmapped ElfSection
void resolveAddresses(const(ubyte)[] debugLineSectionData, Location[] locations) @nogc nothrow
void resolveAddresses(const(ubyte)[] debugLineSectionData, size_t baseAddress, Location[] locations) @nogc nothrow
{
debug(DwarfDebugMachine) import core.stdc.stdio;

Expand All @@ -142,6 +142,8 @@ void resolveAddresses(const(ubyte)[] debugLineSectionData, Location[] locations)
runStateMachine(lp,
(size_t address, LocationInfo locInfo, bool isEndSequence)
{
address += baseAddress;

// If loc.line != -1, then it has been set previously.
// Some implementations (eg. dmd) write an address to
// the debug data multiple times, but so far I have found
Expand Down
64 changes: 64 additions & 0 deletions src/rt/backtrace/elf.d
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ struct Image

return null;
}

@property size_t baseAddress()
{
// the DWARF addresses for DSOs are relative
const isDynamicSharedObject = (file.ehdr.e_type == ET_DYN);
if (!isDynamicSharedObject)
return 0;

return cast(size_t) getMemoryRegionOfExecutable().ptr;
}
}

private:
Expand Down Expand Up @@ -322,3 +332,57 @@ else
{
static assert(0, "unsupported byte order");
}


const(void)[] getMemoryRegionOfExecutable() @nogc nothrow
{
import core.sys.posix.unistd : readlink, getpid;
import core.stdc.stdio, core.stdc.stdlib, core.stdc.string;

// get absolute path to executable
char[1024] selfPath = void;
version (FreeBSD)
{
getFreeBSDExePath(selfPath[]);
}
else
{
version (linux)
{
auto selfLink = "/proc/self/exe".ptr;
}
else version (DragonFlyBSD)
{
auto selfLink = "/proc/curproc/file".ptr;
}

const length = readlink(selfLink, selfPath.ptr, selfPath.length);
assert(length > 0 && length < selfPath.length);
selfPath[length] = 0;
}

// open the current process' maps file
char[1024] selfMapsPath = void;
snprintf(selfMapsPath.ptr, selfMapsPath.length, "/proc/%d/maps", getpid());
FILE* fp = fopen(selfMapsPath.ptr, "r");
assert(fp);
scope(exit) fclose(fp);

// use the region in the first line for the executable file
char[128] line = void;
while (fgets(line.ptr, line.length, fp) !is null)
{
line[strlen(line.ptr) - 1] = '\0'; // remove trailing '\n'
char* path = strchr(line.ptr, '/');
if (path && strcmp(selfPath.ptr, path) == 0)
{
char* tail;
const start = cast(void*) strtoul(line.ptr, &tail, 16);
++tail; // skip over '-'
const end = cast(void*) strtoul(tail, &tail, 16);
return start[0 .. end - start];
}
}

assert(0);
}
5 changes: 5 additions & 0 deletions src/rt/backtrace/macho.d
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,9 @@ struct Image
auto data = getsectiondata(self, "__DWARF", "__debug_line", &size);
return data[0 .. size];
}

@property size_t baseAddress()
{
return 0;
}
}

0 comments on commit d109d53

Please sign in to comment.