我的一个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;
}
答案 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, ...
系统调用或库函数,当程序较大或使用多个线程时,这些调用或库函数会更加突出。
ps -eLf
来获取tid)。strace -p $(YOUR PID) -e read
跟踪程序的系统调用。如有必要,添加-v
选项。如果要跟踪进程及其所有子线程以查找代码,请使用Strace -fp $(YOUR PID) -e read
。在后台执行程序时,所有read(0, ..., ...)
调用都可能导致SIGTTIN。根据{{1}}的参数或返回值,可以找到相应的代码位置。