본문 바로가기
CS

strace 처음 사용하기

by Warehaus 2023. 1. 18.

 

저는 디버깅 목적으로는 보통 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