我有一个C ++应用程序崩溃了segfault与一些未知的客户数据。客户拒绝分享他的输入数据。是否有可能弄清楚错误发生在哪里?
当Java应用程序在最终用户端崩溃时,它通常会生成一个堆栈跟踪,可以帮助开发人员找出程序中的错误位置以及哪些程序不变的地方。
但是在这种情况下C ++开发人员应该怎么做?我是否应该使用某些编译器选项重新编译应用程序,以便在发生错误时提供一些诊断信息?
答案 0 :(得分:4)
如果您没有重新创建问题所需的输入数据(无论出于何种原因......包括困难客户)并且您没有核心/小型转储,那么您无能为力。我曾经遇到过很多这样的情况。我的办法是重新创建我认为基于访问客户的执行路径,然后进行细致的代码审查以找出错误条件的可能性。我会测试每个候选条件并最终找到问题。这是痛苦的,耗时的,并且主要的先决条件是您能够阅读几乎与您一样的代码并阅读您的母语。
开始故事时间
我曾经在一个多租户系统中随机显示崩溃错误的地方工作。没有任何日志记录,核心转储等可以帮助我们找到它。最后,我回顾了代码(line。by.line。for many thousands of lines),并注意到开发人员正在从传递给ctor的char *序列构造一个std :: string实例。在代码中几乎没有变化的部分是深层次的,因此将问题与最近的变化联系起来只是一组错误的线索。我问开发人员,"你的所有char数组都是空终止了吗?"答案:"否。"我:"然后我们随机读取内存,直到找到空值,显然有时堆有很多连续的非零内存。"以不同方式处理char数组边界导致解决问题。
结束故事时间
虽然您无法找到找到所有错误的单一方法,但您可以使用非常简单的防御设计。一旦被这种情况烧毁,大多数人都会把它放在代码中。该方法是添加对不同级别的日志记录详细程度的支持,并且基本上使用不执行的日志输出来检测代码,除非将代码设置为使用正确的详细级别。将详细级别提升到重新创建错误之后,您至少可以了解它的发生位置。通常,客户在共享编辑日志数据时不会遇到问题(假设日志中存在敏感数据)。将日志加载到Splunk或类似的东西中(如果客户尚未在分析工具中汇总其日志),您将更容易查看数据。
不幸的是,使用C ++,您无法获得免费的堆栈跟踪和事后数据(一般情况下)。您必须事先将这些事后故障排除功能添加到您的设计中。大多数设计都来自预期的部署环境和代码的用户角色,因此添加了困难的客户"作为一个角色并开始编码。 :)