Get linux executable load address (__builtin_return_address and addr2line)

笑着哭i 提交于 2019-12-07 19:55:52

问题


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.


回答1:


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;
}


来源:https://stackoverflow.com/questions/17389968/get-linux-executable-load-address-builtin-return-address-and-addr2line

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!