UBSan으로 C 미정의 동작 런타임에 잡기 — gcc·clang 실측 비교
정수 오버플로나 배열 범위 밖 접근처럼 C의 미정의 동작(undefined behavior)은 대개 크래시 없이 조용히 지나간다. 컴파일 경고로 잡히는 것은 상수로 접근하는 뻔한 경우뿐이고, 인덱스나 시프트 값이 런타임에 결정되면 경고가 나오지…
리눅스 시스템 디버깅
정수 오버플로나 배열 범위 밖 접근처럼 C의 미정의 동작(undefined behavior)은 대개 크래시 없이 조용히 지나간다. 컴파일 경고로 잡히는 것은 상수로 접근하는 뻔한 경우뿐이고, 인덱스나 시프트 값이 런타임에 결정되면 경고가 나오지…
메모리 문제는 대부분 사후에 발견된다. OOM으로 프로세스가 죽은 뒤 dmesg 한 줄이 남고, 그 전까지 누가 얼마나 잡아먹고 있었는지는 알 수 없다. /proc/meminfo나 /proc/slabinfo는 지금 이 순간의 스냅샷이라 어떤 작업이…
4편까지는 스케줄러가 하는 일을 밖에서 들여다보기만 했다. 스케줄링 정책 자체를 바꾸려면 kernel/sched/를 고쳐 커널을 다시 빌드하고 재부팅해야 했고, 정책 하나 시험하는 데 빌드 주기가 통째로 들어갔다. 커널 6.12에 정식 합류한…
CPU 사용률이 100%가 아닌데도 응답이 느린 서버가 있다. 태스크가 실행 가능(runnable) 상태로 런큐에서 기다린 시간, 즉 런큐 지연(run queue latency)이 원인인 경우가 많은데 top이나 vmstat에는 이 값이 나오지 않는다. /proc/PID/schedstat에…
같은 vfs_read()를 관측하더라도 BPF 프로그램을 붙일 수 있는 훅은 kprobe, fentry, tracepoint, raw tracepoint 등 여러 가지다. 훅마다 인자에 접근하는 방법, 커널 버전이 바뀔 때의 안정성, 이벤트당 비용이 다르다. 고빈도…
eBPF 프로그램은 이벤트 하나를 처리하고 끝나는 짧은 함수라서, 이벤트 사이에 상태를 유지하거나 결과를 유저 공간에 넘기려면 BPF 맵이 필요하다. 문제는 맵 종류가 30가지가 넘고, 잘못 고르면 카운트가 조용히 유실되거나 이벤트가…
커널 동작을 들여다보려면 예전에는 커널 모듈을 만들거나 커널을 다시 빌드해야 했다. 모듈 버그 하나가 곧 커널 패닉이고, 커널 버전이 바뀔 때마다 다시 컴파일해야 한다. eBPF는 검증된 작은 프로그램을 실행 중인…
공유 라이브러리는 프로세스마다 다른 주소에 올라간다. ASLR이 켜져 있으면 같은 libc.so.6도 실행할 때마다 위치가 바뀐다. 그런데 .text는 읽기 전용으로 매핑되어 여러 프로세스가 물리 페이지를 공유하므로, call printf의 피연산자에 실제 주소를…
스핀락(spinlock)과 뮤텍스(mutex)를 잘못 쓴 커널 코드는 대부분 조용히 지나간다. 초기화하지 않은 스핀락은 0으로 채워진 메모리라 x86에서는 그냥 동작하고, 스핀락 안에서 호출한 kmalloc(GFP_KERNEL)은 메모리가 넉넉하면 잠들지 않으니 아무 일도 없다. 그러다…
장애 상황을 재현하려고 보면 소스가 없는 바이너리이거나, 디스크를 실제로 가득 채우거나 시스템 시계를 바꿔야 하는 경우가 많다. 코드를 고치지 않고 "이 프로그램이 어떤 파일을 여는지", "디스크가 꽉 차면 에러 처리를…