c++ - C++ 开发人员如何捕获发布版本中的编程错误?

标签 c++

我有一个 C++ 应用程序,它因某些未知客户数据的段错误而崩溃。客户拒绝分享他的输入数据。是否可以找出错误发生在哪里?

当 Java 应用程序在最终用户端崩溃时,它通常会产生一个堆栈跟踪,可以帮助开发人员找出程序中的错误所在以及哪些程序不变量被破坏。

但在这种情况下,C++ 开发人员应该怎么做呢?我是否应该使用某些编译器选项重新编译应用程序,以便在发生错误时提供一些诊断?

最佳答案

如果您没有重现问题所需的输入数据(无论出于何种原因......包括难缠的客户)并且您没有核心/小型转储,那么您无能为力。我遇到过很多这样的情况。我的办法是重新创建我认为是基于采访客户的执行路径,然后进行细致的代码审查以找出错误条件的可能性。我会测试每个候选条件并最终找到问题所在。这是痛苦的、耗时的,主要的先决条件是您能够像阅读母语一样阅读代码。

开始故事时间

我工作的地方有一个随机出现在 Multi-Tenancy 系统中的崩溃错误。再多的日志记录、核心转储等也无法帮助我们找到它。最后,我查看了代码(逐行、数千行)并注意到开发人员正在从传递给 ctor 的 char* 序列构造一个 std::string 实例。它在代码的深处几乎从未改变过,因此将问题与最近的变化相关联只是一组错误的线索。我问开发人员,“你们所有的字符数组都是空终止的吗?”答:“没有。”我:“好吧,我们然后随机读取内存,直到它找到一个空值,显然有时堆有很多连续的非零内存。”以不同方式处理 char 数组边界导致问题得到解决。

结束故事时间

虽然您找不到找到所有错误的单一方法,但可以应用一种非常简单的防御设计。一旦遇到这种情况,大多数人都会将其放入代码中。该方法是添加对不同级别的日志记录详细程度的支持,并且本质上是使用日志输出来检测您的代码,除非将代码设置为使用正确的详细程度,否则这些日志输出不会执行。将详细级别调高,直到错误被重新创建,您至少可以了解错误发生的位置。客户通常不会在共享编辑后的日志数据时遇到问题(假设日志中有敏感数据)。将日志加载到 Splunk 或类似工具中(如果客户尚未在分析工具中聚合他们的日志),您将可以更轻松地查看数据。

不幸的是,对于 C++,您无法免费(通常)获得良好的堆栈跟踪和事后分析数据。您必须预先将这些事后故障排除功能添加到您的设计中。大多数设计都是由预期的部署环境和代码的用户角色驱动的,因此将“难缠的客户”添加为角色并开始编码。 :)

关于c++ - C++ 开发人员如何捕获发布版本中的编程错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48953962/

相关文章:

c++ - 返回不返回变量值

c++ - Boost::filesystem::is_symlink() 不起作用

c++ - 对于 `shared_ptr` 树结构,比 "widget"更好的选择?

c++ - 整数列表的交集 - 无法返回结果列表

c++ - 了解循环输出

c++ - 在 C++ 中的两个 vector 之间交换不同长度的序列

c++ - auto&& 将如何延长临时对象的生命周期?

c++ - CUDA:统一内存,使用数组

c++ - 为什么我可以捕获一个对象或 dynamic_cast 即使它的 std::type_info 对象不同?

c# - 如何使用 size_t 遍历 uint64*,c# 的等价物是什么?