QUESTION
strace에 보이지 않는 시간은 어디에서 확인해야 하는가?
strace는 ptrace/seccomp 기반으로 syscall 진입·종료와 signal을 보여 주지만 userspace 계산과 kernel 내부 함수 구간을 직접 나누지 못한다. /proc는 특정 시점의 fd, maps, status, sched 정보를 제공하고 perf는 counter, sampling, tracepoint로 CPU와 kernel event를 관찰한다.
한 도구 출력만으로 원인을 단정하지 않는다. syscall wall time, off-CPU wait, page fault, scheduler delay, userspace CPU sample을 같은 request timeline에 맞춘다.
STRUCTURE
구조 그림
도구마다 관찰 단위가 다르다. syscall trace로 userspace CPU hot path를 설명하거나 RSS snapshot으로 page fault latency를 설명할 수 없다.
CALL PATH
호출 흐름
관찰 질문을 먼저 고른다. fd leak에는 fd table, page fault latency에는 fault counter, CPU hot path에는 sampling처럼 대상 객체와 도구를 맞춘다.
함수 이름을 외우기 위한 그림이 아니다. 반환값, 파일 디스크립터, 메모리 매핑, 대기 큐 가운데 무엇이 다음 단계로 전달되는지 확인한다.
SOURCE COORDINATES
Linux 6.18.37 LTS 소스 위치
glibc 함수에서 멈추지 않고 syscall 구현과 커널 객체가 만나는 파일까지 내려간다. 링크는 동일한 태그의 원본 파일을 가리킨다.
| 파일 | 함수·구조체 | 여기서 볼 것 |
|---|---|---|
| fs/proc/base.c | proc_pid_status(), proc_pid_fd_operations | PID별 status/fd 파일이 어떤 task 정보를 노출하는지 확인 |
| kernel/events/core.c | perf_event_open(), perf_event_alloc() | perf event context와 fd 수명 |
| kernel/trace/trace_events.c | event_trace_add_tracer() | tracepoint event enable과 ring buffer 연결 |
COMPLETE PROGRAM
실행 예제 원본
아래 코드는 설명을 위해 중간 줄을 생략한 의사 코드가 아니다. 파일로 빌드해 실행할 수 있는 최소 예제다.
cc -std=c17 -Wall -Wextra -O2 observe_me.c -o observe_me01#define _DEFAULT_SOURCE
02#include <fcntl.h>
03#include <stdio.h>
04#include <stdlib.h>
05#include <sys/mman.h>
06#include <unistd.h>
07
08int main(void)
09{
10 long page = sysconf(_SC_PAGESIZE);
11 size_t length = 32UL * 1024 * 1024;
12 unsigned char *area = mmap(NULL, length, PROT_READ | PROT_WRITE,
13 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
14 if (area == MAP_FAILED)
15 return 1;
16 for (size_t offset = 0; offset < length; offset += (size_t)page)
17 area[offset] = (unsigned char)(offset / (size_t)page);
18
19 int fd = open("/dev/null", O_WRONLY | O_CLOEXEC);
20 if (fd < 0)
21 return 1;
22 dprintf(fd, "pid=%ld pages=%zu\n", (long)getpid(), length / (size_t)page);
23 close(fd);
24 printf("pid=%ld checksum=%u\n", (long)getpid(), area[length - page]);
25 munmap(area, length);
26 return 0;
27}
CODE NOTES
코드 조각별 설명
sysconf(_SC_PAGESIZE)계측 loop 단위를 실제 base page 크기에 맞춰 fault 수와 접근 수를 비교할 수 있게 한다.
mmap(NULL, lengthstrace에는 빠른 mmap syscall 하나로 보이지만 실제 page 비용은 아래 write loop의 minor fault에서 발생한다.
area[offset] =perf stat의 page-faults/minor-faults가 증가하고 userspace loop CPU 시간이 생기는 지점이다.
open("/dev/null"/proc/self/fd에는 잠깐 fd가 나타나며 strace에서 openat/close 수명을 확인할 수 있다.
munmap(areamapping 수명을 명시적으로 끝낸다. process exit가 정리해 주더라도 장기 process의 반복 동작에서는 unmap 시점이 RSS/VA에 중요하다.
DETAILS
세부 동작
strace 시간은 syscall 안과 밖을 나눈다
-T는 syscall 진입부터 반환까지 경과를 보여 주지만 ptrace overhead가 짧은 호출과 multithread scheduling에 영향을 준다. -ttt/clock 기준으로 application request log와 맞춘다.
unfinished/resumed 표시는 thread가 syscall에서 block된 동안 다른 trace line이 끼었음을 뜻한다.
/proc 파일도 읽는 순간 변한다
fd directory를 순회하는 동안 process가 fd를 닫고 재사용할 수 있다. maps와 smaps 사이에도 VMA가 바뀔 수 있다. snapshot처럼 보이지만 전체 process state transaction은 아니다.
정확한 dump가 필요하면 process stop, ptrace, application safepoint 등 consistency 방법을 정한다.
perf sampling은 확률적 관찰이다
sample frequency가 낮으면 짧은 hot path를 놓치고 높으면 overhead와 lost sample이 늘어난다. call graph 방식 frame pointer/DWARF/LBR의 tradeoff를 기록한다.
counter multiplexing이 있으면 time_enabled/time_running 비율과 scaled value를 확인한다.
OBJECTS
객체와 수명
| 대상 | 언제 생기고 없어지는가 | 확인할 값 |
|---|---|---|
tracee task | strace attach부터 detach/exit까지 ptrace 관계가 유지된다 | stop reason, syscall state, signal |
proc file snapshot | open/read 시 task 객체를 조회하며 각 파일마다 consistency 범위가 다르다 | PID reuse, namespace, permission |
perf event fd | perf_event_open에서 생기고 enable/disable/read/close로 관리된다 | counter, sample ring, time scaling |
FAILURE PATH
실패 조건과 오해하기 쉬운 부분
| 겉으로 보이는 현상 | 실제 원인 후보 | 확인 방법 |
|---|---|---|
| strace에서 병목이 안 보임 | userspace CPU 또는 scheduler delay | perf record/sched와 wall timeline |
| PID 대상이 바뀜 | 숫자 PID 재사용 | pidfd와 starttime 확인 |
| perf 결과 불안정 | sampling 부족/multiplex/주파수 변화 | 반복, scaling, CPU pinning |
LAB
직접 확인
- strace -c와 -ttT로 syscall count와 개별 latency를 보고 perf stat page-faults와 결과를 맞춘다.
- 프로그램을 getchar로 멈춘 변형에서 /proc/PID/maps, smaps_rollup, fd, status를 한 번에 수집한다.
- perf record -g와 flame graph 이전에 compiler frame pointer 설정, debug symbol, sample loss를 확인한다.
./observe_mestrace -ttT -f ./observe_me && perf stat -d ./observe_mePRIMARY REFERENCES