问题描述
我想像gdb那样得到 backtrace
类似的输出。但我想直接通过 ptrace()
来实现。我的平台是Linux,x86;和后来的x86_64。
现在我只想从栈中读取返回地址,而不需要转换为符号名称。
因此,对于测试程序,由 gcc-4.5
编译 -O0
模式:
int g(){
kill(getpid(),SIGALRM);
}
int f(){
int a;
int b;
a = g();
b = a;
返回a + b;
}
int e(){
int c;
c = f();
}
main(){
return e();
}
我将开始一个程序并连接 ptrace
在一开始就测试程序。然后,我会做PTRACE_CONT并等待信号。当测试程序会做自杀时,该信号将被传送到我的程序。在这一刻,我想读取返回地址,他们会像(因为 kill
功能目前处于活动状态):
0x00_some_address_in_g
0x00_some_address_in_f
0x00_some_address_in_e
0x00_some_address_in_main
0x00_some_address_in__libc_start_main
如何使用 ptrace
查找当前停止的测试进程的返回地址?会有帧循环?什么时候应该停止这样的循环?
PS:是的,这也非常类似于在想法中,但我想通过ptrace在外部执行此操作。
osgx发布的示例仅适用于使用帧指针的代码。 GCC使用优化生成的代码 x86_64
没有。至少在一些处理器上, x86
上的内核 vdso
代码不使用帧指针。 GCC 4.6(带优化)不会在 x86
模式下使用帧指针。
以上所有组合
你可以使用 libunwind
(它同时支持本地(正在处理)和(通过ptrace进行的进程外)展开)。
或者您必须重新实现 libunwind
的很大一部分。
通过 ptrace
使用 libunwind
获取回溯。
I want to get a backtrace
-like output as gdb does. But I want to do this via ptrace()
directly. My platform is Linux, x86; and, later x86_64.
Now I want only to read return addresses from the stack, without conversion into symbol names.
So, for test program, compiled in -O0
mode by gcc-4.5
:
int g() {
kill(getpid(),SIGALRM);
}
int f() {
int a;
int b;
a = g();
b = a;
return a+b;
}
int e() {
int c;
c = f();
}
main() {
return e();
}
I will start a my program and connect with ptrace
to test program at very beginning. Then, I will do PTRACE_CONT and will wait for signal. When test program will do a self-kill; the signal will be delivered to my program. At this moment I want to read return addresses, they will be like (because kill
function is active at the moment):
0x00_some_address_in_g
0x00_some_address_in_f
0x00_some_address_in_e
0x00_some_address_in_main
0x00_some_address_in__libc_start_main
How can I find return addresses of currently stopped test process with ptrace
? There will be a loop over frames? When should I stop such loop?
PS: yes, this is also very like backtrace(3)
libc function in idea, but I want to do this externally via ptrace.
The example posted by osgx will work only with code that uses frame pointers. x86_64
code produced by GCC with optimizations doesn't. The kernel vdso
code on x86
doesn't use frame pointers on at least some processors. GCC 4.6 (with optimization) doesn't use frame pointers in x86
mode either.
All of the above combine to make the "stack crawl via frame pointers" exceedingly unreliable.
You can use libunwind
(which supports both local (in-process) and global (out-of-process via ptrace) unwinding).
Or you'll have to re-implement very large portion of libunwind
.
Example of getting backtrace via ptrace
using libunwind
.
这篇关于如何获得“回溯” (如gdb)只使用ptrace(linux,x86 / x86_64)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!