简体   繁体   English

为什么将SIGINT发送给子进程却什么也不做?

[英]Why SIGINT is send to a child process and does nothing?

I am building a simple debugger for my university class and I have a problem in handling SIGINT. 我正在为我的大学课程构建一个简单的调试器,并且在处理SIGINT时遇到问题。

What I want to do is when the debugger process (from now on PDB) takes a SIGINT signal passes that to the child process (the one that is being actually debugged by PDB). 我想做的是,当调试器进程(从现在开始在PDB上)接收到SIGINT信号时,将其传递给子进程(实际上是由PDB调试的那个进程)。

I am doing this: 我正在这样做:

pid_t childid;

void catch_sigint(int sig)
{
    signal(SIGINT,SIG_DFL);
    kill(childid,sig);
}

int debuger (char *address, parm *vars)
{
    int ignore=1;
    int status;

    childid = fork();
    signal(SIGINT,catch_sigint);
    if(childid==0)
    {
        ptrace(PTRACE_TRACEME,0, NULL,NULL);
        if(execve(address,NULL,NULL)==-1)
        {
            perror("ERROR occured when trying to create program to trace\n");
            exit(1);
        }
    }
    else
    {
        int f_time=1;

        while(1)
        {
            long system_call;

            wait(&status);
            if(WIFEXITED(status))break;
            if(WIFSIGNALED(status))break;

            system_call = ptrace(PTRACE_PEEKUSER,childid, 4 * ORIG_EAX, NULL);

            if(!strcmp(vars->category,"process-control") || !strcmp(vars->category,"all"))      
                ignore = pr_calls(system_call,ignore,limit,childid,vars->mode); //function that takes the system call that is made and prints info about it
            if(!strcmp(vars->category,"file-management") || !strcmp(vars->category,"all"))
                ignore = fl_calls(system_call,ignore,limit,childid,vars->mode);

            if(f_time){ignore=1;f_time=0;}
            ptrace(PTRACE_SYSCALL,childid, NULL, NULL);
        }        
    }
    signal(SIGINT,SIG_DFL);
    return 0;
}

This program runs and forks a child process and execs a program to trace its system calls. 该程序运行并派生一个子进程,并执行一个程序以跟踪其系统调用。 That works fine when it doesn't get any signal. 当它没有任何信号时,它工作正常。

But when in the middle of some tracing I press ctrl+c I expect the child process to stop and PDB to continue and stop (because of this line if(WIFSIGNALED(status))break; . That never happens. The program it traces continues its system calls and prints. 但是当我在进行一些跟踪时,按ctrl + c组合键,我希望子进程停止并且PDB继续并停止(因为这一行if(WIFSIGNALED(status))break;这永远不会发生。它跟踪的程序继续它的系统调用并打印。

The tracing program is that: 跟踪程序是:

#include <stdio.h>

int main(void)
{
    for(;;) printf("HELLO WORLD\n");        
    return 0;
}

That program continues printing HELLO WORLD even after I hit ctrl+c. 即使我按了ctrl + c,该程序仍继续打印HELLO WORLD。

I also observed that the system calls that ptrace gives after ctrl+c are -38 and that the status in wait changes only once after the signal from 1407 (I think is the normal value) to 639 and then back again to 1407 on the next wait. 我还观察到,在ctrl + c之后ptrace给出的系统调用为-38,并且等待状态仅在信号从1407(我认为是正常值)变为639之后再更改一次,然后在下一次又回到1407等待。

So what I am doing wrong in that? 那么我在做什么错呢?

The problem it's on this line: 问题在这条线上:

ptrace(PTRACE_SYSCALL,childid, NULL, NULL);

It has to be like that: 它必须像这样:

ptrace(PTRACE_SYSCALL,childid, NULL, signal_variable);

Where signal_variable is an int declared in global scope so the handler and the debugger can see it. 其中signal_variable是在全局范围内声明的int,以便处理程序和调试器可以看到它。 It has a starting value of 0. 起始值为0。

The signal handler now takes the signal and passes it in this variable and at the next loop when the ptrace orders the tracee program to continue it sends it the signal too. 现在,信号处理程序获取信号并将其传递到此变量中,并在下一个循环中,当ptrace命令tracee程序继续执行时,它也会发送信号。 That happens because when you trace a program the tracee stops execution when it receives a signal and waits further instruction for what to do with the signal from the tracer through ptrace. 发生这种情况的原因是,当您跟踪程序时,跟踪程序在接收到信号时停止执行,并等待进一步的指示,以通过ptrace处理来自跟踪程序的信号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM