2016-07-14 3 views
0

bash 프롬프트로 돌아 가지 않는 프로그램을 디버깅 하려다가 strace을 사용하고 PID를주었습니다. 이 프로그램은 바이너리 파일이며 소스 코드가 없습니다. strace에 따르면 -1 EBADF (Bad file descriptor)이 있습니다. 그러나 어떤 파일에 문제가 있는지 알 수 없습니다.strace가 잘못된 파일 설명자를보고합니다.

아래에서 볼 수 있듯이 strace 출구이므로 lsof -p <PID>에는 아무런 결과가 없습니다.

read(5, "80\0\0\0\00078", 8)   = 8 
read(5, "prf-exit\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 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, "\0\0\0\0", 4)     = 4 
write(5, "\0\0\0\0", 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\0", 6)     = 6 
write(9, "15 NORMAL_EXITING\0", 19) = 19 
read(9, "\0", 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, "\0\0\0\0", 4)     = 4 
write(5, "\0\0\0\0", 4)     = 4 
read(5, "\0\0\0\0", 4)     = 4 
write(5, "\0\0\0\0", 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, "\35\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0\1\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 64) = 64 
close(5)        = 0 
close(4)        = 0 
exit_group(0)       = ? 
Process 29588 detached 
[[email protected] ~]# lsof -p 29588 
[[email protected] ~]# 

누락 된 파일/오류가있는 파일은 어떻게 검색합니까?

+1

이것은 반드시 버그 일 필요는 없습니다. FD가 닫혀 있는지 확인하려면 먼저 열려 있는지 확인해야합니다. EBADF를 닫으면 EBADF는 무시됩니다. –

+0

... 하위 프로세스를 시작할 때 파이썬의'close_fds' 플래그를 사용한다면, 예를 들어, FD 번호 3-255를 실행하고 열려 있는지 여부에 관계없이 모든 것을 닫으려고합니다. . –

+0

BTW에서는 strace 대신 sysdig를 사용하는 것을 고려해보십시오. 특히, 과거에 있었던 것처럼 프로세스의 FD 테이블을 덤프하도록 요청할 수 있습니다 (모든 프로세스 - 시스템 전체 모니터링). 시각*. –

답변

4

당신은 두 번 같은 파일 기술자를 닫는 것 : 파일 기술자 번호가 파일에 매핑되지 않은 경우

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

EBADF가 발생합니다. 따라서 정의상, 입니다. 문제가되는 파일이 없습니다.


솔직히 말해서 이것은 버그가 아니며 찾고있는 버그가 아닙니다. FD를 닫으려고 시도하는 것은 완전히 일반적인 행동입니다. 비록 파일을 열지 못했다 할지라도 FD를 닫으려고 시도합니다. 파일 설명자가 다른 방법을 통해 열려 있는지 확인한 다음 닫는 것보다 효율적입니다 조건부.

+0

* FD 5는 이전에'10.10.10.251'에 연결된 소켓에 매핑되었습니다. * 어떻게 결론을 냈습니까? –

+0

오독으로, 솔직하게 - 가까이서 보면 FD 9였습니다. –

1

처음으로 프로그램을 닫은 후 다른 스레드가 open()을 호출하고 같은 파일 설명자를 부여 할 수 있기 때문에 프로그램이 다중 스레드 인 경우 파일 설명자를 두 번 이상 닫는 것이 좋습니다. 다른 파일을 참조); 이 시점에서 스레드에서 두 번째 닫는 호출은 다른 스레드의 파일을 닫습니다. 항상 다음과 같이 사용하십시오 :

닫기 (x); x = -1;

실수로 다시 사용 된 설명자를 닫지 않았는지 확인하십시오.