是否可以将addr2line与使用发布优化参数编译的应用程序一起使用

Is it possible to use addr2line with application compiled with release optimization arguments?

本文关键字:优化 参数 编译 一起 应用程序 布优化 addr2line 是否      更新时间:2023-10-16

所以我有一个回溯

Exit with signal 11 at 2013-12-28_14:28:58.000000
/opt/s3ds/App(_Z7handlers+0x52) [0x5de322]
/lib/libc.so.6(+0x32230) [0x7f6ab9b3a230]
/opt/s3ds/App(_ZN17Service17Controller5frameERKf+0x505) [0x5a6b85]
/opt/s3ds/App(_ZN17Service15Cloud10updateEf+0x1de) [0x58642e]
/opt/s3ds/App(_ZN17Manager6updateEf+0x21b) [0x59194b]
/opt/s3ds/App(_ZN7Manager3runEv+0xd2) [0x604fa2]
/opt/s3ds/App() [0x62bfea]
/lib/libpthread.so.0(+0x68ca) [0x7f6abb0048ca]
/lib/libc.so.6(clone+0x6d) [0x7f6ab9bd7b6d]

我已经用下一个参数编译了我的应用程序:

-std=c++11 -fpermissive -m64 -g -rdynamic -mtune=native -flto -O3

因此,它是一个包含一些最少调试信息的发布版本。

我想知道是否可以使用addr2line从这样优化的构建中获得任何行号?

我尝试了这里显示的例子,但我得到了??:0,比如:

$ addr2line -e ./App 0x62bfea
??:0

对于CCD_ 2中的所有地址。我知道从Service::Controller::frameManager::run(甚至可能是lambda/opt/s3ds/App() [0x62bfea])的跟踪中的函数应该在我的应用程序代码中(而不是在某个库中)。

那么,有可能获得生产优化代码的行号吗?是否需要额外的编译器权限才能获得它们?

这可能是可能的,但可能意义不大。

您必须明白,优化的目标是更改代码以使其更好(通过某种度量);而改变意味着所得到的代码可能在之后没有被有意义地映射到源代码。

一些例子:

  • Dead Code Elimination等将删除现有代码,这主要影响在给定源行放置断点的尝试,因为该行可能没有代码
  • Common Sub Expression Elimination将突然创建新的临时变量,以便只计算一次子表达式;这些子表达式最初可能出现在源代码中的多个表达式中,因此新指令属于多行。。。或者根本没有
  • 与原始源代码相比,不变提升或循环旋转将改变表达式的计算顺序,因此您可能会看到在第3行执行的代码,然后是第6行,然后是4、5、7
  • 循环展开将多次复制/粘贴循环的正文

当然,这些都是函数的本地,你还必须考虑

  • 函数内联将在调用站点复制粘贴函数的正文
  • 函数合并将采用两个不同的函数并删除其中一个,将其调用转发给另一个(当然,因为它们具有相同的行为)

毕竟,从源代码的角度来尝试和推理有意义吗?不,不是真的。当然,我甚至没有考虑到这样一个事实,即所有这些转换都发生在中间表示上,并且汇编代码的最终发布将进一步扰乱事物(是的,强度降低!)。

老实说,即使addr2line给你一些线索,我也会怀疑它的结果。。。那么问这个问题有什么意义呢?

我不确定。通常,当函数是您自己代码的一部分时(在您的示例中,情况似乎就是这样),rdynamic开关应该足够了

你试过用-fno-inline-functions -fno-inline-functions-called-once -fno-optimize-sibling-calls编译吗?它在分析优化程序时非常有用。也许它也可以帮助解决你的问题。

(旁注:使用-C开关调用addr2line会激活去映射,建议您使用C++。)