Sockets 挂起的进程在连接到strace时恢复
我有一个使用TCP套接字用C编写的网络程序。有时,客户机程序永远挂起,等待来自服务器的输入。具体来说,客户端挂起fd上的select()调用集,该fd用于读取服务器发送的字符 我正在使用strace来了解进程在哪里受阻。但是,有时当我将挂起的客户端进程连接到strace时,它会立即恢复执行并正确退出。并不是所有挂起的进程都表现出这种行为,有些进程即使我将它们附加到strace上,也会卡在select()中。但大多数进程在连接到strace时会恢复执行 我很好奇,当连接到strace时,是什么导致过程恢复。这可能会给我一些线索,让我知道为什么客户端进程会挂起 有什么想法吗?是什么导致挂起的进程在连接到strace时恢复执行 更新: 这是strace在挂起进程上的输出Sockets 挂起的进程在连接到strace时恢复,sockets,linux-kernel,gdb,strace,ptrace,Sockets,Linux Kernel,Gdb,Strace,Ptrace,我有一个使用TCP套接字用C编写的网络程序。有时,客户机程序永远挂起,等待来自服务器的输入。具体来说,客户端挂起fd上的select()调用集,该fd用于读取服务器发送的字符 我正在使用strace来了解进程在哪里受阻。但是,有时当我将挂起的客户端进程连接到strace时,它会立即恢复执行并正确退出。并不是所有挂起的进程都表现出这种行为,有些进程即使我将它们附加到strace上,也会卡在select()中。但大多数进程在连接到strace时会恢复执行 我很好奇,当连接到strace时,是什么导致
> sudo strace -p 25645
Process 25645 attached - interrupt to quit
--- SIGSTOP (Stopped (signal)) @ 0 (0) ---
--- SIGSTOP (Stopped (signal)) @ 0 (0) ---
[ Process PID=25645 runs in 32 bit mode. ]
select(6, [3 5], NULL, NULL, NULL) = 2 (in [3 5])
read(5, "\0", 8192) = 1
write(2, "", 0) = 0
read(3, "====Setup set_oldtempbehaio"..., 8192) = 555
write(1, "====Setup set_oldtempbehaio"..., 555) = 555
select(6, [3 5], NULL, NULL, NULL) = 2 (in [3 5])
read(5, "", 8192) = 0
read(3, "", 8192) = 0
close(5) = 0
kill(25652, SIGKILL) = 0
exit_group(0) = ?
Process 25645 detached
_
_
不仅是select(),而且(同一个程序的)进程在我将它们附加到strace之前会被各种系统调用卡住。在连接到strace后,它们突然恢复。如果我不把它们绑在绳子上,它们就永远挂在那里
更新2:
我了解到strace可以启动以前停止的进程(进程处于T状态)。现在我试图理解为什么这些过程会进入“T”状态,原因是什么。以下是/proc//状态信息:
> cat /proc/12554/status
Name: someone
State: T (stopped)
SleepAVG: 88%
Tgid: 12554
Pid: 12554
PPid: 9754
TracerPid: 0
Uid: 5000 5000 5000 5000
Gid: 48986 48986 48986 48986
FDSize: 256
Groups: 9149 48986
VmPeak: 1992 kB
VmSize: 1964 kB
VmLck: 0 kB
VmHWM: 608 kB
VmRSS: 608 kB
VmData: 156 kB
VmStk: 20 kB
VmExe: 16 kB
VmLib: 1744 kB
VmPTE: 20 kB
Threads: 1
SigQ: 54/73728
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000006
SigCgt: 0000000000004000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
Cpus_allowed: 00000000,00000000,00000000,0000000f
Mems_allowed: 00000000,00000001
strace
使用ptrace
。政府有:
Since attaching sends SIGSTOP and the tracer usually suppresses it,
this may cause a stray EINTR return from the currently executing system
call in the tracee, as described in the "Signal injection and
suppression" section.
您是否看到
select
returnEINTR
?strace
使用ptrace
。政府有:
Since attaching sends SIGSTOP and the tracer usually suppresses it,
this may cause a stray EINTR return from the currently executing system
call in the tracee, as described in the "Signal injection and
suppression" section.
您是否看到
select
returnEINTR
?否,select()正确返回。我用strace输出更新了我的问题。我看到一些其他进程在不同的地方卡住了(connect()、read()…等等)。令人惊讶的是,一旦我将所有这些进程连接到strace,它们就会恢复执行。他们之间唯一的共同点是他们已经运行了一个月(实际上是挂起了)。Linux内核会将不活动(没有I/O)的进程放在一边,永远不会恢复它们吗?我尝试用NICE提高优先级。但是NICE对它们没有影响,只有strace在发挥神奇的作用。我查看了所有这些挂起进程的进程状态。其中一些处于S+状态,一些处于T状态。连接到strace后恢复执行的是处于“T”状态的kill-SIGCONT
也会在“T”状态下启动那些挂起的进程。然而,我不清楚是什么让他们进入“T”状态。内核会在运行很长时间后将进程发送到“T”状态吗?如果没有人及时发出SIGSTOP
信号将进程发送到'T'状态,则'T'状态表示已停止。它可能是由另一个跟踪它的进程引起的(在这种情况下,/proc/pid/status
可能会显示一个非零的TracerPid
),或者是因为它被发送了一个SIGTSTP(通过键入control-Z),或者发送了一个SIGSTOP,或者如果它在后台试图在终端上执行输出或输入,则得到了一个SIGTTOU或SIGTIN。我不认为“t”状态的出现仅仅是因为进程一直在等待。您的select
是否只涉及网络套接字,还是也涉及终端设备?否,select()正确返回。我用strace输出更新了我的问题。我看到一些其他进程在不同的地方卡住了(connect()、read()…等等)。令人惊讶的是,一旦我将所有这些进程连接到strace,它们就会恢复执行。他们之间唯一的共同点是他们已经运行了一个月(实际上是挂起了)。Linux内核会将不活动(没有I/O)的进程放在一边,永远不会恢复它们吗?我尝试用NICE提高优先级。但是NICE对它们没有影响,只有strace在发挥神奇的作用。我查看了所有这些挂起进程的进程状态。其中一些处于S+状态,一些处于T状态。连接到strace后恢复执行的是处于“T”状态的kill-SIGCONT
也会在“T”状态下启动那些挂起的进程。然而,我不清楚是什么让他们进入“T”状态。内核会在运行很长时间后将进程发送到“T”状态吗?如果没有人及时发出SIGSTOP
信号将进程发送到'T'状态,则'T'状态表示已停止。它可能是由另一个跟踪它的进程引起的(在这种情况下,/proc/pid/status
可能会显示一个非零的TracerPid
),或者是因为它被发送了一个SIGTSTP(通过键入control-Z),或者发送了一个SIGSTOP,或者如果它在后台试图在终端上执行输出或输入,则得到了一个SIGTTOU或SIGTIN。我不认为“t”状态的出现仅仅是因为进程一直在等待。您的select
是否仅涉及网络套接字,还是也涉及终端设备?它看起来就像一个处于T状态的进程在连接到strace时将开始执行。如果在执行时退出strace会话,进程将再次移动到T状态。看起来处于T状态的进程在连接到strace时将开始执行。如果在执行时退出strace会话,进程将再次移动到T状态。
Since attaching sends SIGSTOP and the tracer usually suppresses it,
this may cause a stray EINTR return from the currently executing system
call in the tracee, as described in the "Signal injection and
suppression" section.