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. MHA 一主两从搭建-keepalived-手动切换

    环境介绍:主机名 IP MHA角色 MySQL角色node1 192.168.56.26 Node MySQL Master node2 192.168.56.27 Node MySQL Master ...

  2. stm32的电源

    有人说rtc会不工作

  3. 【t043】成绩查询

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 说起测试计算机的软件,排在第一位的就应当是SuperPi 了.它不但能良好的体现机器的整体水平,而且还 ...

  4. eclipse调试鼠标放上去显示变量值

    在eclipse中调试时,鼠标移动到变量上不显示值,这个原来自己也遇到过,没注意,反正就使用ctrl+shift+i嘛,也可以的,刚查了一下,解决方法如下: Window->Preference ...

  5. GDB(十)--调试正在运行的进程

    我编写了一个循环: long i;    for (i = 0; i < 999999; i++) {        mt.a += 1;        sleep(1);    }把它编译成a ...

  6. 自行实现透明的控件如Panel GroupBox(使用不需要重绘父控件的效果,一切都因为窗口有了WS_EX_TRANSPARENT属性)

    CSDN的Blog开通了.我想这里的Blog作为今后自己回答别人问题的时候,收藏答案的地方很不错呢. 因为社区的贴子早晚都会沉下去,查找起来很不方便,甚至再也找不到呢. Q: http://commu ...

  7. BootStrap让两个控件在一行显示

    <div class="row"> <div> <label class="form-inline">参加单位:<in ...

  8. 浅谈struts2的国际化----i18n

    可能大家在使用struts框架的时候,偶尔会看到这个词: i18n.也就是 Internationalization    i 开头,n 结尾. 总共18个字母,今天的主要内容就是环绕这 四个字母. ...

  9. [Angular Unit Testing] Testing Services with dependencies

    import { Http, Response, ResponseOptions } from '@angular/http'; import { TestBed } from '@angular/c ...

  10. [Git] Use git add --patch for better commit history and mitigating bugs

    Let's split our changes into separate commits. We'll be able to check over our changes before stagin ...