加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

如何使用ptrace(linux,x86 / x86_64)获得“回溯”(如gdb)

发布时间:2020-12-14 00:51:39 所属栏目:Linux 来源:网络整理
导读:我想像gdb那样获得类似backtrace的输出.但是我想直接通过ptrace()来做这件事.我的平台是 Linux,x86;以及后来的x86_64. 现在我只想从堆栈中读取返回地址,而不转换为符号名称. 因此,对于测试程序,通过gcc-4.5在-O0模式下编译: int g() { kill(getpid(),SIGALR
我想像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;
    return 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:是的,这也非常像backtrace(3) libc function的想法,但我想通过ptrace在外部做到这一点.

解决方法

osgx发布的示例仅适用于使用帧指针的代码. GCC通过优化生成的x86_64代码没有. x86上的内核vdso代码至少在某些处理器上不使用帧指针. GCC 4.6(带优化)也不在x86模式下使用帧指针.

所有上述内容相结合,使“通过帧指针进行堆栈爬行”非常不可靠.

您可以使用libunwind(它支持local(进程内)和global(进程外通过ptrace)展开).

或者你必须重新实现libunwind的很大一部分.

Example使用libunwind通过ptrace获取回溯.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读