strace를 사용하여 Linux 시스템 호출을 모니터링하는 방법

게시 됨: 2022-01-29
랩톱 PC의 양식화된 터미널 창입니다.
Fatmawati achmad zaenuri/Shutterstock.com

Linux 프로그램은 커널에게 몇 가지 작업을 수행하도록 요청합니다. strace 명령은 이러한 시스템 호출을 표시합니다. 프로그램이 작동하는 방식과 때로는 작동하지 않는 이유를 이해하는 데 사용할 수 있습니다.

커널과 시스템 호출

아무리 똑똑해도 컴퓨터 프로그램이 스스로 모든 것을 할 수는 없습니다. 특정 기능이 수행되도록 요청해야 합니다. 이러한 요청은 Linux 커널로 이동합니다. 일반적으로 프로그램이 호출하는 라이브러리 또는 기타 소프트웨어 인터페이스가 있으며 라이브러리는 커널에 적절한 요청(시스템 호출이라고 함)을 만듭니다.

프로그램이 수행한 시스템 호출과 응답을 볼 수 있으면 관심 있거나 작성한 프로그램의 내부 작동을 이해하는 데 도움이 될 수 있습니다. 이것이 바로 strace 가 하는 일입니다. 문제를 해결하고 병목 현상을 찾는 데 도움이 될 수 있습니다.

이것은 gdb 와 같은 도구를 사용하여 애플리케이션을 디버깅하는 것과 동일하지 않습니다. 디버깅 프로그램을 사용하면 프로그램이 실행될 때 프로그램의 내부 작업을 조사할 수 있습니다. 이를 통해 프로그램 논리를 단계별로 실행하고 메모리 및 변수 값을 검사할 수 있습니다. 그에 비해 strace 가 하는 일은 프로그램이 실행될 때 시스템 호출 정보를 캡처하는 것입니다. 추적된 프로그램이 종료되면 strace 는 시스템 호출 정보를 터미널 창에 나열합니다.

시스템 호출은 파일에 대한 읽기 및 쓰기 작업, 프로세스 종료 등과 같은 모든 종류의 저수준 기능을 제공합니다. syscalls 매뉴얼 페이지에는 수백 개의 시스템 호출 목록이 있습니다.

관련: GDB로 디버깅: 시작하기

strace 설치

컴퓨터에 strace 가 아직 설치되어 있지 않다면 매우 쉽게 설치할 수 있습니다.

Ubuntu에서는 다음 명령을 사용합니다.

 sudo apt 설치 strace 

Fedora에서 다음 명령을 입력합니다.

 sudo dnf 설치 strace 

Manjaro에서 명령은 다음과 같습니다.

 sudo pacman -Sy strace 

strace를 사용한 첫 번째 단계

우리는 strace 를 보여주기 위해 작은 프로그램을 사용할 것입니다. 많은 작업을 수행하지 않습니다. 파일을 열고 해당 파일에 한 줄의 텍스트를 기록하고 오류 검사를 하지 않습니다. strace 와 함께 사용할 수 있는 빠른 해킹입니다.

 #include <stdio.h>

int 메인(int argc, char argv[]) { 

  // 파일 핸들 
  파일 *fileGeek;

  // "strace_demo.txt"라는 파일을 열거나 생성합니다. 
  fileGeek = fopen("strace_demo.txt", "w");

  // 파일에 일부 텍스트 쓰기 
  fprintf(fileGeek, "파일에 쓰기" );

  // 파일을 닫는다 
  fclose(파일긱);

  // 프로그램 종료 
  리턴(0); 

} // 메인 끝

이것을 "file-io.c"라는 파일에 저장하고 gcc 를 사용하여 " st race ex ample"이라는 이름의 stex 라는 실행 파일로 컴파일했습니다.

 gcc -o stex 파일-io.c

명령줄에서 strace 를 호출하고 새 실행 파일의 이름을 추적하려는 프로세스로 전달합니다. Linux 명령이나 다른 바이너리 실행 파일을 쉽게 추적할 수 있습니다. 우리는 두 가지 이유로 우리의 작은 프로그램을 사용하고 있습니다.

첫 번째 이유는 strace 가 장황하기 때문입니다. 많은 출력이 있을 수 있습니다. 화가 난 상태에서 strace 를 사용할 때 좋은 방법이지만 처음에는 압도적일 수 있습니다. 우리의 작은 프로그램에는 제한된 strace 출력이 있습니다. 두 번째 이유는 우리 프로그램의 기능이 제한적이고 소스 코드가 짧고 간단하기 때문입니다. 이렇게 하면 프로그램 내부 작업의 다른 부분을 참조하는 출력 섹션을 쉽게 식별할 수 있습니다.

 strace ./stex 

열린 파일에 "Write this to the file"이라는 텍스트를 보내는 write 시스템 호출과 exit_group 시스템 호출을 명확하게 볼 수 있습니다. 이것은 응용 프로그램의 모든 스레드를 종료하고 반환 값을 다시 셸로 보냅니다.

출력 필터링

우리의 간단한 데모 프로그램으로도 꽤 많은 결과물을 얻을 수 있습니다. -e (표현식) 옵션을 사용할 수 있습니다. 보고자 하는 시스템 호출의 이름을 전달합니다.

 strace -e 쓰기 ./stex 

광고

여러 시스템 호출을 쉼표로 구분된 목록으로 추가하여 보고할 수 있습니다. 시스템 호출 목록에 공백을 포함하지 마십시오.

 strace -e 닫기, ./stex 쓰기 

파일로 출력 보내기

출력 필터링의 이점은 출력 필터링의 문제이기도 합니다. 당신은 당신이 보도록 요청한 것을 볼 수 있지만 다른 것은 볼 수 없습니다. 그리고 그 다른 출력 중 일부는 당신이 보도록 요청한 것보다 당신에게 더 유용할 수 있습니다.

때로는 모든 것을 캡처하고 전체 결과 집합을 검색하고 스크롤하는 것이 더 편리합니다. 그렇게 하면 중요한 것을 실수로 제외하지 않을 것입니다. -o (출력) 옵션을 사용하면 strace 세션의 출력을 텍스트 파일로 보낼 수 있습니다.

 추적 -o 추적 출력.txt ./stex 

그런 다음 less 명령을 사용하여 목록을 스크롤하고 이름으로 시스템 호출 또는 기타 항목을 검색할 수 있습니다.

 적은 trace-output.txt 

이제 less 의 모든 검색 기능을 사용하여 출력을 조사할 수 있습니다.

관련: Linux에서 less 명령을 사용하는 방법

타임스탬프 추가

출력에 여러 다른 타임스탬프를 추가할 수 있습니다. -r (상대 타임스탬프) 옵션은 각 연속 시스템 호출의 시작 사이의 시간 차이를 표시하는 타임스탬프를 추가합니다. 이 시간 값에는 이전 시스템 호출에 소요된 시간과 다음 시스템 호출 이전에 프로그램이 수행한 모든 시간이 포함됩니다.

 strace -r ./stex 

광고

타임스탬프는 각 출력 라인의 시작 부분에 표시됩니다.

각 시스템 호출에 소요된 시간을 보려면 -T (syscall-times) 옵션을 사용하십시오. 이것은 각 시스템 호출 내에서 소요된 시간을 보여줍니다.

 strace -T ./stex 

지속 시간은 각 시스템 호출 라인의 끝에 표시됩니다.

각 시스템 호출이 호출된 시간을 보려면 -tt (절대 타임스탬프) 옵션을 사용합니다. 이것은 마이크로초 해상도로 "벽시계" 시간을 보여줍니다.

 strace -tt ./stex 

시간은 각 줄의 시작 부분에 표시됩니다.

실행 중인 프로세스 추적

추적하려는 프로세스가 이미 실행 중인 경우 여전히 strace 를 연결할 수 있습니다. 그러려면 프로세스 ID를 알아야 합니다. 이것을 찾으려면 grep 과 함께 ps 를 사용할 수 있습니다. Firefox가 실행 중입니다. firefox 프로세스의 ID를 찾으려면 ps 를 사용하고 grep 을 통해 파이프할 수 있습니다.

 추신 - 전자 | 그렙 파이어 폭스 

광고

프로세스 ID가 8483임을 알 수 있습니다. -p (프로세스 ID) 옵션을 사용하여 strace 에 연결할 프로세스를 알려줍니다. sudo 를 사용해야 합니다.

 sudo strace -p 8483 

strace 가 프로세스에 연결되었다는 알림이 표시되고 시스템 추적 호출이 평소와 같이 터미널 창에 표시됩니다.

보고서 작성

-c (요약만) 옵션은 strace 가 보고서를 인쇄하도록 합니다. 추적된 프로그램이 수행한 시스템 호출에 대한 정보에 대한 테이블을 생성합니다.

 strace -c ./stex 

열은 다음과 같습니다.

  • % time : 각 시스템 호출에 소요된 실행 시간의 백분율입니다.
  • : 각 시스템 호출에 소요된 총 시간(초 및 마이크로초)입니다.
  • usecs/call : 각 시스템 호출에 소요된 평균 시간(마이크로초)입니다.
  • 호출 : 각 시스템 호출이 실행된 횟수입니다.
  • errors : 각 시스템 호출에 대한 실패 횟수입니다.
  • syscall : 시스템 호출의 이름입니다.

이 값은 빠르게 실행되고 종료되는 사소한 프로그램에 대해 0을 표시합니다. 실제 값은 데모 응용 프로그램보다 더 의미 있는 작업을 수행하는 프로그램에 대해 표시됩니다.

깊은 통찰력, 쉽게

strace 출력은 어떤 시스템 호출이 수행되고 있는지, 어떤 시스템 호출이 반복적으로 수행되는지, 커널 측 코드 내에서 얼마나 많은 실행 시간이 소요되는지를 보여줄 수 있습니다. 좋은 정보네요. 종종 코드 내부에서 무슨 일이 일어나고 있는지 이해하려고 할 때 바이너리가 많은 기능을 수행하기 위해 커널과 거의 논스톱으로 상호 작용한다는 사실을 잊기 쉽습니다.

strace 를 사용하면 전체 그림을 볼 수 있습니다.

관련: 개발자 및 열광자를 위한 최고의 Linux 노트북