strace
(或任何其他使用ptrace
系统调用的工具)可能会导致“挂起”的系统调用返回(并带有EINTR
退出代码)。Some system calls return with EINTR if a signal was sent to a
tracee, but delivery was suppressed by the tracer. (This is very typical operation: it is usually done by debuggers on every attach, in order to not introduce a bogus SIGSTOP). As of Linux 3.2.9, the following system calls are affected (this list is likely incomplete): epoll_wait(2), and read(2) from an inotify(7) file descriptor. The usual symptom of this bug is that when you attach to a quiescent process with the command
strace -p <process-ID>
then, instead of the usual and expected one-line output such as
restart_syscall(<... resuming interrupted call ...>_
or
select(6, [5], NULL, [5], NULL_
('_' denotes the cursor position), you observe more than one line. For example:
clock_gettime(CLOCK_MONOTONIC, {15370, 690928118}) = 0 epoll_wait(4,_
What is not visible here is that the process was blocked in epoll_wait(2) before strace(1) has attached to it. Attaching caused epoll_wait(2) to return to user space with the error EINTR. In this particular case, the program reacted to EINTR by checking the current time, and then executing epoll_wait(2) again. (Programs which do not expect such "stray" EINTR errors may behave in an unintended way upon an strace(1) attach.)
很可能strace输出只是减慢了进程,使死锁不太可能发生。我以前见过这种情况,当时使用strace或添加其他调试打印或调试调用时也会发生。
死锁通常在多线程交互中最常见。但在你的情况下,你有多个进程。如果每次strace释放进程,那么我想你打开套接字或套接字握手的方式就是出问题的地方。我认为在套接字上缓冲和阻塞可能会使你陷入进程死锁状态。
类似的问题,但是针对的是多线程进程,在线程之间死锁而不是在不同进程之间死锁:使用strace修复内存挂起问题
很难提供一般性的示例,特别是因为不知道你的不同进程在做什么或是否以某种方式共享资源?我会尝试……
一个需要保护的对象/资源的示例:
一个进程开始对一个对象进行更改(例如向列表/数据库表中添加项目)
另一个进程开始迭代列表/表。
有一个进程迭代循环被混淆并永远不会退出,或者做一些更糟糕的事情,比如写入无效的内存。
对象/资源由互斥锁保护的示例
两个资源问题的经典简单死锁。
~比哲学家就餐问题更简单
一个线程/进程获取对象A上的互斥锁,执行一些工作。
另一个线程/进程获取对象B上的互斥锁,执行一些工作。
同一个线程/进程需要更新对象A,等待A的互斥锁。
原始线程/进程需要访问对象B,等待B的互斥锁。
. . . . . . . . . . . . @ . . . . . . . . . . .
除了风声和风滚草在景象中滚动之外,一片寂静。
死锁。
我只遇到过一次这个问题,它与信号处理有关。这是单线程代码中竞态条件的一个来源。