为什么strace和ltrace会导致EINTR发生?

约瑟夫·西布尔-恢复莫妮卡

考虑以下程序:

#include <stdio.h>
#include <sys/epoll.h>

int main(void) {
       int epfd = epoll_create1(0);
       struct epoll_event event;
       event.events = EPOLLIN;
       event.data.fd = 0;
       epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &event);
       epoll_wait(epfd, &event, 1, -1);
       perror("epoll_wait");
       return 0;
}

当我自己运行该程序时,调整终端的大小(从而生成SIGWINCH)不会对其执行任何操作,并且会一直等待stdin上的输入。当我在strace或ltrace中运行它时,SIGWINCH导致epoll_wait出现EINTR错误。我对EINTR的理解是,仅当信号在您的代码中调用信号处理程序时才生成它,但是我没有注册它们中的任何一个。我以为strace或ltrace可能已经为我设置了一个,所以我尝试将其显式设置为SIG_IGN,但这仍然没有停止EINTR。为什么会这样呢?

托马斯·迪基

他们使用ptrace(2),其手册页注释

在跟踪过程中,即使信号被忽略,每次发送信号时,跟踪都会停止(一个例外是SIGKILL,它具有通常的效果。)跟踪程序将在其下一次调用waitpid(2)(或相关的“等待”系统调用之一)时得到通知该调用将返回一个状态值,该状态值包含指示示踪停止的原因的信息。停止跟踪时,跟踪器可以使用各种ptrace请求来检查和修改跟踪。然后,跟踪程序使跟踪程序继续进行,可以选择忽略所传递的信号(或什至替代地传递不同的信号)。

然后:

请注意,被抑制的信号仍然会导致系统调用过早返回。在这种情况下,系统调用将重新启动:如果跟踪器使用,则跟踪器将观察被跟踪者以重新执行被中断的系统调用(或restart_syscall(2)使用不同的重新启动机制的一些系统调用的系统调用)PTRACE_SYSCALL甚至poll(2)在信号被抑制后重新启动的系统调用(例如)也无法重新启动;但是,存在内核错误,即使没有将可观察到的信号注入到tracee中,也会导致某些系统调用因EINTR失败

默认情况下,SIGWINCH被忽略,但它听起来好像epoll是类似够pollEINTR是给调用者(甚至与重启)可见。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么curl和wget会导致403被禁止?

为什么digest和digest('hex')会导致不同的输出?

为什么会导致错误?

为什么`time`和`strace -c`不同?

为什么更改构造函数调用的顺序会导致它发生故障?

为什么setNetworkTimeout会导致带有函数的查询发生超时异常?

为什么添加内联汇编注释会导致GCC生成的代码发生如此根本的变化?

为什么边框半径会导致Chrome按钮的样式发生巨大变化?

为什么使用`Checked`属性会导致奇怪的错误,该事件只能在+ =或-=的右侧发生?

为什么修改不相关的变量会导致链接列表发生变化?

为什么创建新的 Pandas 列会导致原始列发生变化?

为什么运行`strace会回显“ hello world”?grep write`显示完整的strace输出?

什么会导致执行失败?接下来发生什么?

为什么此函数会导致['h','-','-','-','-']?

为什么这个条件会导致错误?

为什么此分配会导致NPE?

为什么gcov会导致程序崩溃?

为什么内容会导致列溢出?

为什么矢量会导致细分错误?

为什么网格间隙会导致溢出?

为什么.isHidden会导致分解动画?

屏幕为什么会导致sftp问题?

为什么 ngModel 会导致崩溃?

为什么NPE会导致JVM崩溃?

为什么空变量会导致崩溃

为什么 lock("myLock") 会导致问题?

为什么会导致无限循环?

为什么此类定义会导致NoMethodError?

为什么 runAsync 会导致 Java IllegalStateException?