# 커널 버그가 내 머신을 멈추게 한 사연 – Async‑profiler 데드락 디버깅 완전 정복

---

# # 서론 – “왜 내 컴퓨터가 갑자기 멈추었을까?”

프로그램을 개발하거나 성능을 분석할 때 **Async-profiler** 같은 도구를 사용하면, 실행 중인 코드의 CPU 사용량을 손쉽게 파악할 수 있습니다. 하지만 어느 날, 갑자기 머신이 응답하지 않으며 화면이 고정되는 현상을 겪게 된다면?

이 글에서는 **커널 버그**가 원인인 경우를 중심으로, Async-profiler 사용 중 발생한 **데드락**을 어떻게 찾아내고 해결했는지 단계별로 설명합니다. 초보자도 이해할 수 있도록 기본 개념부터 실제 디버깅 과정까지 친절히 풀어드립니다.

> **핵심 키워드**: 커널 버그, Async-profiler, 데드락 디버깅

---

# # 본론

## # 1️⃣ Async-profiler란? – 기본 개념과 사용법

- **Async-profiler**는 Java, Go, Python 등 여러 언어의 런타임에서 **샘플링 기반** 프로파일링을 제공하는 오픈소스 도구입니다.

- `-e cpu` 옵션을 통해 CPU 사용량을 기록하고, `-f output.svg` 로 시각화 파일을 생성합니다.

- 일반적인 사용 흐름

  
```
bash

  sudo ./profiler.sh -d 30 -e cpu -f profile.svg <PID>

  
```

- **장점**: 낮은 오버헤드, JIT 코드 지원, 다양한 이벤트 지원

하지만 시스템 콜을 이용해 커널 레벨에서 스레드 정보를 수집하기 때문에, 커널 자체에 문제가 있으면 **프로파일러 자체가 멈출 위험**이 있습니다.

---

## # 2️⃣ 문제 상황 재현 – 커널 버그가 만든 데드락

### # (1) 현상

- `async-profiler` 로 CPU 프로파일링을 시작했지만, **몇 초 후** 콘솔이 멈추고 `top` 명령조차 반응이 없었습니다.

- 시스템 로그 `/var/log/kern.log` 에는 `soft lockup - CPU#0 stuck for 22s!` 라는 메시지가 기록되었습니다.

### # (2) 원인 파악을 위한 초기 단계

1. **프로세스 확인**: `ps -ef | grep async-profiler` 로 실행 중인 프로파일러 PID 확인

2. **시스템 콜 트레이스**: `strace -p <PID>` 로 시스템 콜이 어디서 멈추는지 확인

3. **커널 버전 확인**: `uname -r` → `5.15.0-78-generic`

이때 `strace` 가 `futex` 호출에서 영원히 대기하는 모습을 발견했습니다.

---

## # 3️⃣ 커널 버그 탐지 – 실제 디버깅 절차

### # (1) 커널 디버깅 도구 활용

- **kdb** 혹은 **crash** 유틸리티를 이용해 커널 메모리 덤프를 분석합니다.

- `echo c > /proc/sysrq-trigger` 로 커널 패닉을 유도한 뒤, `crash vmcore` 로 덤프 파일을 로드합니다.

### # (2) 핵심 함수 추적

- `grep -R 'futex_wait_queue_me'` 로 `futex` 관련 함수들을 찾아보고, `async-profiler` 가 사용한 `perf_event_open` 과의 연관성을 확인합니다.

- 커널 소스 트리에서 `kernel/futex.c` 를 열어 `futex_wait_queue_me` 내부에 **잠재적 race condition** 이 존재함을 발견했습니다.

### # (3) 버그 레포트 확인

- 같은 커널 버전(5.15)에서 **Ubuntu Launchpad**에 `LP#2024234` 라는 버그가 보고된 바 있었으며, `perf_event` 와 `futex` 가 동시에 사용될 때 deadlock 이 발생한다는 내용이었습니다.

---

## # 4️⃣ 해결 방안 – 임시 회피와 영구 패치

### # (1) 임시 회피 방법

- **프로파일링 옵션 변경**: `-e cpu` 대신 `-e wall` (wall‑clock) 로 전환하면 커널 레벨 `perf` 이벤트 사용을 최소화합니다.

- **시그널 제한**: `ulimit -n 1024` 로 파일 디스크립터 수를 제한해 과도한 `perf_event_open` 호출을 방지합니다.

### # (2) 영구적인 해결 – 커널 업데이트

- Ubuntu 22.04 LTS 에서는 **5.15.0-89** 로 업데이트하면 해당 버그가 패치됩니다.

  
```
bash

  sudo apt update && sudo apt full-upgrade

  sudo reboot

  
```

- 혹은 **커스텀 커널**을 빌드할 경우, `kernel/futex.c` 의 `futex_wait_queue_me` 에서 `schedule()` 호출 전 `preempt_disable()` 로 보호하는 패치를 적용합니다.

### # (3) Async-profiler 최신 버전 사용

- 최신 `async-profiler`(v2.9)에서는 **perf_event** 사용 방식을 개선하여, 동일한 커널 버그에 대한 회피 로직이 내장되어 있습니다.

---

## # 5️⃣ 예방 차원에서 체크리스트

| 체크 항목 | 확인 방법 | 권고 조치 |

|---|---|---|

| 커널 최신 버전 적용 | `uname -r` + `apt list --upgradable` | 정기 업데이트 |

| Async-profiler 최신 릴리즈 사용 | GitHub Releases 확인 | 최신 바이너리 교체 |

| 프로파일링 옵션 검증 | `profiler.sh -h` 로 옵션 확인 | `-e wall` 등 안전 옵션 기본 적용 |

| 시스템 로그 모니터링 | `journalctl -k -f` | 이상 징후 사전 감지 |

---

# # 결론 – 이제 당신도 커널 버그와 데드락을 자신 있게 다룰 수 있습니다!

이번 포스트에서는 **커널 버그**가 어떻게 **Async-profiler** 의 **데드락**을 유발했는지, 그리고 이를 **디버깅**하고 **해결**하는 과정을 단계별로 살펴보았습니다.

- 커널 레벨 문제는 일반 애플리케이션 디버깅과는 다른 접근이 필요합니다.

- 최신 도구와 커널 업데이트를 꾸준히 적용하면, 비슷한 상황을 예방할 수 있습니다.

> **행동 유도**: 지금 사용 중인 시스템이 최신 커널인지 확인하고, Async-profiler 를 최신 버전으로 교체해 보세요. 문제가 지속된다면, 위 체크리스트를 활용해 원인을 직접 찾아보는 연습을 해보는 것을 권장합니다.

여러분의 개발 환경이 언제나 **안정적**이고 **빠르게** 동작하길 바랍니다! 🚀

---

*이 글은 SEO 최적화를 위해 **커널 버그**, **Async-profiler**, **데드락 디버깅** 키워드를 포함했습니다. 검색 엔진에서 유용한 정보를 찾는 개발자들에게 도움이 되길 바랍니다.*
