저는 디버깅 목적으로는 보통 gdb를 사용합니다.
실제 코드가 어떻게 수행되는지 확인하는 gdb와는 다르게 수행 중인 프로세스가 어떤 signal에 의해 죽는지
확인이 필요한 경우가 있는데 이런 경우 필요에 따라서 strace라는 툴을 사용하게 됩니다.
오늘은 strace 의 기본적인 사용방법에 대해 정리해 보고
이를 시작으로 strace 를 다양한 목적으로 사용해 보려고 합니다.
제가 작업하는 환경은 Ubuntu 22.04.1 LTS 입니다.
strace
manpage 를 우선 간단히 확인해 보면 다음과 같습니다.
NAME
strace - trace system calls and signals
SYNOPSIS
strace [-ACdffhikqqrtttTvVwxxyyzZ] [-I n] [-b execve] [-e expr]... [-O overhead] [-S sortby] [-U columns] [-a column] [-o file] [-s strsize] [-X format] [-P path]... [-p pid]...
[--seccomp-bpf] { -p pid | [-DDD] [-E var[=val]]... [-u username] command [args] }
strace -c [-dfwzZ] [-I n] [-b execve] [-e expr]... [-O overhead] [-S sortby] [-U columns] [-P path]... [-p pid]... [--seccomp-bpf] { -p pid | [-DDD] [-E var[=val]]... [-u username] command
[args] }
DESCRIPTION
In the simplest case strace runs the specified command until it exits. It intercepts and records the system calls which are called by a process and the signals which are received by a
process. The name of each system call, its arguments and its return value are printed on standard error or to the file specified with the -o option.
strace is a useful diagnostic, instructional, and debugging tool. System administrators, diagnosticians and trouble-shooters will find it invaluable for solving problems with programs for
which the source is not readily available since they do not need to be recompiled in order to trace them. Students, hackers and the overly-curious will find that a great deal can be learned
about a system and its system calls by tracing even ordinary programs. And programmers will find that since system calls and signals are events that happen at the user/kernel interface, a
close examination of this boundary is very useful for bug isolation, sanity checking and attempting to capture race conditions.
system call 과 signal 을 trace 해 주는 역할을 합니다.
앞에서 말했 듯 저는 보통 실행중인 프로세스가 어떤 signal의 영향을 받는지 확인이 필요할 때 사용합니다.
가끔 이유도 없이 비명횡사를 반복하는 경우가 있는데.. 이럴때 signal catch라도 하려면
strace가 필요합니다. (물론 코드를 통해 찍어봐도 되기는 합니다..)
간단한 예시 프로세스를 실행하고 strace 를 붙여보겠습니다.
그냥 sleep 을 실행해 보았습니다.
$ sleep 300&
[1] 3277
$ strace -p 3277
strace: Process 3277 attached
restart_syscall(<... resuming interrupted read ...>
sleep 300 을 수행하고 있는 pid 3277 에 strace 를 붙여보았습니다.
별다른 반응이 없습니다.
다른 터미널에서 3277 프로세스를 죽여보았습니다.
$ kill 3277
그 결과, strace 에서 나타나는 출력은 다음과 같습니다.
$ strace -p 3277
strace: Process 3277 attached
restart_syscall(<... resuming interrupted read ...>c
) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=2101, si_uid=1000} ---
+++ killed by SIGTERM +++
[1]+ Terminated sleep 300
kill 명령으로 죽였기 때문에 SIGTERM 에 의해 죽었다는 메시지를 뿌리고 strace는 종료됩니다.
여기서 signal정보 외에도 유용한 정보가 있다면
si_pid정보가 되겠습니다.
어떤 프로세스가 이 시그널을 날렸는지 정보를 담고 있는데요.
이거.. 아주 유용하게 사용이 가능합니다.
사실 써보기 전 까지는 얼마나 좋은지.. 느낄 수 없다고 생각합니다.
그..
산수유도 남자한테 참 좋은데
먹어봐야 알잖아요
잘 알아두었다가
뭔가 사고터졌을때
strace 가 생각나면 이제 쉽게 가는겁니다.
오늘은 이만 정리하겠습니다.
.wh
'CS' 카테고리의 다른 글
리눅스에서 C++ 프로그래밍을 위한 gcc, g++ 의 개념과 활용 (0) | 2024.02.18 |
---|---|
Linux 에서 프로세스의 core file(core dump) 분석 (0) | 2023.07.21 |
gdb 기초 사용방법 - 리눅스에서 C++ 디버깅 실행부터 값 출력까지 (0) | 2022.12.06 |
[디자인패턴] 방문자 패턴 (Visitor pattern) 의 개념 및 구조 요약정리 (0) | 2022.10.30 |
[디자인패턴] 중재자 패턴 (Mediator pattern) 의 개념, 구조 및 예시 요약정리 (0) | 2022.08.19 |