返回

文章详情

C++26:新的调试头文件

Hacker News2026年10月16日 18:52

如果你曾在 C++ 中需要以编程方式触发断点,你可能写过类似这样的代码: #if defined(_MSC_VER) __debugbreak(); #elif defined(__clang__) __builtin_debugtrap(); #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) __asm__ volatile ( "int3" ); #else raise( SIGTRAP ); #endif 每个主要的 C++ 项目都重新发明了这个轮子。Boost.Test 有 debugger_break(),Catch2 有 CATCH_BREAK_INTO_DEBUGGER,Dear ImGui 有 IM_DEBUG_BREAK(),而 Unreal 有 UE_DEBUG_BREAK。所需的平台知识是晦涩的,但对于工具实现者而言是众所周知的——只是没有标准化。 C++26 通过 P2546R5 及其伴侣 P2810R4 修复了这一点,感谢 Rene Ferdinand Rivera Morell。一个新的 <debugging> 头文件提供了三个函数。三个函数如下: #include <debugging> namespace std { void breakpoint() noexcept; bool is_debugger_present() noexcept; void breakpoint_if_debugging() noexcept; } 这三者都是 noexcept,且都是自由函数。都不是 constexpr——调试是一个运行时问题。 std::breakpoint() 一个无条件的断点。当调试器连接时,执行将暂停并控制转交给调试器。在 x86 上,这通常编译为一条单独的 int3 指令。当没有调试器时,行为是实现定义的——在大多数平台上,进程接收到一个信号(如 SIGTRAP)并将终止,除非该信号被捕获。 std::is_debugger_present() 如果程序当前正在被调试器追踪,则返回 true。检查在每次调用时立即执行——结果不会被缓存,因为调试器可以在执行期间的任何时候附加或分离。这个函数的底层工作方式因平台而异。例如,在 Windows 上,某个实现可能会调用 ::IsDebuggerPresent()。在 Linux 上,GCC 的 libstdc++ 读取 /proc/self/status 并检查 TracerPid 字段。标准并没有强制任何特定机制——语义是实现定义的,预期行为在非标准性注释中描述。使这个函数有趣的一点是它是可替换的,和 operator new 和 operator delete 的意义一样。你可以定义自己的版本: bool std::is_debugger_present() noexcept { return my_hardware_debug_flag; } 这是由 P2810R4 引入的,解决了自由函数的问题:在裸机平台上,可能没有 OS 级别的方法来检测调试器。如果没有可替换性,函数要么必须被排除在自由函数之外(在每处都强制使用 #ifdef 守卫),要么返回一个无用的默认值。可替换性使你可以将其连接到你平台提供的任何东西。 std::breakpoint_if_debugging() 大多数用户会使用的便利函数。等同于: if (std::is_debugger_present()) std::breakpoint(); 当调试器连接时,你会触发断点。当它没有连接时,什么也不会发生。这是 Catch2、Boost.Test 和其他所有框架手动实现的模式。 超越断点 将 is_debugger_present() 作为一个单独的函数使得不仅仅是条件断点成为可能。你可能会用它来: 产生额外的调试输出 在单步调试期间禁用超时 切换到更适合调试的分配器 跳过使调试变得困难的优化 关注的分离是经过深思熟虑的——breakpoint() 和 is_debugger_present() 是正交的构建块,而 breakpoint_if_debugging() 是便利的组合。 结论 <debugging> 是另一个让你感到为什么花了这么长时间才加入 C++26 的重要功能。所需的平台知识非常清晰,每个主要项目已经有自己的版本,而 API 只有三个函数。有时候,最有用的标准库新增功能是最简单的那些。深入联系 如果你喜欢这篇文章,请点击喜欢按钮,订阅我的通讯,和我在推特上联系!如果你正在准备 C++ 量化/交易面试,请查看 GetCracked。

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

☕请我喝杯咖啡