strace 도구 고장 검사 5 가지 간단 한 방법

strace 도구 고장 검사 5 가지 간단 한 방법
본문 은 strace 를 사용 하여 문 제 를 해결 하 는 5 가지 간단 한 방법 에서 기원 되 었 다. 
strace 는 실행 가능 한 프로그램의 시스템 호출(system call)을 추적 하 는 매우 간단 한 도구 입 니 다.가장 간단 한 사용 은 실행 가능 한 프로그램 이 실 행 될 때의 전체 생명 주 기 를 추적 하고 모든 시스템 에서 호출 된 이름,파라미터 와 반환 값 을 출력 하 는 것 이다.  하지만 더 많은 일 을 할 수 있다.
  • 시스템 호출 또는 시스템 호출 그룹 을 기반 으로
  • 을 걸 러 낼 수 있 습 니 다.
  • 은 시스템 호출 횟수,소요 시간 및 성공 과 실패 횟수 를 계산 하여 시스템 호출 의 사용
  • 을 설명 할 수 있다.
  • 프로 세 스에 보 내 는 신호(signal)
  • 을 추적 할 수 있 습 니 다.
  • 프로 세 스 id(pid)번 호 를 통 해 실행 중인 프로 세 스에
  • 에 가입 할 수 있 습 니 다.
    어떻게 사용 합 니까?
    여 기 는 strace 를 어떻게 사용 하 는 지 간단하게 설명 할 뿐 이에 대해 깊이 분석 할 생각 은 없다.
  • 프로그램 이 시 작 될 때 어떤 프로필 을 읽 었 는 지 찾 았 을 때 설정 파일 을 어떻게 수정 하 든 프로그램 이 당신 의 생각 대로 실행 되 지 않 았 다 는 것 을 알 게 되 었 습 니 다.이것 은 무슨 이유 입 니까?간단 하지만 무시 하기 쉬 운 고려 는 프로그램 이 시 작 될 때 읽 을 프로필 을 읽 었 습 니까?아래 의 예 를 보면
     $ strace php 2>&1 | grep php.ini          open("/usr/local/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory)          open("/usr/local/lib/php.ini", O_RDONLY) = 4          lstat64("/usr/local/lib/php.ini", {st_mode=S_IFLNK|0777, st_size=27,        ...}) = 0          readlink("/usr/local/lib/php.ini", "/usr/local/Zend/etc/php.ini",        4096) = 27          lstat64("/usr/local/Zend/etc/php.ini", {st_mode=S_IFREG|0664,st_size=40971, ...}) = 0    
    
    상기 phop 프로그램 은 /usr/local/bin/ 에서 php.ini 파일 을 먼저 읽 습 니 다.아마도 당신 이 생각 하 는 것 이 아 닐 것 입 니 다.먼저 /usr/local/lib/ 에서 읽 습 니 다.상기 출력 이 많 을 것 입 니 다.우 리 는 심지어 매개 변 수 를 통 해 우리 가 관심 을 가 지 는 시스템 호출 만 추적 할 수 있 습 니 다.예 를 들 어 다음 과 같 습 니 다.
      $ strace -e open php 2>&1 | grep php.ini           open("/usr/local/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or         directory)           open("/usr/local/lib/php.ini", O_RDONLY) = 4  
    
  • 왜 프로그램 이 내 파일 을 열지 않 았 습 니까?실행 가능 한 프로그램 마다 파일 을 읽 을 때 권한 이 부족 하면 거부 당 합 니 다.만약 에 파일 을 찾 지 못 한다 면 오류 가 발생 하지 않 을 것 입 니 다.프로그램 에서 오류 처 리 를 설정 하지 않 는 한 So.만약 에 프로그램 이 제 파일 을 읽 지 않 았 다 면 저 는 어떻게 추적 해 야 합 니까?
     $ strace -e open,access 2>&1 |grep your-filename
    
    open()과 access()시스템 이 호출 한 출력 결 과 를 확인 하고 어떤 원인 인지 알 아 보 세 요.
  • 프로 세 스 는 지금 무엇 을 하고 있 습 니까?프로그램 이 갑자기 CPU 를 많이 소모 하거나 프로그램 이 끊 긴 것 같 습 니 다.프로 세 스 의 pid 번 호 를 통 해 현재 무엇 을 하고 있 는 지 알 아 보 겠 습 니 다.
     root@dev:~# strace -p 15427           Process 15427 attached - interrupt to quit           futex(0x402f4900, FUTEX_WAIT, 2, NULL           Process 15427 detached  
    
    추적 을 통 해 프로그램 이 끊 긴 이 유 는 futex()를 호출 하고 있 기 때 문 입 니 다.
  • 프로그램의 시간 이 어디 에 쓰 이 는 지 항상 프로그램 이 원 하 는 대로 일 할 수 있 기 를 바 랍 니 다.또한 정확 한 시간 에 정확 한 일 을 할 수 있 기 를 바 랍 니 다.심지어 그것 이 가장 좋 기 를 바 랍 니 다.가능 한 한 프로그램 이 실행 되 는 주기 에 소모 되 는 90%이상 의 자원 은 간단 한 기다 림 이 아니 라 해 야 할 일 을 하고 있 습 니 다.아마도 아래 의 이 명령 은 당신 에 게 도움 이 될 것 입 니 다.
     root@dev:~# strace -c -p 11084
     Process 11084 attached - interrupt to quit
     Process 11084 detached
     % time     seconds  usecs/call     calls    errors syscall
     ------ ----------- ----------- --------- --------- ----------------
      94.59    0.001014          48        21           select
       2.89    0.000031           1        21           getppid
       2.52    0.000027           1        21           time
     ------ ----------- ----------- --------- --------- ----------------
     100.00    0.001072                    63           total
     root@dev:~# 
    
    만약 당신 이 추적 하 는 백 엔 드 데 몬 이 라면 위의 명령 을 통 해 일정 시간 추적 한 다음 에 ctrl+c 을 누 르 면 strace 는 얻 은 정보 에 따라 위의 결 과 를 설명 할 수 있 습 니 다.상기 예 는 현재 프로 세 스(postmaster)가 select() 함 수 를 기다 리 는 데 가장 걸 리 는 시간 을 설명 합 니 다.select 함 수 를 호출 할 때마다 getpid 함수 와 time 함 수 를 호출 합 니 다.백 엔 드 데 몬 이 아니라면 strace 는 프로 세 스 의 시작 과 끝 을 추적 할 수 있 습 니 다.아래 와 같이:
     root@dev:~# strace -c >/dev/null ls
     % time     seconds  usecs/call     calls    errors syscall
     ------ ----------- ----------- --------- --------- ----------------
      23.62    0.000205         103         2           getdents64
      18.78    0.000163          15        11         1 open
      15.09    0.000131          19         7           read
      12.79    0.000111           7        16           old_mmap
       7.03    0.000061           6        11           close
       4.84    0.000042          11         4           munmap
       4.84    0.000042          11         4           mmap2
       4.03    0.000035           6         6         6 access
       3.80    0.000033           3        11           fstat64
       1.38    0.000012           3         4           brk
       0.92    0.000008           3         3         3 ioctl
       0.69    0.000006           6         1           uname
       0.58    0.000005           5         1           set_thread_area
       0.35    0.000003           3         1           write
       0.35    0.000003           3         1           rt_sigaction
       0.35    0.000003           3         1           fcntl64
       0.23    0.000002           2         1           getrlimit
       0.23    0.000002           2         1           set_tid_address
       0.12    0.000001           1         1           rt_sigprocmask
     ------ ----------- ----------- --------- --------- ----------------
     100.00    0.000868                    87        10 total
    
    ls 프로그램 은 디 렉 터 리 항목 을 읽 는 데 대부분의 시간 을 쓴다.
  • 왜 나 는 서버 에 연결 할 수 없 습 니까?디 버 깅 프로 세 스 가 서버 에 연결 되 지 못 하 는 것 은 고통스러운 일이 다.왜냐하면 원인 이 매우 많 기 때문이다.예 를 들 어 DNS 가 효력 을 잃 었 고 연결 이 끊 겼 으 며 서버 가 이상 한 데 이 터 를 되 돌려 주 었 고 서버 자체 가 이상 하 다 는 등 이다.일반 네트워크 디 버 깅 에 있어 서 많은 사람들 이 또 다른 아주 좋 은 도구 인 tcpdump 를 생각 할 것 이다.그러나 매개 변수 가 너무 많 고 수백 개의 연결 프로 세 스 에서 프로 세 스 가 왜 연결 되 지 않 는 지 찾 는 것 은 매우 힘 든 작업 일 것 입 니 다.strace 는 사실 이런 상황 에서 당신 을 도 울 수 있 습 니 다.시스템 호출 과 관련 된 데 이 터 를 출력 하 는 것 만으로 도 우리 의 주 의 를 더욱 집중 시 킬 수 있 습 니 다.아래 와 같이:
     $ strace -e poll,select,connect,recvfrom,sendto nc www.news.com 80
     sendto(3, "\24\0\0\0\26\0\1\3\255\373NH\0\0\0\0\0\0\0\0", 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
     connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
     connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
     connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, 28) = 0
     poll([{fd=3, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1
     sendto(3, "\213\321\1\0\0\1\0\0\0\0\0\0\3www\4news\3com\0\0\34\0\1", 30, MSG_NOSIGNAL, NULL, 0) = 30
     poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 5000) = 1
     recvfrom(3, "\213\321\201\200\0\1\0\1\0\1\0\0\3www\4news\3com\0\0\34\0\1\300\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, [16]) = 153
     connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, 28) = 0
     poll([{fd=3, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1
     sendto(3, "k\374\1\0\0\1\0\0\0\0\0\0\3www\4news\3com\0\0\1\0\1", 30, MSG_NOSIGNAL, NULL, 0) = 30
     poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 5000) = 1
     recvfrom(3, "k\374\201\200\0\1\0\2\0\0\0\0\3www\4news\3com\0\0\1\0\1\300\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, [16]) = 106
     connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, 28) = 0
     poll([{fd=3, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1
     sendto(3, "\\\2\1\0\0\1\0\0\0\0\0\0\3www\4news\3com\0\0\1\0\1", 30, MSG_NOSIGNAL, NULL, 0) = 30
     poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 5000) = 1
     recvfrom(3, "\\\2\201\200\0\1\0\2\0\0\0\0\3www\4news\3com\0\0\1\0\1\300\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, [16]) = 106
     connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("216.239.122.102")}, 16) = -1 EINPROGRESS (Operation now in progress)
     select(4, NULL, [3], NULL, NULL)        = 1 (out [3])
    
    그러면 상기 출력 은 프로 세 스 가 무슨 일이 일 어 났 는 지 설명 합 니까?이 프로 세 스 가 /var/run/nscd/socket 연결 을 시도 하 는 것 을 알 았 습 니까?이 는 nc 프로그램 이 먼저 NSCD-Name Service Cache Daemon-NIS,YP,LDAP 또는 디 렉 터 리 프로 토 콜 과 관련 된 도 메 인 이름 조회 설정 을 설정 하 는 데 사 용 됩 니 다.상기 예 에서 연결 이 실 패 했 습 니 다.다음 프로 세 스 가 DNS 에 연결 되 기 시작 했다 는 점 은 sin_port=htons(53) 출력 에서 알 수 있다.이 어 sendto() 호출 을 통 해 www.news.com 메 시 지 를 포함 한 DNS 패 키 지 를 보 낸 것 을 볼 수 있다.그리고 돌아 온 패키지 데 이 터 를 읽 습 니 다.무슨 이유 인지 세 번 이나 시 도 했 습 니 다.가능 한 이 유 는 www.news.com 이 CNAME 기록 이기 때문이다.여러 차례 요청 한 것 은 아마도 nc 프로그램 처리 의 한 방식 일 것 이다.마지막 으로 connect() 작업 을 시 작 했 습 니 다.이 작업 의 반환 결 과 는 EINPROGRESS 입 니 다.이것 은 이 연결 이 비 차단 식 이라는 것 을 의미 합 니 다.nc 이 계속 되 기 를 원 하기 때문에 select() 을 호출 했 습 니 다.read,write 을 strace 추적 시스템 호출 목록 에 추가 하면 다음 과 같은 결 과 를 볼 수 있 습 니 다.
     read(0, "test
    ", 1024) = 5 write(3, "test
    ", 5) = 5 poll([{fd=3, events=POLLIN, revents=POLLIN}, {fd=0, events=POLLIN}], 2, -1) = 1 read(3, "
    은'test'+표준 에서 입력 한 줄 의 정 보 를 읽 고 네트워크 연결 에 기록 한 다음 에 poll 을 호출 하여 응답 을 기다 린 다음 에 네트워크 피드백 정 보 를 읽 고 표준 출력 에 기록 합 니 다.
  • 좋은 웹페이지 즐겨찾기