Reputation: 932
I'm writing some code that stores a backtrace for each memory allocation. I'm then writing a list of these to a file for offline analysis. In win32 I use _AddressOfReturnAddress
and then manually create the backtrace. Since the address is random for each run I use GetModuleInformation
and lpBaseOfDll
to get the base address. This works great on x86 without FPO, which is good enough for me. I then load the PDB using win32 API to translate the address to function name.
How would I do this on linux? My current approach is to use __builtin_return_address(x)
and addr2line
offline to get the same result. The problem is that the addresses are randomized each run, so addr2line
doesn't understand them. __executable_start
didn't work as it returns the same value each run. Is there any way to get the base address of my executable in runtime?
One run gives me this:
__executable_start: 0x8048000
backtrace:
0x9cce628
0x9cce2b8
0x9cce260
0x9cce1f8
0x9cce138
0x9cce0c8
0x9cce060
0x9cce008
And the next:
__executable_start: 0x8048000
backtrace:
0x8db6628
0x8db62b8
0x8db6260
0x8db61f8
0x8db6138
0x8db60c8
0x8db6060
0x8db6008
And so on.
Upvotes: 3
Views: 3431
Reputation: 239011
You can use the dl_iterate_phdr()
on Linux to determine the load address of each dynamically loaded object:
#define _GNU_SOURCE
#include <stdio.h>
#include <link.h>
int callback(struct dl_phdr_info *info, size_t size, void *data)
{
printf("%s @ %#lx\n", info->dlpi_name, (unsigned long)info->dlpi_addr);
return 0;
}
int main()
{
dl_iterate_phdr(&callback, NULL);
return 0;
}
Upvotes: 2