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

0
534

랩톱 PC의 양식화된 터미널 창입니다.
Fatmawati achmad zaenuri/Shutterstock.com

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

커널과 시스템 호출

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

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

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

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

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

strace 설치

만약에 strace 아직 컴퓨터에 설치되어 있지 않으므로 매우 쉽게 설치할 수 있습니다.

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

sudo apt install strace

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

sudo dnf install strace

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

sudo pacman -Sy strace

strace를 사용한 첫 번째 단계

우리는 시연하기 위해 작은 프로그램을 사용할 것입니다 strace. 많은 작업을 수행하지 않습니다. 파일을 열고 해당 파일에 한 줄의 텍스트를 기록하고 오류 검사를 하지 않습니다. 그것은 우리가 사용할 무언가를 가지고 있기 때문에 단지 빠른 해킹입니다. strace.

#include <stdio.h>

int main(int argc, char argv[]) { 

  // file handle 
  FILE *fileGeek;

  // open a file called "strace_demo.txt", or create it 
  fileGeek = fopen("strace_demo.txt", "w");

  // write some text to the file 
  fprintf(fileGeek, "Write this to the file" );

  // close the file 
  fclose(fileGeek);

  // exit from program 
  return (0); 

} // end of main

이것을 “file-io.c”라는 파일에 저장하고 다음으로 컴파일했습니다. gcc 라는 실행 파일로 stex, “의 이름을 딴경주 앰플.”

gcc -o stex file-io.c

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

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

strace ./stex

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

출력 필터링

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

strace -e write ./stex

광고

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

strace -e close,write ./stex

출력을 파일로 보내기

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

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

strace -o trace-output.txt ./stex

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

less trace-output.txt

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

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

타임스탬프 추가

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

strace -r ./stex

광고

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

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

strace -T ./stex

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

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

strace -tt ./stex

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

실행 중인 프로세스 추적

추적하려는 프로세스가 이미 실행 중인 경우에도 계속 연결할 수 있습니다. strace 그것에. 그러려면 프로세스 ID를 알아야 합니다. 당신이 사용할 수있는 ps ~와 함께 grep 이것을 찾기 위해. Firefox가 실행 중입니다. 아이디를 알아보려면 firefox 프로세스, 우리는 사용할 수 있습니다 ps 그리고 그것을 통해 파이프 grep.

ps -e | grep firefox

광고

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

sudo strace -p 8483

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

보고서 작성

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

strace -c ./stex

열은 다음과 같습니다.

  • % 시각: 각 시스템 호출에 소요된 실행 시간의 백분율입니다.
  • : 각 시스템 호출에 소요된 총 시간(초 및 마이크로초)입니다.
  • 사용/통화: 각 시스템 호출에 소요된 평균 시간(마이크로초)입니다.
  • 전화: 각 시스템 호출이 실행된 횟수입니다.
  • 오류: 각 시스템 호출에 대한 실패 횟수입니다.
  • 시스템 콜: 시스템 호출의 이름입니다.

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

깊은 통찰력, 쉽게

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

사용하여 strace, 당신은 전체 그림을 참조하십시오.