Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]日志文件中打印出来的栈信息不能使用addr2line识别 #381

Open
hnwyllmm opened this issue Apr 18, 2024 · 2 comments
Open
Labels
bug Something isn't working good first issue Good for newcomers help wanted Needs help from a contributor

Comments

@hnwyllmm
Copy link
Collaborator

hnwyllmm commented Apr 18, 2024

Describe the bug
A clear and concise description of what the bug is.

为了方便调试,日志中可以增加 lbt() 来打印调用栈,日志中会将栈的各个Frame地址打印出来。我们期望可以直接使用addr2line工具查看调用栈信息。但是当前的栈信息不能使用addr2line查看,得到的结果中文件名和行号是问号和0。

导致无法查看符号的原因是程序在运行时会动态调整程序基址,导致每次程序运行的得到的栈信息地址会变化,也不能使用addr2line识别。

解决方法:

  1. 在编译时增加 -no-pie,让程序不做重定位(不推荐)
  2. 在输出栈信息时,自动减去起始偏移信息

Environment
Environment Details sometimes important

  • OS Version: ubuntu 22.04
  • CPU Arch(x86/arm): x86
  • Compiler: gcc 12
  • Others:

Additional context
Add any other context about the problem here.

日志示例:

[2024-04-18 15:26:42.993921 pid:1577569 tid:7f62c9dac7c0 ctx:0 DEBUG: unlock@mutex.cpp:272] >> debug unlock 0x7f62c4a44b70, lbt=0x7f62ca352c0e 0x44a9af 0x77c6d1 0x58fb34 0x58c16f 0x51fecd 0x51fd0b 0x5293eb 0x66a6d0 0x6742a6 0x673fce 0x673c39 0x674b3f 0x66abdd 0x66a7e3 0x65b064 0x6596bb 0x65f97c 0x5a339a 0x596a37 0x5a0c5d 0x5a0ae3 0x5a092a 0x5be359 0x5b0524 0x599d65 0x596d50 0x420807 0x4afe1f 0x4a8c0b 0x484416 0x484f31 0x48586f 0x495d51 0x4b0de6 0x4a9d4d 0x494373 0x42b73a 0x427e9a 0x7f62c9ddad90 0x7f62c9ddae40 0x4125d5

addr2line工具使用:

addr2line -pCfe observer 0x44a9af 0x77c6d1 0x58fb34 0x58c16f

参考资料:https://stackoverflow.com/questions/47778099/what-is-no-pie-used-for

@hnwyllmm hnwyllmm added bug Something isn't working help wanted Needs help from a contributor labels Apr 18, 2024
@hnwyllmm
Copy link
Collaborator Author

减去偏移量的做法更通用,不需要增加编译选项,对普通的应用程序来说更安全。
这个偏移量是Linux系统在加载二进制文件,比如动态库,可执行文件时,会根据ASLR的值,随机生成的。这个偏移量是在运行时确定的,所以我们可以通过读取/proc/self/maps文件,获取到这个偏移量,然后减去这个偏移量,就可以得到真正的地址。
获取偏移量的代码,可以参考OceanBaseget_rel_offset@ob_backtrace.cpp,大致逻辑是遍历/proc/self/maps文件,找到当前函数的地址所在的区间,这个区间的起始地址,就是偏移量。

@hnwyllmm hnwyllmm added the good first issue Good for newcomers label May 21, 2024
@hnwyllmm
Copy link
Collaborator Author

这里讲解了进程内存布局,可以帮助理解:
https://stackoverflow.com/questions/1401359/understanding-linux-proc-pid-maps-or-proc-self-maps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers help wanted Needs help from a contributor
Projects
None yet
Development

No branches or pull requests

1 participant