문제

한 동료는 Linux에서 모든 것이 디버깅에 실패했을 때 마지막 옵션은 다음을 사용하는 것이라고 말했습니다. 스트레이스.

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

그래서,

  • 정확히 무엇이며 어떤 역할을 합니까?
  • 어떤 경우에 어떻게 사용해야 하나요?
  • 출력을 어떻게 이해하고 처리해야 합니까?

간단히 말해서, 간단한 말로, 이 물건은 어떻게 작동하나요?

도움이 되었습니까?

해결책

Strace 개요
Strace는 가벼운 무게 디버거로 볼 수 있습니다. 프로그래머 / 사용자는 프로그램이 OS와 어떻게 상호 작용하는지 빠르게 찾을 수 있습니다. 시스템 호출 및 신호를 모니터링하여이를 수행합니다.

용도
소스 코드가 없거나 실제로 그것을 겪고 싶지 않은 경우에 좋습니다.
또한 GDB를 열고 싶지 않지만 외부 상호 작용을 이해하는 데 관심이있는 경우 자신의 코드에 유용합니다.

좋은 작은 소개
나는 다른 날 에이 소개를 Strace 사용으로 만났습니다. Strace Hello World

다른 팁

간단히 말해서, 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

Strace는 모두 나열됩니다 시스템 호출 적용되는 프로세스에 의해 수행됩니다. 시스템 호출이 어떤 의미인지 모른다면 많은 마일리지를 얻을 수 없습니다.

그럼에도 불구하고 문제가 파일 또는 경로 또는 환경 값과 관련이있는 경우 문제가있는 프로그램에서 Strace를 실행하고 출력을 파일로 리디렉션 한 다음 Path/File/Env String에 대한 해당 파일을 greping습니다. 프로그램이 무엇인지 확인할 수 있습니다. 실제로 당신이 기대했던 것과 구별되는 것으로 시도합니다.

Strace는 디버거 아래에서 이러한 프로그램을 실행할 여유가없는 생산 시스템을 조사하기위한 도구로 두드러집니다. 특히, 우리는 다음 두 가지 상황에서 Strace를 사용했습니다.

  • 프로그램 Foo는 교착 상태에 빠졌고 응답이 없어졌습니다. 이것은 GDB의 대상이 될 수 있습니다. 그러나 우리는 항상 소스 코드를 가지고 있지 않았거나 때로는 디버거 아래에서 실행되기에 직접적으로 진행되지 않은 스크립트 언어를 다루고있었습니다. 이 경우 이미 실행중인 프로그램에서 Strace를 실행하면 시스템 통화 목록이 작성됩니다. 클라이언트/서버 응용 프로그램 또는 데이터베이스와 상호 작용하는 응용 프로그램을 조사하는 경우 특히 유용합니다.
  • 프로그램이 느린 이유를 조사합니다. 특히, 우리는 방금 새로운 분산 파일 시스템으로 이동했으며 시스템의 새로운 처리량은 매우 느 렸습니다. 각 시스템 호출에 소요 된 시간을 알려주는 '-t'옵션으로 Strace를 지정할 수 있습니다. 이것은 파일 시스템이 왜 속도를 늦추는지를 결정하는 데 도움이되었습니다.

Strace를 사용하여 분석하는 예는 내 답변을 참조하십시오. 이 질문.

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

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

어디에 gnome-calculator 실행하려는 명령입니다.

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

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

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

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

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

strace/ltrace의 가장 큰 문제는 출력을 읽는 것입니다.호출 방법을 모르거나 최소한 시스템 호출/함수의 이름을 모른다면 의미를 해독하기 어려울 것입니다.함수가 반환하는 내용을 아는 것도 특히 다양한 오류 코드의 경우 매우 유용할 수 있습니다.해독하는 것은 고통스러운 일이지만 때로는 실제로 지식의 진주를 반환합니다.inode가 부족하지만 여유 공간이 부족하지 않은 상황을 본 후에는 모든 일반 유틸리티에서 경고를 표시하지 않았으므로 새 파일을 만들 수 없었습니다.strace의 출력에서 ​​오류 코드를 읽으면 올바른 방향을 알 수 있습니다.

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

OS 시스템이 애플리케이션이 사용하는 OS 시스템과 어떤 매개 변수를 호출하는지 알려줍니다.

예를 들어 프로그램이 열려있는 파일을 열고 날씨가 성공합니다.

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

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

Strace는 프로그램이 다양한 시스템 호출 (커널에 대한 요청)을 만드는 방법을 배우는 좋은 도구이며 해당 실패와 관련된 오류 값과 함께 실패한 것들을보고합니다. 모든 실패가 버그가 아닙니다. 예를 들어, 파일을 검색하려는 코드는 ENOENT (파일 또는 디렉토리) 오류가 발생할 수 있지만 코드의 논리에서 허용 가능한 시나리오 일 수 있습니다.

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

또한 사고를 디버깅하는 데 좋습니다. 당신은 찾을 수 있습니다 Strace 및 디버깅 충돌에 관한이 기사 (내) 기사 유용한.

나는 그것이 읽는 곳에 답을 좋아했다 strace 운영 체제와 상호 작용하는 방법을 확인합니다.

이것이 바로 우리가 볼 수있는 것입니다. 시스템이 호출됩니다. 비교하면 strace 그리고 ltrace 차이가 더 분명합니다.

$>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 :이 기능 모두 strace 그리고 ltrace 시스템 호출을 사용하고 있습니다 ptrace. 그래서 ptrace 시스템 호출은 효과적으로 방법입니다 strace 공장.

ptrace () 시스템 호출은 하나의 프로세스 ( "트레이서")가 다른 프로세스 ( "트레이스")의 실행을 관찰하고 제어 할 수있는 수단을 제공하고 추적의 기억과 레지스터를 검사하고 변경할 수 있습니다. 주로 중단 점 디버깅 및 시스템 호출 추적을 구현하는 데 사용됩니다.

참고 2 : 사용할 수있는 다양한 매개 변수가 있습니다. strace, 부터 strace 매우 장황 할 수 있습니다. 나는 실험하고 싶다 -c 그것은 사물의 요약과 같습니다. 기반 -c 하나의 시스템 호출을 선택할 수 있습니다 -e trace=open 그 전화 만 볼 수있는 곳. 추적중인 명령 중에 어떤 파일이 열릴 파일을 검사하는 경우에도 흥미로울 수 있습니다. 물론, 당신은 사용할 수 있습니다 grep 같은 목적을 위해서는 이렇게 리디렉션해야합니다. 2>&1 | grep etc 명령이 발행 될 때 구성 파일이 참조되어 있음을 이해합니다.

참고 3 :이 중요한 메모를 발견했습니다. 귀하는 특정 아키텍처에만 국한되지 않습니다. strace 다른 아키텍처의 바이너리를 추적 할 수 있기 때문에 마음을 날려 버릴 것입니다.enter image description here

최소한의 실행 가능한 예

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

이 경우,이 예제는 Linux X86_64 어셈블리 독립형 (LIBC 없음) Hello World입니다.

안녕하세요

.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 +++

이러한 최소한의 예제로 출력의 모든 단일 문자는 자체적으로 분명합니다.

  • execve 라인 : 방법을 보여줍니다 strace 실행 hello.out, 문서화 된 CLI 인수 및 환경을 포함하여 man execve

  • write 라인 : 우리가 만든 쓰기 시스템 호출을 보여줍니다. 6 문자열의 길이입니다 "hello\n".

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

  • exit 라인 : 우리가 만든 출구 시스템 호출을 보여줍니다. 프로그램이 종료되었으므로 반환 값이 없습니다!

더 복잡한 예

Strace의 적용은 물론 어떤 시스템 호출 복잡한 프로그램이 실제로 프로그램을 디버그 / 최적화하는 데 도움이되는지 확인합니다.

특히 Linux에서 발생할 가능성이있는 대부분의 시스템 호출은 Glibc 래퍼가 있습니다. 그들 중 많은 사람들이 Posix에서 온 것입니다.

내부적으로 GLIBC 포장지는 인라인 어셈블리를 어느 정도 사용합니다. 인라인 어셈블리에서 Sysenter를 통해 시스템 호출을 호출하는 방법은 무엇입니까?

다음 예를 공부 해야하는 예는 POSIX입니다 write 안녕하세요 세계 :

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

이번에는 GLIBC가 수많은 시스템 호출이 이루어지고 있음을 알 수 있습니다. main 메인을위한 멋진 환경을 설정합니다.

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

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

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

그래서 우리는 write Posix 기능은 Linux를 사용합니다 write 시스템 호출.

우리는 또한 그것을 관찰합니다 return 0 in로 연결됩니다 exit_group 대신 전화하십시오 exit. 하, 나는 이것에 대해 몰랐다! 이는 이유 strace 너무 멋지다. man exit_group 그런 다음 설명합니다.

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

그리고 여기 내가 어떤 시스템 호출을 공부 한 또 다른 예가 있습니다. dlopen 사용 : https://unix.stackexchange.com/questions/226524/what-system-call-is-used-to-libraries-in-linux/462710#462710

우분투 16.04, GCC 6.4.0, Linux 커널 4.4.0에서 테스트.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top