Skip to main content

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

Published 4 min readMarkdown

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

프로그램을 개발하거나 성능을 분석할 때 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, 데드락 디버깅 키워드를 포함했습니다. 검색 엔진에서 유용한 정보를 찾는 개발자들에게 도움이 되길 바랍니다.

No comments yet. Be the first to comment.

More from this blog