科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道使用Ptrace跟踪进程收到的异常信号

使用Ptrace跟踪进程收到的异常信号

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

我们在调试程序的时候,程序有时会出现进程收到SIGSEGV信号,异常退出。如果使用GDB,通过拦截该信号,并打印堆栈来实现,但在嵌入式的环境里,需要在嵌入式设备注入gdb server。

作者:korn 来源:赛迪网 2008年6月27日

关键字: 命令行 Linux 技巧

  • 评论
  • 分享微博
  • 分享邮件

最初的想法,我们在调试程序的时候,程序有时会出现进程收到SIGSEGV信号,异常退出。如果使用GDB,通过拦截该信号,并打印堆栈来实现,但在嵌入式的环境里,需要在嵌入式设备注入gdb server,来进行调试,比较麻烦。

我的一个想法,能够直接写一个程序,跑在设备里,拦截到特殊信号后,就打印堆栈呢?

有两个难点:

1、 如何实现信号的拦截,发现信号后,开始打印堆栈。

2、 打印堆栈,最好能够连带调用函数时的参数值。

信号的拦截

一开始我想到了使用ptrace,因为gdb是以它为基础的,gdb能够做到,它也能够做到。但通过查资料,ptrace主要是拦截系统调用,或者进行单步跟踪,没有谈及如何跟踪信号。那么在主程序,fork出子程序后,注册一个信号处理函数,在信号处理函数中打印出堆栈是否可行呢?

经过测试发现,在exec之后,起来的进程会冲掉原来该子进程的代码段,从而注册的信号处理事件失效。

这条路是否到头了呢?

继续想到,既然exec会冲掉原来的代码段,那么我是否可以采用将程序起来后,通过黑客的手段注入代码,并执行来实现呢?

理论上来讲,应该可行,但难度比较大。

峰回路转……

在linux内核分析的时候,发现这么一段话:

在do_signal中,首先它检查current接收进程是否正受某一进程的监控:既然这样,do_signal就调用notify_parent()和schedule让监控进程知道进行的信号处理。

这说明signal的信号处理肯定是能够被监控的。

通过google发现,strace是能够拦截signal的。我通过分析strace的源代码,发现了strace是如何监控信号。

Child=fork()

If(child==0)

{

ptrace(PTRACE_TRACEME, 0, NULL, NULL);

Exec //执行待监控的进程

}

Else

{

pid = wait4(-1, &status, wait4_options, cflag ? &ru : NULL);

if (WIFSIGNALED(status)) //检查是否因为信号挂起

if (WIFEXITED(status))

if (!WIFSTOPPED(status))

if (WSTOPSIG(status) != SIGTRAP) //注意SIGSEGC信号就是通过这里处理的。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章