strace로 8μs 간격 동시성 버그를 찾아낸 DevOps 엔지니어의 이야기

by DD
3개월 전
조회수 14

shaka-packager를 사용한 스트리밍 패키징 과정에서 간헐적인 파일 쓰기 오류 발생

strace를 활용하여 시스템콜을 추적, mkdirat 호출 시 8μs 간격으로 발생하는 동시성 문제 발견

create_directories 함수의 반환값 처리 오류로 인해 디렉토리 생성 실패, 파일 쓰기 오류 발생

디렉토리 사전 생성을 통해 문제를 해결, shaka-packager 코드 수정 및 우회 방법 제시

strace를 활용한 시스템콜 추적

본문에서는 strace(strace)를 사용하여 shaka-packager의 파일 쓰기 오류를 분석했다. strace는 프로세스가 호출하는 시스템콜(System Call)을 추적하여 애플리케이션의 저수준 동작을 파악하는 데 유용하다. 특히, -ff, -tt, -y 옵션을 사용하여 스레드별 로그를 시간순으로 비교함으로써 동시성 문제를 효과적으로 진단했다. strace는 DevOps 엔지니어(DevOps Engineer)가 시스템 레벨의 문제를 해결하는 데 필수적인 도구이다.

동시성 버그의 원인 분석

글에 따르면, shaka-packager의 LocalFile::Open 함수 내에서 디렉토리 생성 로직의 문제점을 발견했다. 구체적으로, std::filesystem::create_directories 함수의 반환값만 확인하고, std::error_code(Error Code)를 확인하지 않아 발생한 문제이다. 두 스레드가 동시에 디렉토리 생성을 시도할 때, 먼저 생성된 스레드는 성공하지만, 8μs 후에 실행된 스레드는 이미 디렉토리가 존재함에도 불구하고 오류로 처리되어 파일 생성이 실패했다.

create_directories 함수의 함정

글에서 언급된 std::filesystem::create_directories 함수는 디렉토리 생성 성공 여부를 반환하지만, 이미 존재할 경우에도 false를 반환한다. 이 때, std::error_code를 통해 추가적인 정보를 확인해야 한다. shaka-packager 코드는 이 부분을 간과하여, 디렉토리가 이미 존재할 경우에도 오류로 처리하는 결함(Defect)을 보였다. 이러한 오류는 동시성 환경에서 간헐적으로 발생하며, 디버깅을 어렵게 만드는 요인이다.

문제 해결 및 우회 방법

본문에서는 근본적인 해결책으로 shaka-packager 코드에서 create_directories 호출 시 std::error_code를 확인하도록 수정하는 것을 제시했다. 임시 해결책으로는 패키징 실행 전에 출력 디렉토리를 미리 생성하는 우회 방법(Workaround)을 사용했다. 이 방법은 디렉토리가 이미 존재할 경우 create_directories를 호출하지 않도록 하여 문제를 회피한다. 이러한 접근 방식은 DevOps 엔지니어(DevOps Engineer)가 실제 운영 환경에서 겪는 문제에 대한 효과적인 대처법을 보여준다.

디버깅 과정의 교훈

글쓴이는 애플리케이션 로그만으로는 원인을 파악하기 어려웠던 문제를 strace를 통해 해결했다. strace를 통해 시스템콜 수준에서 문제를 분석함으로써, 파일 쓰기 실패(File Write Failure)의 정확한 원인을 찾아낼 수 있었다. 이 경험은 로그만으로는 파악하기 어려운 문제를 해결하기 위해 시스템콜 추적과 같은 저수준 디버깅(Low-level Debugging) 기법의 중요성을 강조한다. 또한, 동시성 문제 해결에 있어 경합 조건(Race Condition)을 이해하고, 코드의 세밀한 부분까지 파악하는 것이 중요함을 시사한다.

strace 추적으로 8μs 차이의 동시성 버그 찾기