TL;DR
- C++26은 플랫폼별 중단점 구현을 표준화한
<debugging>헤더를 제공하며, 세 함수는 모두noexcept와 프리스탠딩(freestanding) 환경을 지원함. std::breakpoint()는 디버거가 연결된 경우 실행을 멈추고 디버거에 제어를 넘기며, 디버거가 없을 때의 동작은 구현 정의임.std::is_debugger_present()는 호출할 때마다 디버거 연결 여부를 확인하며, 프리스탠딩 환경의 플랫폼별 구현을 위해 재정의할 수 있음.std::breakpoint_if_debugging()은 디버거가 연결된 경우에만 중단점을 설정하는 편의 함수임.- 디버거 감지 함수는 진단 출력, 타임아웃, 메모리 할당자, 최적화 설정 등 중단점 외의 디버깅 동작에도 활용할 수 있음.
디버거 중단점 구현의 표준화
- C++에서 프로그램 코드로 중단점을 설정하려면 컴파일러와 플랫폼에 따라
__debugbreak(),__builtin_debugtrap(), x86 어셈블리의int3,raise(SIGTRAP)등을 조건부로 사용하는 방식이 일반적임. - 주요 C++ 프로젝트는 각자 이 기능을 구현해 왔으며,
Boost.Test의debugger_break(),Catch2의CATCH_BREAK_INTO_DEBUGGER,Dear ImGui의IM_DEBUG_BREAK(),Unreal의UE_DEBUG_BREAK가 그 사례임. - 도구 구현자에게는 플랫폼별 지식이 잘 알려져 있었지만, 표준화되어 있지는 않았음.
- Rene Ferdinand Rivera Morell의 제안인 P2546R5와 동반 제안 P2810R4를 통해 C++26에
<debugging>헤더와 세 함수가 추가됨.
세 함수
<debugging>헤더는std::breakpoint(),std::is_debugger_present(),std::breakpoint_if_debugging()을 선언함.- 세 함수는 모두
noexcept이며 프리스탠딩 환경에서도 제공됨. - 디버깅은 런타임 작업이므로 세 함수 중
constexpr함수는 없음.
`std::breakpoint()`
- 조건 없이 중단점을 설정함. 디버거가 연결되어 있으면 실행이 멈추고 제어가 디버거로 넘어감.
- x86에서는 보통 단일
int3명령어로 컴파일됨. - 디버거가 없을 때의 동작은 구현 정의임. 대부분의 플랫폼에서는
SIGTRAP같은 시그널을 프로세스에 보내며, 해당 시그널을 처리하지 않으면 프로세스가 종료됨.
`std::is_debugger_present()`
- 프로그램이 현재 디버거에 의해 추적되고 있는지
bool값으로 반환함. - 호출할 때마다 즉시 확인하며 결과를 캐시하지 않음. 실행 중 언제든 디버거가 연결되거나 분리될 수 있기 때문임.
- 내부 구현은 플랫폼에 따라 다름. Windows 구현은
::IsDebuggerPresent()를 호출할 수 있으며, Linux의 GCClibstdc++는/proc/self/status를 읽고TracerPid필드를 확인함. - 표준은 특정 확인 방법을 요구하지 않으며, 의미는 구현 정의이고 의도된 동작은 비규범적 주석에 설명됨.
- 이 함수는
operator new와operator delete처럼 재정의할 수 있음. 예를 들어 플랫폼이 제공하는 하드웨어 디버그 플래그를 반환하도록 자체 구현을 정의할 수 있음. - P2810R4는 프리스탠딩 환경 문제를 해결하기 위해 재정의 가능성을 도입함. 베어메탈 플랫폼에는 디버거를 감지하는 운영체제 수준의 방법이 없을 수 있음.
- 재정의가 불가능하면 프리스탠딩 환경에서 함수를 제외해 곳곳에
#ifdef를 요구하거나, 쓸모없는 기본값을 반환해야 하는 문제가 생김. 재정의 가능성은 플랫폼이 제공하는 수단에 함수를 연결할 수 있게 함.
`std::breakpoint_if_debugging()`
- 가장 간편하게 사용할 수 있는 함수로,
std::is_debugger_present()가 참이면std::breakpoint()를 호출하는 것과 같음. - 디버거가 연결되어 있으면 중단점에 도달하고, 연결되어 있지 않으면 아무 동작도 하지 않음.
Catch2,Boost.Test를 비롯한 프레임워크가 수동으로 구현해 온 패턴임.
중단점 외의 활용
std::is_debugger_present()를 별도로 제공하므로 조건부 중단점 외에도 다양한 디버깅 동작에 활용할 수 있음.- 디버깅 중 추가 진단 출력을 생성함.
- 단계별 실행 중 발생할 수 있는 타임아웃을 비활성화함.
- 디버거 친화적인 메모리 할당자로 전환함.
- 디버깅을 어렵게 만드는 최적화를 건너뜀.
- 관심사를 분리한 설계임.
breakpoint()와is_debugger_present()는 서로 독립적인 구성 요소이며,breakpoint_if_debugging()은 두 함수를 조합한 편의 함수임.
결론
<debugging>은 플랫폼별 구현이 잘 알려져 있고 주요 프로젝트가 이미 자체 버전을 보유한 기능을 세 함수로 표준화한 C++26 추가 사항임.- 가장 유용한 표준 라이브러리 추가 기능은 때로 이처럼 단순한 기능임.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요