Luc*_*cas 6 c++ debugging boost exception debug-information
我正在努力为我的OSS应用程序添加异常和异常处理.例外从一开始就是一般的想法,但是我想找到一个好的异常框架,并且在开始使用它们之前,要完全理解C++异常处理约定和习惯用法.我在使用C#/ .Net,Python和其他使用异常的语言方面有很多经验.我对这个想法并不陌生(但远非主人).
在C#和Python中,当发生未处理的异常时,用户会获得一个很好的堆栈跟踪,并且通常会获得许多非常有用的无价调试信息.如果你正在开发一个OSS应用程序,让用户将这些信息粘贴到问题报告中......好吧,我只是说我发现没有它就很难生存.对于这个C++项目,我得到"应用程序崩溃",或者来自更明智的用户,"我做了X,Y和Z,然后它崩溃了".但我也想要调试信息!
我已经(并且非常困难)让我感到安心,因为我永远不会看到跨平台和交叉编译的方式获得C++异常堆栈跟踪,但我知道我可以获得函数名称和其他相关信息.
现在我想要那些未经处理的例外情况.我正在使用boost :: exception,他们有这个非常好的diagnostic_information thingamajig,它可以打印出(unmangled)函数名,文件,行,最重要的是,程序员添加到该异常的其他异常特定信息.
当然,我会尽可能地处理代码中的异常,但我认为我不会让一对夫妇溜走(当然是无意的).
所以我想做的是将我的主入口点包装在一个try块中catch,创建一个特殊的对话框,通知用户应用程序中发生了错误,当用户单击"更多"或"调试"时会显示更详细的信息信息"或其他什么.这将包含来自diagnostic_information的字符串.然后,我可以指示用户将此信息粘贴到问题报告中.
但是一种唠叨的直觉感觉告诉我,将一切都包装在一个试块中是一个非常糟糕的主意.我将要做什么愚蠢的事情?如果是(即使不是),有什么更好的方法来实现我想要的?
Han*_*ant 33
在main()中放置一个try/catch块是可以的,它不会导致任何问题.无论如何,该程序已经死于未处理的异常.在你寻求获得最重要的堆栈跟踪时,它根本没有帮助.当catch块捕获异常时,该信息是奇闻趣事.
捕获C++异常也不是很有用.程序死于从std :: exception派生的异常的几率非常小.虽然它可能发生.在C/C++应用程序中更有可能是由于硬件异常导致死亡,AccessViolation是数字uno.捕获它们需要main()方法中的__try和__except关键字.同样,很少有上下文可用,你基本上只有一个异常代码.AV还会告诉您哪个确切的内存位置导致异常.
这不仅仅是一个跨平台的问题,你无法在任何平台上获得良好的堆栈跟踪.没有可靠的方法来进行堆叠,有太多的优化(如framepointer遗漏)使这成为一个危险的旅程.它是C/C++方式:尽可能快地使它,不知道它爆炸时发生了什么.
你需要做的是用C/C++方式调试这些问题.您需要创建一个minidump.它大致类似于旧的"核心转储",即异常发生时过程映像的快照.那时候,你实际上已经完全转储了核心.已经取得了进展,现在它是"迷你",有点必要,因为一个完整的核心转储需要接近2千兆字节.它实际上很适合诊断程序状态.
在Windows上,通过调用SetUnhandledExceptionFilter()开始,您提供一个回调函数指针,该函数将在程序在未处理的异常上死亡时运行.任何异常,C++以及SEH.您的下一个资源是dbghelp.dll,可在Windows调试工具下载中找到.它有一个名为MiniDumpWriteDump()的入口点,它创建一个minidump.
一旦你获得了由MiniDumpWriteDump()创建的文件,你就会变得非常精彩.您可以在Visual Studio中加载.dmp文件,几乎就像它是一个项目.按F5和VS研磨掉一段时间,试图为进程中加载的DLL加载.pdb文件.您需要设置符号服务器,这对于获得良好的堆栈跟踪非常重要.如果一切正常,您将在抛出异常的确切位置获得"调试中断".使用堆栈跟踪.
要使这项工作顺利进行,您需要做的事情:
嗯,这就是我为我工作的公司所做的.工作得非常好,它将碰撞斗频率从数千减少到数十.给开源ffdshow组件创建者的个人信息:我热爱你.但是你不再崩溃了我们的应用程序!坏蛋.
将所有代码包装在一个try/catch块中是可以的。例如,它不会减慢其中任何内容的执行速度。事实上,我所有的程序都有(代码类似)这个框架:
int execute(int pArgc, char *pArgv[])
{
// do stuff
}
int main(int pArgc, char *pArgv[])
{
// maybe setup some debug stuff,
// like splitting cerr to log.txt
try
{
return execute(pArgc, pArgv);
}
catch (const std::exception& e)
{
std::cerr << "Unhandled exception:\n" << e.what() << std::endl;
// or other methods of displaying an error
return EXIT_FAILURE;
}
catch (...)
{
std::cerr << "Unknown exception!" << std::endl;
return EXIT_FAILURE;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5664 次 |
| 最近记录: |