핵심 요약
- C++26 표준에 신규 `<debugging>` 헤더가 추가되어 컴파일러·플랫폼별로 파편화되었던 브레이크포인트 호출이 공식 표준화됩니다.
- 디버거 감지 및 중단점 호출 함수 3종이 제공되며, OS가 없는 환경을 위해 사용자 재정의(replaceable)까지 지원합니다.
- 언리얼 엔진, Boost 등 주요 프로젝트들이 매번 직접 매크로로 구현해야 했던 불편이 마침내 해소되었습니다.
요약 C++로 개발할 때 코드 내부에서 강제로 브레이크포인트(중단점)를 걸려면 컴파일러와 운영체제마다 각기 다른 전처리기 매크로를 작성해야 했습니다. MSVC에서는 `__debugbreak()`, Clang에서는 `__builtin_debugtrap()`, GCC x86 환경에서는 인라인 어셈블리 `int3`, 그 외 플랫폼에서는 `raise(SIGTRAP)`을 호출하는 등 복잡한 분기 처리가 필수적이었습니다.
이 때문에 Boost.Test(`debugger_break()`), Catch2(`CATCH_BREAK_INTO_DEBUGGER`), Dear ImGui(`IM_DEBUG_BREAK()`), Unreal Engine(`UE_DEBUG_BREAK`) 등 거의 모든 주요 C++ 프레임워크와 대형 프로젝트가 매번 자체적으로 똑같은 유틸리티를 바퀴 재발명하듯 만들어 써야만 했습니다.
다가오는 C++26 표준에서는 P2546R5 및 P2810R4 제안을 통해 신규 헤더 `<debugging>`이 추가되어 이 문제가 표준 라이브러리 차원에서 해결됩니다. 제공되는 함수는 `breakpoint()`, `is_debugger_present()`, `breakpoint_if_debugging()` 총 3가지입니다.
무조건 실행을 멈추는 `breakpoint()` 외에도, 현재 프로세스에 디버거가 연결되어 있는지 즉시 확인하는 `is_debugger_present()`가 분리되어 도입됩니다. 윈도우의 `::IsDebuggerPresent()`나 리눅스의 `/proc/self/status` 내 `TracerPid` 확인 등 플랫폼별 구현 방식을 표준화했을 뿐만 아니라, `operator new`처럼 사용자가 직접 재정의(replaceable)할 수 있어 OS가 없는 베어메탈(freestanding) 환경에서도 하드웨어 디버그 플래그 등에 유연하게 대응할 수 있습니다.
가장 자주 사용될 편의 함수인 `breakpoint_if_debugging()`은 디버거가 붙어 있을 때만 안전하게 브레이크포인트를 발생시키며, 디버거 감지 기능 덕분에 디버깅 중 타임아웃 해제나 전용 얼로케이터 전환 등 다양한 진단 환경을 손쉽게 구성할 수 있게 되었습니다. 단순하지만 수십 년간 파편화되었던 실무 필수 기능이 마침내 공식 표준화되었다는 평가입니다.
Sponsored · 광고