1.背景:

  在开发人员进行项目开发和调试代码时,有一个非常困扰的问题,就是程序在调试运行过程中会莫名其妙地异常退出。由于导致异常退出的问题非常多,因此在面对这种无任何提示的异常退出时,开发人员会非常无奈。因为他需要考虑最近的那些更改有可能导致这个错误的发生,万不得已,可能就需要把代码回退到某个版本,然后去慢慢验证了。这当然是非常影响工作效率的。

  后来,项目经理前段时间介绍了一个新的库,用这个库可以非常准确地定位上一次奔溃的出错位置。这样开发人员便可以在奔溃的位置添加断点,进行调试。

  自从知道有这个工具后,我就爱不释手。从此,再也不怕遇到程序异常退出的情况了。因为你知道,那里有一个助手帮你监视着程序的一举一动,随时等待你的召唤。

  下面就介绍一下这个工具,它的名字叫:**CrashRptProbe。**Probe是探针的意思,顾名思义,就是探测程序奔溃并发送报告的一个工具。这个工具在Github上的地址为:https://github.com/bitshares/devshares/tree/master/CrashRpt

2. CrashRptProbe的基本介绍:

  目前我是将这个库引入了VS2012开发C++的项目中,在其他开发工具和语言上还没有试过。

  这个工具是作为第三方库引入项目中的。它的地位就和之前引入的其他第三方库,如DCMTK, VTK, ITK, GTEST, OpenCV, log4cplus等一样。

  从Github上把这个包下载下来,并解压到项目中的thirdparty中即可。或者从以下的链接中下载这个包。

  具体的放置位置如下图所示: 

由于需要把该工具引入到项目中。因此需要将它在放置在和本项目的应用程序的入口函数main.cpp的同级目录内。并且需要定义一个当系统奔溃时,奔溃报告的存放位置。因此,在main.cpp的同级目录下,创建两个文件:
CrashHandler.h和CrashHandler.cpp。

CrashHandler.h的代码为:

  1. #ifndef _DXCRASHHANDLER_H_
  2. #define _DXCRASHHANDLER_H_
  3. #include <QString>
  4. class DxCrashHandler
  5. {
  6. public:
  7. DxCrashHandler();
  8. ~DxCrashHandler();
  9. private:
  10. QString AddAppPath(const QString relativepath);
  11. };
  12. #endif // _DXCRASHHANDLER_H_

CrashHandler.cpp的代码为:

  1. #include "CrashRpt.h"
  2. #include "DxCrashHandler.h"
  3. #include <QApplication>
  4. #include <QDir>
  5. #include <QMainWindow>
  6. #include <QMessageBox>
  7. QString DxCrashHandler::AddAppPath(const QString relativepath)
  8. {
  9. QDir root(QCoreApplication::applicationDirPath());
  10. return QDir::cleanPath(root.absoluteFilePath(relativepath));
  11. }
  12. // Define the callback function that will be called on crash
  13. int CALLBACK CrashCallback(CR_CRASH_CALLBACK_INFO* pInfo)
  14. {
  15. // The application has crashed!
  16. if ( pInfo->nStage == CR_CB_STAGE_PREPARE )
  17. {
  18. // Close log file here when necessary
  19. }
  20. else //CR_CB_STAGE_FINISH
  21. {
  22. QMessageBox::critical(QApplication::activeWindow(), "FTT3D", "There is some critical error in the application. So it will be closed. \nPlease send error reports and related information to the administrators. \nThat will help us to improve the product.");
  23. }
  24. // Return CR_CB_DODEFAULT to generate error report
  25. return CR_CB_NOTIFY_NEXT_STAGE ; //CR_CB_DODEFAULT;
  26. }
  27. DxCrashHandler::DxCrashHandler()
  28. {
  29. // Install crash reporting
  30. CR_INSTALL_INFO info;
  31. memset(&info, 0, sizeof(CR_INSTALL_INFO));
  32. info.cb = sizeof(CR_INSTALL_INFO);
  33. info.pszAppName = "TestAPP"; // Define application name.
  34. info.pszAppVersion = "1.0"; // Define application version.
  35. //Install all available exception handlers.
  36. info.dwFlags |= CR_INST_ALL_POSSIBLE_HANDLERS;
  37. info.dwFlags |= CR_INST_DONT_SEND_REPORT;
  38. info.dwFlags |= CR_INST_STORE_ZIP_ARCHIVES ;
  39. info.dwFlags |= CR_INST_AUTO_THREAD_HANDLERS ;
  40. //Set the error reprot path
  41. char lpsReportPath[MAX_PATH];
  42. strcpy_s(lpsReportPath,
  43. (LPCTSTR)(AddAppPath("ErrorReport")).toLocal8Bit().data()
  44. );
  45. info.pszErrorReportSaveDir = lpsReportPath;
  46. //     Article effective minidumps recommand the MiniDumpWithPrivateReadWriteMemory. But it cause the dump file up to 50 MB.
  47. //     So we use the MiniDumpWithIndirectlyReferencedMemory as alternative, which lost some information but ensure the
  48. //     a reasonable dump size.
  49. // Not all flag will be used due to some callback not provided in crashrpt licrary. If more dump needed, we must modify the
  50. // crashrpt code about crashdump.
  51. info.uMiniDumpType  = (MINIDUMP_TYPE)( // MiniDumpWithPrivateReadWriteMemory |
  52. MiniDumpWithDataSegs |
  53. MiniDumpWithHandleData |
  54. // The following parameters are supported by 6.2 and later
  55. MiniDumpWithIndirectlyReferencedMemory |
  56. MiniDumpWithFullMemoryInfo |
  57. MiniDumpWithThreadInfo |
  58. MiniDumpWithUnloadedModules
  59. );
  60. int nResult = crInstall(&info);
  61. if(nResult!=0)
  62. {
  63. QMessageBox::warning(NULL, "TestApp", "Prepare error report handler failed!");
  64. }
  65. //      Set crash callback function
  66. crSetCrashCallback(CrashCallback, NULL);
  67. // Add the last application log
  68. crAddFile2(
  69. (LPCTSTR)(AddAppPath("TestApp.App.log")).toLocal8Bit().data(),
  70. "TestApp.app.log",
  71. ("Log file"),
  72. CR_AF_MAKE_FILE_COPY |CR_AF_MISSING_FILE_OK );
  73. // Take screenshot of the app window at the moment of crash
  74. crAddScreenshot2(CR_AS_MAIN_WINDOW|CR_AS_USE_JPEG_FORMAT, 95);
  75. }
  76. DxCrashHandler::~DxCrashHandler()
  77. {
  78. //Uninstall crash reporting
  79. }

3. 在项目中引入Thirdparty - CrashRptProbe

根据以上的步骤,将CrashRptProbe的输入奔溃报告的路径指定后,我们便可以将它引入项目中了。

在项目的起始入口函数main.cpp中,需要实例化这个类的一个对象。

  1. int main(int argc, char *argv[])
  2. {
  3. QApplication a(argc, argv);
  4. // Initialize the crash handler
  5. DxCrashHandler crashhandler;
  6. return 0;
  7. }

之后,我们便可以在项目中进行测试了。


以下是我的测试步骤,我在原来某一个文件调用一个指针的方法时,去掉了这个指针的new。因此,当程序运行到这里的时候,便会由于指针未初始化而发生奔溃。

(1)当发生奔溃后,不用担心。这时在Bin目录下面会自动生成一个名字为ErrorReport的文件夹,如图所示。

(2)然后打开这个文件,会出现一些压缩文件和文件夹。根据时间排序,找到最近生成的一个文件夹并打开,便可以看到本次奔溃的报告文件,后缀名为dmp文件。 

(3)点击右键,选择VS2012打开该dmp文件,可以看到它会加载程序奔溃时的部分程序并打开。此时,在界面的右上部分的Actions下面,会有一个绿色的按钮,名称为 Debug with Native Only.

(4)点击这个绿色按钮后,会弹出一个异常信息提示框,如图所示。 
然后点击这个提示对话框上的Break按钮,则可以看到它已经帮我们定位到了该源代码的第97行。因为,我之前测试时并没有去New这个m_pVolume的指针,因此当程序运行到这里时便会奔溃。

可见,这个工具可以非常高效地帮我们记录程序出现异常的位置,提高我们debug代码和查找异常的效率。

 

参考链接:

CrashRptProbe在Github上的地址:

https://github.com/bitshares/devshares/tree/master/CrashRpt https://groups.google.com/forum/#!msg/crashrpt/UEnzFEiXyAo/e3M_butCBQAJ

http://blog.csdn.net/caoshangpa/article/details/76575920

优秀开源项目之四:CrashRptProbe,查询程序奔溃的利器的更多相关文章

  1. Golang优秀开源项目汇总, 10大流行Go语言开源项目, golang 开源项目全集(golang/go/wiki/Projects), GitHub上优秀的Go开源项目

    Golang优秀开源项目汇总(持续更新...)我把这个汇总放在github上了, 后面更新也会在github上更新. https://github.com/hackstoic/golang-open- ...

  2. github优秀开源项目大全-iOS

    github优秀开源项目大全-iOS APR 25TH, 2014 前言 本文旨在搜集github上优秀的开源项目 本文搜集的项目都是用于iOS开发 本文会持续更新… 完整客户端 ioctocat g ...

  3. 【转】近百个Android优秀开源项目

    近百个Android优秀开源项目   Android开发又将带来新一轮热潮,很多开发者都投入到这个浪潮中去了,创造了许许多多相当优秀的应用.其中也有许许多多的开发者提供了应用开源项目,贡献出他们的智慧 ...

  4. IOS-github优秀开源项目大全

    github优秀开源项目大全-iOS 前言 本文旨在搜集github上优秀的开源项目 本文搜集的项目都是用于iOS开发 本文会持续更新… 完整客户端 ioctocat github的iOS客户端,目前 ...

  5. Python优秀开源项目Rich源码解析

    这篇文章对优秀的开源项目Rich的源码进行解析,OMG,盘他.为什么建议阅读源码,有两个原因,第一,单纯学语言很难在实践中灵活应用,通过阅读源码可以看到每个知识点的运用场景,印象会更深,以后写代码的时 ...

  6. Android优秀开源项目

    本文转自:http://blog.tisa7.com/android_open_source_projects Android优秀开源项目 Android经典的开源项目其实非常多,但是国内的博客总是拿 ...

  7. jeecg智能开发平台参与-2013年度中国优秀开源项目评比

    JEECG正在参与<2013年度中国十大优秀开源项目> 评比,如果大家觉得JEECG还不错, 请投出你宝贵的一票,给我们以支持吧!!! [目前排名第8位] https://code.csd ...

  8. TypeScript 优秀开源项目大合集

    TypeScript出来有段时间了,也冒出了很多用TypeScript开发的优秀开源项目,搜寻了一些基于TypeScript项目,分享给大家: https://github.com/brookshi/ ...

  9. DolphinScheduler 荣获 2021 中国开源云联盟优秀开源项目奖!

    点击上方 蓝字关注我们 好消息,中国开源云联盟(China Open Source Cloud League,简称"COSCL")于近日公布 2021 杰出开源贡献者.优秀开源项目 ...

随机推荐

  1. ocx中用自定义消息去调用自定义事件

    硬件发送消息---->接收到消息后调用回调函数DWORD __stdcall CxxxCtrl::FVI_NotifyCallBack(void *FVINOTIFYCallbackCtx,UI ...

  2. js页面载入特效如何实现

    js页面载入特效如何实现 一.总结 一句话总结:可以加选择器(里面的字符串)作为参数,这样函数就可以针对不同选择器,就很棒了. 1.特效的原理是什么? 都是通过标签的位置和样式来实现特效的. 二.js ...

  3. Intellij IDEA中使用Debug

    Intellij IDEA中使用Debug Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用 ...

  4. POJ 1562 Oil Deposits (HDU 1241 ZOJ 1562) DFS

    现在,又可以和她没心没肺的开着玩笑,感觉真好. 思念,是一种后知后觉的痛. 她说,今后做好朋友吧,说这句话的时候都没感觉.. 我想我该恨我自己,肆无忌惮的把她带进我的梦,当成了梦的主角. 梦醒之后总是 ...

  5. RSA DH

    https://www.cnblogs.com/hiflora/archive/2013/07/04/3171775.html http://www.ruanyifeng.com/blog/2013/ ...

  6. 【转载】 Searching过程粗略梳理 分类: H4_SOLR/LUCENCE 2014-07-25 22:59 316人阅读 评论(0) 收藏

    转载自:http://www.cnblogs.com/huangfox/archive/2012/02/09/2344686.html solr-searching过程分析(一) --searchin ...

  7. [Angular] Create custom validators for formControl and formGroup

    Creating custom validators is easy, just create a class inject AbstractControl. Here is the form we ...

  8. 【机器学习实战】第7章 集成方法(随机森林和 AdaBoost)

    第7章 集成方法 ensemble method 集成方法: ensemble method(元算法: meta algorithm) 概述 概念:是对其他算法进行组合的一种形式. 通俗来说: 当做重 ...

  9. [Grid Layout] Use the minmax function to specify dynamically-sized tracks

    Using minmax() is an amazingly useful way to specify boundaries for the smallest and largest size a ...

  10. Opencv中integral计算积分图

    Paul Viola和Michael Jones在2001年首次将积分图应用在图像特征提取上,在他们的论文"Rapid Object Detection using a Boosted Ca ...