Post

strace 명령어 활용하기

리눅스에서 시스템 콜을 추적하는 디버깅 툴

strace 명령어 활용하기

strace 란?

man strace bash 명령어를 실행해보면 정의 및 설명은 아래와 같다. 간단히, 시스템 콜(호출)을 추적하는 디버깅 툴이라고 보면 된다.

strace - trace system calls and signals

  • intercepts and records the system calls which are called by a process and the signals which are received by a process.
  • is a useful diagnostic, instructional, and debugging tool.

시스템 콜 추적

간단한 예시로 ls 명령어 실행 시의 시스템 콜을 추적해본다. ls 는 파일 디렉토리를 리스팅하는 기본 명령어다. strace ls 실행해보면 100여 라인의 시스템 콜이 화면에 찍히는데 간단히 살펴보자.

1
2
3
4
5
6
7
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tr"..., 1024) = 464
read(3, "", 1024)                       = 0
close(3)                                = 0
access("/etc/selinux/config", F_OK)     = -1 ENOENT (No such file or directory)
...

각 라인의 맨 앞에 오는 단어들은 어떤 시스템 콜을 하는지를 나타낸다. 시스템 콜들의 설명과 간단한 동작 설명은 아래와 같다. 동작 설명은 ChatGPT 를 통해 검색했다. 이외에도 많은 시스템 콜들이 있는데 미리 알고 있을 필요는 없고 궁금할 때 하나씩 찾아보면 되겠다.

openat

  • 파일을 열거나 새로 생성하는 시스템 호출
  • open 과 달리 openat 은 특정 디렉토리(상대 경로)를 기준으로 파일을 열기 위한 함수
  • 현재 작업 디렉토리(AT_FDCWD)를 기준으로, “/proc/filesystems” 을 읽기 전용(O_RDONLY)으로 연다.
  • O_CLOEXEC 은 파일 디스크립터가 새로운 프로그램이 실행될 때 자동으로 닫히도록 설정
    • 파일 디스크립터가 예상치 않게 다른 프로그램에서 열려 있는 것을 방지하여 보안성을 향상
    • 프로세스가 파일 디스크립터를 남겨두지 않으므로 리소스가 낭비되지 않도록 자원 관리
  • 반환값: 파일 디스크립터(3)

fstat

  • 파일의 메타데이터를 가져오는 시스템 호출
  • 프로그램이 파일을 읽거나 쓰기 전에 해당 파일 속성(크기, 타입 등)을 알기 위해 자주 호출된다.
  • st_mode 는 파일 유형과 권한을, st_size 는 파일 크기가 0바이트임을 나타낸다.

read

  • 파일 디스크립터가 가리키는 위치에서 지정된 크기만큼 데이터를 읽어 메모리 버퍼에 저장하는 시스템 호출
  • 프로그램이 파일, 네트워크 소켓, 파이프 등에서 데이터를 읽을 때 사용된다.
  • 파일을 연 후 데이터 읽기를 수행하거나, 네트워크에서 들어오는 메시지를 수신하는 작업에 유용
  • 함수 인자: 파일 디스크립터, 읽은 데이터를 저장할 메모리 버퍼 주소, 읽을 데이터의 최대 바이트 수
  • 반환 값: 실제로 읽은 바이트 수. 0 은 파일의 끝(EOF)을, -1 은 오류 발생을 의미

access

  • 특정 파일에 대해 프로세스가 읽기/쓰기/실행 등의 권한을 가지고 있는지 확인하는 시스템 호출
  • 함수 인자: 접근을 확인할 파일 경로, 확인할 권한
    • 권한: R_OK(읽기), W_OK(쓰기), X_OK(실행), 또는 F_OK(존재 여부)

프로세스 디버깅

나는 strace 의 활용을 주로 디버깅 용도로 활용한다. 개발 업무 중 ruby 스크립트를 콘솔에서 실행할 일이 아주 많은데, ps 명령어를 통해 얻은 PID 를 가지고 프로세스에 strace 연결하여 실행한 코드가 어떤 상태인지 확인한다. 스크립트가 실행 중 멈춘 것 같거나 할 때 유용하다. 여러 개의 콘솔에서 다수의 스크립트를 실행했을 때, 스크립트의 동작을 tracing 해보고 프로세스를 구분하기도 한다.

man(매뉴얼) 페이지에 아래와 같은 설명이 있다.

-p pid: Attach to the process with the process ID pid and begin tracing.

1
2
3
4
5
# strace 활용 예시
# -s (strsize): Specify the maximum string size to print (the default is 32)
# -t: Prefix each line of the trace with the wall clock time
# -f: Trace  child processes as they are created by currently traced processes
sudo strace -s 16 -f -t -p <pid>

참고


This post is licensed under CC BY 4.0 by the author.