strace를 사용하여 Linux 시스템 호출을 모니터링하는 방법
게시 됨: 2022-01-29 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
를 사용하면 전체 그림을 볼 수 있습니다.
리눅스 명령어 | ||
파일 | tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · 보기 · 문자열 · 유형 · 이름 바꾸기 · zip · 압축 풀기 · 마운트 · 언마운트 · 설치 · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · 패치 · 변환 · rclone · 파쇄 · srm | |
프로세스 | alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · 종료 · 재부팅 · 정지 · poweroff · passwd · lscpu · crontab · 날짜 · bg · fg | |
네트워킹 | netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw |
관련: 개발자 및 열광자를 위한 최고의 Linux 노트북