我正在编写一个 C++ 服务器程序,将部署到 *nix 系统(Linux/macOS)。程序有时在生产环境中会遇到段错误,我想收集一些信息,例如核心转储文件。但我不知道这样做的最佳实践是什么:
我了解到有些事情我可以尝试:
RelWithDebInfo
有Release
和CMAKE_BUILD_TYPE
,但似乎它们有不同的优化级别。所以我认为 RelWithDebInfo
构建的性能不如 Release
构建。 (根据此处“RelWithDebInfo 使用 -O2,但 Release 使用 -O3” 什么是 CMAKE_BUILD_TYPE:Debug、Release、RelWithDebInfo 和 MinSizeRel?)objectcopy
/strip
这样的工具允许您从二进制文件中删除调试信息(如何在构建目标之外生成 gcc 调试符号?)SIGSEGV
信号时打印堆栈跟踪(如何在程序崩溃时自动生成堆栈跟踪)我是部署生产C++服务器程序的新手,我想知道以下问题的答案:
RelWithDebInfo
还是Release
?strip
这样的工具?Release
构建二进制文件,当 Release
构建在生产环境中生成核心转储时,我可以稍后使用相同版本的源代码来构建 RelWithDebInfo
二进制文件并使用 ( gdb + RelWithDebInfo
二进制 + Release
构建核心转储)用于核心转储分析?总的来说,我想知道如何建议为生产构建 C++ 程序,以便在我仍然能够对其进行故障排除的同时对其进行最佳优化。非常感谢。
这将是一个相当笼统的答案。
RelWithDebInfo
。或者,您可以覆盖 -O2
优化,让编译器全程优化。strip
。这不会改变任何实际执行的内容,但会删除使调试变得更加容易的内容。您仍然可以调试剥离的可执行文件,但更难理解发生了什么。一般规则是(或应该是)您认为发布环境是敌对的。有时这是真的,有时则不然——这里不能适用一般性,因为只有你知道你的具体情况。
我总是部署我的东西完全优化。如果程序特别有问题,我只会包含调试信息,因为这样可以轻松运行它或使用
gdb
附加到它。
全面优化的缺点是有时事情看起来与您编写的代码有点不同。事情的顺序可能会改变,有些事情可能根本不会发生,并且您可能会发现某些函数实际上并不作为正确的独立函数存在,因为编译器认为内联它们会更好。这些是我观察到的变化,但可能还有其他变化。
最近我了解到有像Google Breakpad这样的工具可以生成小型转储格式的崩溃报告,可以在生产环境中收集和分析。我还没有尝试过,但它对于这个确切的目的可能很有用。