为什么在使用 ptrace 跟踪进程时 WIFSIGNALED(status) 无法检测到信号?

发布于 2024-12-05 08:07:09 字数 1753 浏览 1 评论 0原文

我正在使用 ptrace 来跟踪子进程。当子进程正常退出时,它工作得很好。但如果异常退出,程序就会进入无限循环,尽管使用了宏 WIFSIGNALED(&status)。这是示例子进程:

try.c

int main()
   {
      int a=5/0;
   }

这是跟踪程序

#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h>
#include <sys/syscall.h>   /* For SYS_write etc */
#include <sys/reg.h>
#include <signal.h>
int main()
{   
    pid_t child;
    long orig_eax, eax;
    int status,insyscall = 0;
    child = fork();
    if(child == 0)
    {
            ptrace(PTRACE_TRACEME, 0, NULL, NULL);
            execl("./try", "try", NULL);
    }
    else
    {
        siginfo_t sig;
        memset(&sig,0,sizeof(siginfo_t));
        while(1)
        {
            wait(&status);
            if(WIFSIGNALED(status))
            {
                printf("Exiting due to signal\n");
                exit(0);
            }
            if(WIFEXITED(status))
                break;
            orig_eax = ptrace(PTRACE_PEEKUSER,child, 4 * ORIG_EAX, NULL);
            printf("system call number=%ld\n",orig_eax);
            if(insyscall == 0)
            {
                      /* Syscall entry */
                      insyscall = 1;
                      printf("In sys call\n");
            }
            else 
            {
               /* Syscall exit */
                 eax = ptrace(PTRACE_PEEKUSER,child, 4 * EAX, NULL);
                 printf("System call returned with %ld\n", eax);
                 insyscall = 0;
             }
            ptrace(PTRACE_SYSCALL,child, NULL, NULL);
        }
    }
    return 0;
}

为什么没有检测到信号,而在不使用 ptrace 时该信号可以正常工作?

I am using ptrace to trace a child process. It works perfectly well when the child process exit normally. But if it exit abnormally, the program get into an infinite loop in-spite of using the macro WIFSIGNALED(&status). Here is sample child process:

try.c

int main()
   {
      int a=5/0;
   }

And here is tracing program

#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h>
#include <sys/syscall.h>   /* For SYS_write etc */
#include <sys/reg.h>
#include <signal.h>
int main()
{   
    pid_t child;
    long orig_eax, eax;
    int status,insyscall = 0;
    child = fork();
    if(child == 0)
    {
            ptrace(PTRACE_TRACEME, 0, NULL, NULL);
            execl("./try", "try", NULL);
    }
    else
    {
        siginfo_t sig;
        memset(&sig,0,sizeof(siginfo_t));
        while(1)
        {
            wait(&status);
            if(WIFSIGNALED(status))
            {
                printf("Exiting due to signal\n");
                exit(0);
            }
            if(WIFEXITED(status))
                break;
            orig_eax = ptrace(PTRACE_PEEKUSER,child, 4 * ORIG_EAX, NULL);
            printf("system call number=%ld\n",orig_eax);
            if(insyscall == 0)
            {
                      /* Syscall entry */
                      insyscall = 1;
                      printf("In sys call\n");
            }
            else 
            {
               /* Syscall exit */
                 eax = ptrace(PTRACE_PEEKUSER,child, 4 * EAX, NULL);
                 printf("System call returned with %ld\n", eax);
                 insyscall = 0;
             }
            ptrace(PTRACE_SYSCALL,child, NULL, NULL);
        }
    }
    return 0;
}

Why the signal is not being detected which otherwise works when ptrace is not used?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

唐婉 2024-12-12 08:07:09

当您跟踪进程时,等待将返回任何状态更改。其中之一是当进程即将接收信号时。您的等待将在信号传递给孩子之前返回。如果您希望发生这种情况,您需要使用 PTRACE_CONT 来允许将信号传递给子级。

为什么会这样呢?请记住,ptrace 的主要目的是用于实现调试器。如果您没有机会拦截诸如 SIGSEGV 之类的信号,则调试器无法在进程被终止之前停止并让您检查 seg 错误。

When you ptrace a process, wait will return for any state change. One of those is when the process is about to receive a signal. Your wait will return before the signal is delivered to the child. You need to use PTRACE_CONT to allow the signal to be delivered to the child, if that's what you want to happen.

Why does it work this way? Well remember, ptrace's main purpose is to be used in implementing debuggers. If you didn't get a chance to intercept signals such as SIGSEGV, the debugger couldn't stop and let you examine the seg fault before the process was torn down.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文