C ++:我应该捕获所有异常还是让程序崩溃?

时间:2014-10-03 21:56:30

标签: c++ windows exception crash minidump

我有一个用(Visual)C ++编写的Windows服务,它具有非常详细的日志记录功能,经常帮助我找到客户有时遇到的错误原因。基本上我检查每个返回值并记录发生了什么以及错误来自哪里。

理想情况下,我希望对异常具有相同级别的详细可见性(例如,数组超出范围,除以零等)。换句话说:我想知道异常的来源。出于可读性和实用性的原因,我不想将每几行代码包装到单独的try / catch块中。

我今天所拥有的是一个全能的捕获所有内容,并在关闭程序之前记录错误。从用户的角度来看这很好 - 干净关闭而不是应用程序崩溃 - 但对我来说不好,因为我只从异常中获取一般信息(例如“数组超出范围”),但不知道它来自何处。

删除catch-all并让程序崩溃不是更好吗?我可以指示客户让Windows创建应用程序崩溃转储(如上所述here )。使用转储文件,WinDbg会将我指向引发异常的代码中的位置。

3 个答案:

答案 0 :(得分:3)

您可以通过调用AddVectoredExceptionHandler 来注册自定义的矢量异常处理程序。

每当抛出异常时都会调用它,并且在其中可以生成堆栈跟踪,然后可以保存以进行日志记录。

编写代码来做到这一点并非完全无足轻重,但也不是火箭手术。

我从来没有亲自在C ++中完成它,但如果没有现成的库可以在某个地方使用它,如果你没有时间或倾向于自己做,我会感到惊讶。

答案 1 :(得分:0)

您可以抛出包含错误发生位置的异常以及原因:

throw std::string("could not open this file");

如果您不想为每个可能的错误编写不同的描述,可以使用标准宏__FILE__和__LINE __:

#define _MyError std::string("error in " __FILE__ + std::to_string(__LINE__))
// ...
throw _MyError;

如果源文件名和错误行不够,并且您需要更多信息,例如堆栈跟踪或内存值,则程序可以生成调试报告。 Google Breakpad是一个C ++库,允许您以便携方式执行此操作。来自wxWidgets库的类wxDebugReport是另一种选择。在Windows上,调试报告可能包含一个可以在Visual Studio中加载的minidump文件,并允许您以类似于调试的方式分析错误。

答案 2 :(得分:0)

  

最好不要删除所有内容并让程序运行   而不是崩溃?

你可以抓住所有人和

  • 写一条关于发生的致命错误的(更个人的)消息,强制关闭应用程序。不要让程序继续:你不知道发生了什么,在哪里。继续可能会损坏用户的数据,跟进错误等。
  • 告诉用户与您联系,详细说明他们做了什么以及发生了什么。
  • 告诉用户包含应用程序生成的日志文件。

如果你不做这样的事情,那么你也可以删除所有这些。

  

出于可读性和实用性的原因,我不想包装   每几行代码到单独的try / catch块中。

然而,如果您希望您的程序能够恢复,那么这正是您必须要做的。你能做的是

  • 告诉用户发生了什么,可能是导致它的输入错误。不要让它听起来技术性。
  • 保存用户输入的所有数据,以便他们的工作不会完全丢失
  • 你知道失败发生在哪一步。撤消该步骤,即丢弃对象/数据,然后返回到异常之前的点。
  • 恢复用户从第二点输入的数据,这样他们就不需要重复操作了。

关键是您的程序可以返回有效状态。