C++ C++;函数地址——使用dladdr和backtrace()

C++ C++;函数地址——使用dladdr和backtrace(),c++,backtrace,dladdr,C++,Backtrace,Dladdr,我想使用backtrace()并获取用于跟踪的函数地址。我想在运行时存储backtrace()中的函数地址,并在以后使用它进行分析(例如,使用dladdr()加载回函数名、查看调用统计等)。在这样做时,我试图查看类成员函数的静态地址 Alib.so,A.h.: class A { public: void print_addr(); }; A.cpp 如果我多次重新运行main,它会给我相同的地址。 如果我将main.cpp更改为: int main() { A a; a.

我想使用backtrace()并获取用于跟踪的函数地址。我想在运行时存储backtrace()中的函数地址,并在以后使用它进行分析(例如,使用dladdr()加载回函数名、查看调用统计等)。在这样做时,我试图查看类成员函数的静态地址

Alib.so,A.h.:

class A
{
public:
    void print_addr();
};
A.cpp

如果我多次重新运行main,它会给我相同的地址。 如果我将main.cpp更改为:

int main()
{
   A a;
   a.print_addr();
   return 0;
}
每次运行主可执行文件时,即使没有重新编译,输出也是不同的。so或main:

0x7fae48524aa0
我之所以要检查这一点,是因为我想使用backtrace()获取当前堆栈函数的函数信息(地址)以进行跟踪,它的行为非常类似。我尝试在.so库函数中调用backtrace(),并在当前堆栈函数中使用backtrace()和dladdr()获取函数的符号信息。在中打印函数地址与在main中打印函数地址相比,给出了不同的地址。如何使用dladdr()的函数地址获取信息,例如符号名

在.so和main()中是否存在映射到不同类成员函数地址的内容


编辑:重新编写并提供更多代码示例来解释问题。

您更改了源代码并重新编译。所有地址都可能更改。你为什么认为它们应该是一样的?@kirill其实并不需要它们是一样的。但是使用从backtrace()返回的dladdr()中的地址,如果.so不变,我应该期望dladdr(add,info)返回正确的函数名?好像我不能。从两个位置打印两次这个地址。我打赌你会看到同样的数字。我认为func作为类的成员在这里并不重要,所以如果我编写一个main()程序,请运行一些代码并将&a::foo的地址存储到一个文件中。之后,我编写了另一个程序,链接到相同的。因此A::foo驻留的位置。使用存储的地址&A::foo,我可以使用dladdr()加载回符号信息吗?似乎每次我重新运行main时,我都会得到一个不同的地址&a::foo。看来您错误地认为打印地址的位置很重要。事实并非如此。操作系统如何加载程序的规则取决于您构建程序的方式,可能很复杂。若系统在每次运行时将你们的应用加载到不同的地址,那个么并没有什么错。您需要关注这些规则。您更改了源代码并重新编译。所有地址都可能更改。你为什么认为它们应该是一样的?@kirill其实并不需要它们是一样的。但是使用从backtrace()返回的dladdr()中的地址,如果.so不变,我应该期望dladdr(add,info)返回正确的函数名?好像我不能。从两个位置打印两次这个地址。我打赌你会看到同样的数字。我认为func作为类的成员在这里并不重要,所以如果我编写一个main()程序,请运行一些代码并将&a::foo的地址存储到一个文件中。之后,我编写了另一个程序,链接到相同的。因此A::foo驻留的位置。使用存储的地址&A::foo,我可以使用dladdr()加载回符号信息吗?似乎每次我重新运行main时,我都会得到一个不同的地址&a::foo。看来您错误地认为打印地址的位置很重要。事实并非如此。操作系统如何加载程序的规则取决于您构建程序的方式,可能很复杂。若系统在每次运行时将你们的应用加载到不同的地址,那个么并没有什么错。你需要关注这些规则。
0x400870
int main()
{
   A a;
   a.print_addr();
   return 0;
}
0x7fae48524aa0