strace 报告错误的文件描述符

strace reports bad file descriptor

试图调试我的程序,它没有 return 到 bash 提示符,我使用 strace 并给它 PID。该程序是一个二进制文件,我没有源代码。根据strace,有一个-1 EBADF (Bad file descriptor)。但是不知道是哪个文件有问题

正如您在下方看到的 strace 退出,因此 运行 lsof -p <PID> 没有结果。

read(5, "80[=10=][=10=][=10=][=10=]078", 8)            = 8
read(5, "prf-exit[=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=]"..., 80) = 80
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
fstat(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af316b0f000
write(1, "\n", 1)                       = 1
read(5, "[=10=][=10=][=10=][=10=]", 4)                  = 4
write(5, "[=10=][=10=][=10=][=10=]", 4)                 = 4
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 9
setsockopt(9, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(9, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(9, SOL_SOCKET, SO_SNDBUF, [65536], 4) = 0
setsockopt(9, SOL_SOCKET, SO_RCVBUF, [65536], 4) = 0
fcntl(9, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(9, F_SETFL, O_RDWR)               = 0
connect(9, {sa_family=AF_INET, sin_port=htons(45323), sin_addr=inet_addr("10.10.10.251")}, 16) = 0
write(9, "12345[=10=]", 6)                  = 6
write(9, "15  NORMAL_EXITING[=10=]", 19)    = 19
read(9, "[=10=]", 1)                        = 1
close(9)                                = 0
futex(0x2af31686d9d0, FUTEX_WAIT, 29590, NULL) = 0
futex(0x2af31666c9d0, FUTEX_WAIT, 29589, NULL) = 0
close(6)                                = 0
close(7)                                = 0
read(5, "[=10=][=10=][=10=][=10=]", 4)                  = 4
write(5, "[=10=][=10=][=10=][=10=]", 4)                 = 4
read(5, "[=10=][=10=][=10=][=10=]", 4)                  = 4
write(5, "[=10=][=10=][=10=][=10=]", 4)                 = 4
close(5)                                = 0
close(5)                                = -1 EBADF (Bad file descriptor)
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 5
connect(5, {sa_family=AF_INET, sin_port=htons(49986), sin_addr=inet_addr("172.20.54.10")}, 16) = 0
setsockopt(5, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(5, SOL_TCP, TCP_NODELAY, [1], 4) = 0
write(5, "[=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=]"..., 64) = 64
close(5)                                = 0
close(4)                                = 0
exit_group(0)                           = ?
Process 29588 detached
[root@compute-0-3 ~]# lsof -p 29588
[root@compute-0-3 ~]#

如何搜索 missing/erroneous 文件?

您正在关闭同一个文件描述符两次:

close(5)                                = 0
close(5)                                = -1 EBADF (Bad file descriptor)

EBADF 当文件描述符编号未映射到文件时发生。因此,根据定义, 没有文件有问题。


坦率地说,这不是错误,当然也不是您要查找的错误。尝试关闭 FD 是完全常见的行为,即使您不确定它们是否已打开——这样做比尝试通过其他方式检查文件描述符是否仍处于打开状态并仅将其关闭更有效有条件地。

如果您的程序是多线程的,则多次关闭一个文件描述符是一个非常糟糕的主意,因为在您第一次关闭它之后,另一个线程可以调用 open() 并获得相同的文件描述符 (但指的是不同的文件);此时在您的线程中第二次调用 close 将关闭另一个线程的文件。总是使用类似的东西:

关闭(x); x = -1;

确保您不会无意中关闭重复使用的描述符。