获取Linux可执行文件加载地址(__builtin_return_address和addr2line) [英] Get linux executable load address (__builtin_return_address and addr2line)

查看:776
本文介绍了获取Linux可执行文件加载地址(__builtin_return_address和addr2line)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一些代码,为每个内存分配存储一个回溯.然后,我将这些列表写到文件中以进行离线分析.在win32中,我使用_AddressOfReturnAddress,然后手动创建回溯.由于每次运行的地址都是随机的,因此我使用GetModuleInformationlpBaseOfDll来获取基地址.这在没有FPO的x86上效果很好,对我来说足够了.然后,我使用win32 API加载PDB,以将地址转换为函数名称.

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.

我将如何在Linux上执行此操作?我当前的方法是脱机使用__builtin_return_address(x)addr2line以获得相同的结果.问题在于,每次运行都将地址随机化,因此addr2line无法理解它们. __executable_start无效,因为它每次运行都返回相同的值.有什么方法可以在运行时获取可执行文件的基地址吗?

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

然后是下一个:

__executable_start: 0x8048000
backtrace:
0x8db6628
0x8db62b8
0x8db6260
0x8db61f8
0x8db6138
0x8db60c8
0x8db6060
0x8db6008

以此类推.

推荐答案

您可以在Linux上使用dl_iterate_phdr()确定每个动态加载的对象的加载地址:

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

这篇关于获取Linux可执行文件加载地址(__builtin_return_address和addr2line)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆