如何找到导致应用程序在Linux下接收SIGTTIN的代码位置?

时间:2019-05-29 09:53:19

标签: c linux

我的一个c ++应用程序在运行了一段不确定的时间后将挂起,因为它没有终止,因此无法由父进程重新启动。

众所周知,SIGTTIN可以防止通过nohup或使用</dev/null重定向标准输入来挂起程序,但这不能从根本上解决问题。

那么,有人知道如何调试或定位产生SIGTTIN信号的代码的位置吗?

// this is a example, exec command to get SIGTTIN: ./a.out &
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

int main(int argc, char* argv[]) {
        int len;
        char buf[64];

        while(1) {
                len = read(STDIN_FILENO, buf, 64);
                if (len > 0) {
                        write(STDOUT_FILENO, buf, len);
                }
                else {
                        perror("read");
                }
        }
        return 0;
}

2 个答案:

答案 0 :(得分:3)

您在后台执行程序./a.out &来启动程序,但是您的程序从 stdin 读取,因此您有该信号

来自https://www.gnu.org/software/libc/manual/html_node/Job-Control-Signals.html

  

宏:int SIGTTIN

     

进程在作为后台作业运行时无法从用户终端读取。当后台作业中的任何进程尝试从终端读取时,作业中的所有进程都会发送SIGTTIN信号。此信号的默认操作是停止该过程。有关它如何与终端驱动程序交互的更多信息,请参见访问终端。

     

找到产生SIGTTIN信号的代码的位置?

这是 read

答案 1 :(得分:0)

感谢大家的回复。问题已解决。

有时我知道SIGTTIN的原因,但是我无法找到导致错误的代码。例如,该程序不直接使用scanf, read(0, ...), cin, ...系统调用或库函数,当程序较大或使用多个线程时,这些调用或库函数会更加突出。

如何找到导致SIGTTIN的代码位置:

  • 使用ps查询程序的pid(如果需要调试线程,则可以使用ps -eLf来获取tid)。
  • 使用strace -p $(YOUR PID) -e read跟踪程序的系统调用。如有必要,添加-v选项。如果要跟踪进程及其所有子线程以查找代码,请使用Strace -fp $(YOUR PID) -e read。在后台执行程序时,所有read(0, ..., ...)调用都可能导致SIGTTIN。根据{{​​1}}的参数或返回值,可以找到相应的代码位置。