【发布时间】:2009-11-04 14:40:08
【问题描述】:
不知何故,我的用户空间应用程序有时会在收到 EINTR 信号后阻塞。
我用 strace 记录的:
time(NULL) = 1257343042
time(NULL) = 1257343042
rt_sigreturn(0xbff07be4) = -1 EINTR (Interrupted system call)
--- SIGALRM (Alarm clock) @ 0 (0) ---
time(NULL) = 1257343042
futex(0xb7cea80c, 0x80 /* FUTEX_??? */, 2) = ? ERESTARTSYS (To be restarted)
--- SIGUSR1 (User defined signal 1) @ 0 (0) ---
sigreturn() = ? (mask now [ALRM])
futex(0xb7cea80c, 0x80 /* FUTEX_??? */, 2) = ? ERESTARTSYS (To be restarted)
--- SIGWINCH (Window changed) @ 0 (0) ---
futex(0xb7cea80c, 0x80 /* FUTEX_??? */, 2) = ? ERESTARTSYS (To be restarted)
--- SIGTERM (Terminated) @ 0 (0) ---
time(NULL) = 1257343443
time(NULL) = 1257343443
futex(0xb7cea80c, 0x80 /* FUTEX_??? */, 2) = ? ERESTARTSYS (To be restarted)
--- SIGWINCH (Window changed) @ 0 (0) ---
futex(0xb7cea80c, 0x80 /* FUTEX_??? */, 2
我可以捕捉到 EINTR 信号吗?如何重复相关调用,例如写入、读取或选择?即使我使用了处理系统调用的第三方库,我如何才能确定此 EINTR 发生的位置?
为什么我的应用在收到 EINTR 后被完全阻止(请参阅 strace 转储:我发送了一个通常应该处理的 SIGUSR1)?为什么 futex() 会将 ERESTARTSYS 返回到用户空间?
谢谢
【问题讨论】:
-
EINTR 不是信号,而是系统调用被信号中断时返回的错误号。
-
使用
gstack或gdb获取堆栈跟踪,找出程序当前卡在哪里。