strace는 어떻게 사용해야합니까?


273

한 동료는 리눅스에서 모든 것이 디버깅에 실패했을 때 마지막 옵션은 strace 를 사용하는 것이라고 나에게 말했다 .

나는이 이상한 도구 뒤에 과학을 배우려고 노력했지만 시스템 관리자 전문가가 아니며 실제로 결과를 얻지 못했습니다.

그래서,

  • 정확히 무엇이며 무엇을합니까?
  • 어떻게 그리고 어떤 경우에 사용해야합니까?
  • 결과를 어떻게 이해하고 처리해야합니까?

간단히, 간단한 단어에서 어떻게이 물건 작동합니까?


2
strace -p <pid>는 당신의 프로그램으로 지금 무슨 일이 일어나고 있는지 말해 줄 것입니다 ..... GDB보다 빠르고 쉽습니다
ernesto

1
나는 개인적 man strace으로 읽기 쉽고 유용하다고 생각합니다. (PS 전에 어제의 strace에 대해 알고하지 아니라 리눅스 전문가 한)
알렉산더 Malakhov

1
"strace는 시스템 호출 추적 프로그램"입니다. 프로그램의 결과로 어떤 커널 함수가 호출되는지 (인수와 함께) 표시됩니다.
Pithikos

답변:


184

Strace 개요
strace는 간단한 디버거로 볼 수 있습니다. 이를 통해 프로그래머 / 사용자는 프로그램이 OS와 상호 작용하는 방식을 빠르게 찾을 수 있습니다. 시스템 호출 및 신호를 모니터링하여이를 수행합니다.

사용
잘 사용하면 소스 코드가 없거나 정말 그것을 통해 이동을 방해하지 않으려는 경우에 대해.
또한 GDB를 열고 싶지는 않지만 외부 상호 작용을 이해하는 데 관심이 있다면 자신의 코드에 유용합니다.


며칠 전에 사용을 시작하기 위해이 소개를 살펴본 좋은 소개 : strace hello world


strace가 모니터링하는 레이어 아래에 무언가를 사용하면 어떻게 될까요?
Pacerier

이 경우 @Pacerier check ltrace stackoverflow.com/a/52012215/5884955
prosti

흥미로운 시스템 호출을 만들거나 주로 존재하는 저수준 프로그램을 디버깅하거나 syscall에 대한 새로운 옵션을 실험하여 OS의 기능을 확인하는 데 유용합니다. 기본적으로 일회성 실험을위한 로깅 / 오류 검사 코드 작성 문제를 해결합니다. (또는 당신은 당신이 실수로 잘못된 인수 또는 전화 번호를 건네 좋은 기회. 거기 ASM 또는 무언가에있어 쓰는 경우) 당신을 위해 errno를 코드를 검색하기 때문에 strace를 훨씬 빠르게 GDB보다가, 예를 들어 -EFAULT(죄송합니다, 읽기 전용 버퍼) 또는 -ENOENT(이런 상대 경로가 작동하지 않는 잘못된 디렉토리에서 실행되었습니다.)
Peter Cordes

62

간단히 말해서, strace는 프로그램이 발행 한 모든 시스템 호출과 리턴 코드를 추적합니다. 파일 / 소켓 작업 및 훨씬 더 모호한 작업과 같은 것을 생각하십시오.

여기서 시스템 호출은 표준 C 라이브러리 호출을보다 정확하게 나타낼 수 있으므로 C에 대한 실무 지식이있는 경우 가장 유용합니다.

프로그램이 / usr / local / bin / cough라고 가정 해 봅시다. 간단히 사용하십시오 :

strace /usr/local/bin/cough <any required argument for cough here>

또는

strace -o <out_file> /usr/local/bin/cough <any required argument for cough here>

'out_file'에 쓸 수 있습니다.

모든 strace 출력은 stderr로 이동합니다 (순서 볼륨은 종종 파일로의 리디렉션을 요구합니다). 가장 간단한 경우, 프로그램은 오류와 함께 중단되며 strace 출력에서 ​​OS와의 마지막 상호 작용이 무엇인지 확인할 수 있습니다.

자세한 내용은 다음을 참조하십시오.

man strace

36

strace는 적용된 프로세스에 의해 수행 된 모든 시스템 호출을 나열합니다 . 시스템 호출이 무엇을 의미하는지 모른다면, 많은 마일리지를 얻을 수 없습니다.

그럼에도 불구하고 문제에 파일이나 경로 또는 환경 값이 관련된 경우 문제가있는 프로그램에서 strace를 실행하고 출력을 파일로 리디렉션 한 다음 해당 파일을 경로 / 파일 / env 문자열에 대고 grep하면 프로그램이 실제로 무엇을 시도하고 있는지 확인할 수 있습니다. 기대했던 것과는 달리


7
당신이 당신의 작업은 당신이 결과를 통해 진행을 위해 잘라 그래서 그리고 사소하지 않은 프로그램이 ..., 종종 소방 호스에서 마시는 것과 같다
dmckee --- 전 사회자 고양이

17
strace <prog_name>프로그램을 추적합니다. strace -o <out_file> <prog_name>파일에 넣어
Jestin Joy

8
strace prog 2> & 1 | grep ^ open \ (
eisbaw

10
또는 그냥 : strace -e open myprog또는 모든 파일 관련 sys 호출에 대해 :strace -e file myprog
Amit Naidu

17

Strace는 디버거에서 이러한 프로그램을 실행할 여유가없는 프로덕션 시스템을 조사하기위한 도구입니다. 특히 다음 두 가지 상황에서 strace를 사용했습니다.

  • 프로그램 foo가 교착 상태에 있고 응답하지 않습니다. 이것은 gdb의 대상이 될 수 있습니다. 그러나 우리는 항상 소스 코드를 가지고 있지 않았거나 때로는 디버거에서 간단하게 실행되지 않는 스크립트 언어를 처리하고있었습니다. 이 경우 이미 실행중인 프로그램에서 strace를 실행하면 시스템 호출 목록이 표시됩니다. 클라이언트 / 서버 응용 프로그램 또는 데이터베이스와 상호 작용하는 응용 프로그램을 조사 할 때 특히 유용합니다
  • 왜 프로그램이 느린 지 조사. 특히, 우리는 방금 새로운 분산 파일 시스템으로 옮겼으며 시스템의 새로운 처리량은 매우 느 렸습니다. 각 시스템 호출에 소요 된 시간을 알려주는 '-T'옵션으로 strace를 지정할 수 있습니다. 이것은 파일 시스템으로 인해 속도가 느려지는 이유를 확인하는 데 도움이되었습니다.

strace를 사용하여 분석하는 예는 이 질문에 대한 내 대답을 참조하십시오 .


15

권한 문제를 디버깅하기 위해 항상 strace를 사용합니다. 기술은 다음과 같습니다.

$ strace -e trace=open,stat,read,write gnome-calculator

gnome-calculator실행할 명령은 어디에 있습니까 ?


8

strace -tfp PID는 PID 프로세스의 시스템 호출을 모니터하므로 프로세스 / 프로그램 상태를 디버그 / 모니터 할 수 있습니다.


6

Strace는 디버깅 도구 또는 기본 프로파일 러로 사용할 수 있습니다.

디버거로서 주어진 시스템 호출의 호출, 실행 및 반환 내용을 확인할 수 있습니다. 프로그램이 실패한 것뿐만 아니라 프로그램이 실패한 이유를 알 수 있기 때문에 이것은 매우 중요합니다. 일반적으로 프로그램의 모든 가능한 결과를 포착하지 못하는 형편없는 코딩의 결과입니다. 다른 경우에는 파일 경로를 하드 코딩 한 것입니다. strace없이 당신은 어디서 그리고 어떻게 잘못되었는지 추측 할 수 있습니다. strace를 사용하면 syscall을 분석 할 수 있습니다. 보통 반환 값을 보면 많은 것을 알 수 있습니다.

프로파일 링은 또 다른 용도입니다. 각 syscall의 실행 시간을 개별적으로 또는 집계로 사용할 수 있습니다. 이것이 문제를 해결하기에 충분하지는 않지만 잠재적 인 용의자 목록을 적어도 좁힐 것입니다. 단일 파일에 많은 fopen / close 쌍이 있으면 루프 외부에서 파일을 열고 닫는 대신 루프를 실행할 때마다 파일을 불필요하게 열고 닫을 수 있습니다.

Ltrace는 strace의 가까운 사촌이며 매우 유용합니다. 병목 현상이있는 위치를 차별화하는 법을 배워야합니다. 총 실행이 8 초이고 시스템 호출에 0.05 초만 소비하는 경우 프로그램을 추적하는 것이 그리 좋지 않을 것입니다. 문제는 코드에 있습니다. 일반적으로 논리 문제이거나 프로그램에 실제로 필요합니다. 그렇게 오래 걸립니까

strace / ltrace의 가장 큰 문제는 출력을 읽는 것입니다. 호출 방법 또는 적어도 syscall / 함수 이름을 모른다면 의미를 해독하기가 어려울 것입니다. 함수가 무엇을 반환하는지 아는 것도 특히 다른 오류 코드에 매우 유용 할 수 있습니다. 해독하는 것은 고통 스럽지만 때로는 때로는 지식의 진주를 돌려줍니다. 일단 inode가 부족하지만 여유 공간이 부족한 상황을 보았으므로 모든 일반적인 유틸리티가 나에게 경고를주지 않았으므로 새 파일을 만들 수 없었습니다. strace의 출력에서 ​​오류 코드를 읽으면 올바른 방향으로 나에게 지적되었습니다.


4

Strace는 응용 프로그램이 운영 체제와 어떻게 상호 작용하는지 알려주는 도구입니다.

응용 프로그램이 사용하는 OS 시스템 호출과 호출하는 매개 변수를 알려줍니다.

예를 들어 프로그램에서 어떤 파일을 열려고 시도하고 날씨가 좋을지 알 수 있습니다.

이 도구로 모든 종류의 문제를 디버깅 할 수 있습니다. 예를 들어 응용 프로그램에서 설치 한 라이브러리를 찾을 수 없다고하면 strace는 응용 프로그램이 해당 파일을 찾는 위치를 알려줍니다.

그리고 그것은 빙산의 일각 일뿐입니다.


이것은 매우 정확합니다.
prosti

4

strace는 프로그램이 다양한 시스템 호출 (커널 요청)을 수행하는 방법을 배우는 데 유용한 도구이며, 실패한 오류와 함께 실패한 오류를보고합니다. 모든 실패가 버그는 아닙니다. 예를 들어, 파일을 검색하려는 코드는 ENOENT (이러한 파일 또는 디렉토리 없음) 오류를 얻을 수 있지만 이는 코드 논리에서 허용 가능한 시나리오 일 수 있습니다.

strace를 사용하는 좋은 사용 사례 중 하나는 임시 파일을 만드는 동안 경쟁 조건을 디버깅하는 것입니다. 예를 들어 프로세스 ID (PID)를 사전 결정된 문자열에 추가하여 파일을 작성하는 프로그램은 다중 스레드 시나리오에서 문제에 직면 할 수 있습니다. [PID + TID (프로세스 ID + 스레드 ID) 또는 mkstemp와 같은 더 나은 시스템 호출로이를 해결합니다.]

크래시 디버깅에도 좋습니다. strace 및 디버깅 충돌에 대한 이 기사는 유용 할 수 있습니다.


4

최소 실행 가능 예

개념이 명확하지 않으면 설명하지 않은 더 간단한 예가 있습니다.

이 경우 그 예는 Linux x86_64 어셈블리 독립형 (libc 없음) hello world입니다.

안녕하세요 .S

.text
.global _start
_start:
    /* write */
    mov $1, %rax    /* syscall number */
    mov $1, %rdi    /* stdout */
    mov $msg, %rsi  /* buffer */
    mov $len, %rdx  /* buffer len */
    syscall

    /* exit */
    mov $60, %rax   /* exit status */
    mov $0, %rdi    /* syscall number */
    syscall
msg:
    .ascii "hello\n"
len = . - msg

GitHub의 상류 .

조립 및 실행 :

as -o hello.o hello.S
ld -o hello.out hello.o
./hello.out

예상 결과를 출력합니다.

hello

이제이 예제에서 strace를 사용하겠습니다 :

env -i ASDF=qwer strace -o strace.log -s999 -v ./hello.out arg0 arg1
cat strace.log

우리는 사용:

strace.log 이제는 다음을 포함합니다 :

execve("./hello.out", ["./hello.out", "arg0", "arg1"], ["ASDF=qwer"]) = 0
write(1, "hello\n", 6)                  = 6
exit(0)                                 = ?
+++ exited with 0 +++

이러한 최소한의 예를 통해 출력의 모든 단일 문자는 자명합니다.

  • execveline : CLI 인수 및 환경을 포함하여 strace실행 방법을 보여줍니다 hello.out.man execve

  • writeline : 우리가 작성한 쓰기 시스템 호출을 보여줍니다. 6문자열의 길이입니다 "hello\n".

    = 6시스템 호출의 리턴 값이며, 문서화 된 man 2 write바이트 수입니다.

  • exitline : 우리가 만든 엑시트 시스템 호출을 보여줍니다. 프로그램이 종료되었으므로 리턴 값이 없습니다!

더 복잡한 예

strace의 응용 프로그램은 복잡한 프로그램이 실제로 프로그램을 디버그 / 최적화하기 위해 수행하는 시스템 호출을 확인하는 것입니다.

특히 Linux에서 발생할 가능성이있는 대부분의 시스템 호출에는 glibc 래퍼가 있으며 그 중 대부분은 POSIX에서 제공 됩니다.

내부적으로 glibc 래퍼는 다음과 같이 인라인 어셈블리를 사용합니다. 인라인 어셈블리 에서 sysenter를 통해 시스템 호출을 호출하는 방법은 무엇입니까?

공부해야 할 다음 예는 POSIX writehello world입니다.

main.c

#define _XOPEN_SOURCE 700
#include <unistd.h>

int main(void) {
    char *msg = "hello\n";
    write(1, msg, 6);
    return 0;
}

컴파일하고 실행하십시오.

gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out

이번에 main는 main을위한 멋진 환경을 설정 하기 전에 glibc가 시스템 호출을 많이하고 있음을 알 수 있습니다.

우리는 이제 독립 프로그램을 사용하지 않고 libc 기능을 허용하는보다 일반적인 glibc 프로그램을 사용하고 있기 때문입니다.

그런 다음 모든 끝에서 다음을 strace.log포함합니다.

write(1, "hello\n", 6)                  = 6
exit_group(0)                           = ?
+++ exited with 0 +++

따라서 writePOSIX 함수는 Linux write시스템 호출을 사용합니다.

우리는 또한 대신에 전화로 return 0연결되는 것을 관찰합니다 . 하, 나는 이것에 대해 몰랐다! 이것이 너무 멋진 이유 입니다. 그런 다음 설명 :exit_groupexitstraceman exit_group

이 시스템 호출은 호출 스레드뿐만 아니라 호출 프로세스 스레드 그룹의 모든 스레드를 종료한다는 점을 제외하고 exit (2)와 같습니다.

그리고 여기에 어떤 시스템 호출이 dlopen사용 되는지 연구 한 또 다른 예가 있습니다.

Ubuntu 16.04, GCC 6.4.0, Linux 커널 4.4.0에서 테스트되었습니다.


2

다음은 strace를 사용하여 웹 사이트를 파는 방법에 대한 몇 가지 예입니다. 이것이 도움이 되길 바랍니다.

다음과 같이 첫 바이트 시간을 확인하십시오.

time php index.php > timeTrace.txt

수행중인 작업의 비율을 확인하십시오. 많은 lstatfstat그것의 시간이 캐시를 취소 할 수 있다는 표시 될 수있다 :

strace -s 200 -c php index.php > traceLstat.txt

trace.txt어떤 호출이 이루어지고 있는지 정확하게 볼 수 있도록 출력합니다 .

strace -Tt -o Fulltrace.txt php index.php

아무것도 사이했다 여부를 확인하려면이 옵션을 사용 .1하는 .9부하에 초 :

cat Fulltrace.txt | grep "[<]0.[1-9]" > traceSlowest.txt

에서 누락 된 파일 또는 디렉토리가 무엇인지 파악하십시오 strace. 이것은 우리 시스템과 관련된 많은 것들을 출력 할 것입니다-고객의 파일과 관련된 유일한 비트 :

strace -vv php index.php 2>&1 | sed -n '/= -1/p' > traceFailures.txt

1

strace운영 체제와의 상호 작용 방식을 확인하는 답변 중 일부가 마음에 들었습니다 .

이것이 바로 우리가 볼 수있는 것입니다. 시스템이 호출합니다. 당신이 비교하는 경우 straceltrace의 차이는 더 분명하다.

$>strace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         7           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0        11           close
  0.00    0.000000           0        10           fstat
  0.00    0.000000           0        17           mmap
  0.00    0.000000           0        12           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0         8         8 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         2           getdents
  0.00    0.000000           0         2         2 statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         9           openat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           prlimit64
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    93        10 total

반면에 ltrace추적 기능이 있습니다.

$>ltrace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls      function
------ ----------- ----------- --------- --------------------
 15.52    0.004946         329        15 memcpy
 13.34    0.004249          94        45 __ctype_get_mb_cur_max
 12.87    0.004099        2049         2 fclose
 12.12    0.003861          83        46 strlen
 10.96    0.003491         109        32 __errno_location
 10.37    0.003303         117        28 readdir
  8.41    0.002679         133        20 strcoll
  5.62    0.001791         111        16 __overflow
  3.24    0.001032         114         9 fwrite_unlocked
  1.26    0.000400         100         4 __freading
  1.17    0.000372          41         9 getenv
  0.70    0.000222         111         2 fflush
  0.67    0.000214         107         2 __fpending
  0.64    0.000203         101         2 fileno
  0.62    0.000196         196         1 closedir
  0.43    0.000138         138         1 setlocale
  0.36    0.000114         114         1 _setjmp
  0.31    0.000098          98         1 realloc
  0.25    0.000080          80         1 bindtextdomain
  0.21    0.000068          68         1 opendir
  0.19    0.000062          62         1 strrchr
  0.18    0.000056          56         1 isatty
  0.16    0.000051          51         1 ioctl
  0.15    0.000047          47         1 getopt_long
  0.14    0.000045          45         1 textdomain
  0.13    0.000042          42         1 __cxa_atexit
------ ----------- ----------- --------- --------------------
100.00    0.031859                   244 total

매뉴얼을 여러 번 확인했지만 이름의 출처를 찾지 strace못했지만 시스템 호출 추적 가능성이 높습니다.

에 대해 더 큰 메모가 세 개 있습니다 strace.

주 1 :이 기능 모두 straceltrace시스템 호출을 사용하고 있습니다 ptrace. 따라서 ptrace시스템 호출은 효과적으로 strace작동합니다.

ptrace () 시스템 호출은 한 프로세스 ( "추적자")가 다른 프로세스 ( "추적자")의 실행을 관찰하고 제어 할 수있는 수단을 제공하고 추적의 메모리와 레지스터를 검사하고 변경합니다. 주로 브레이크 포인트 디버깅 및 시스템 호출 추적을 구현하는 데 사용됩니다.

주 2 : 당신이 사용할 수있는 다른 매개 변수가 strace있기 때문에, strace매우 자세한 될 수는. 나는 -c일의 요약과 같은 실험을 좋아합니다. 을 바탕으로 -c당신과 같은 하나의 시스템 호출을 선택할 수 있습니다 -e trace=open만 그 전화를 볼 수 있습니다 어디. 추적하는 명령 중에 어떤 파일이 열릴지를 검사하는 경우 흥미로울 수 있습니다. 물론 grep동일한 목적으로 사용할 수도 있지만 2>&1 | grep etc명령을 실행할 때 구성 파일이 참조된다는 것을 이해하려면 이와 같이 리디렉션해야합니다 .

참고 3 : 나는이 매우 중요한 참고 사항을 찾습니다. 특정 아키텍처로 제한되지 않습니다. strace다른 아키텍처의 바이너리를 추적 할 수 있기 때문에 마음이 날 것입니다. 여기에 이미지 설명을 입력하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.