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. html的meta标签的charset应该用UTF-8还是utf-8?

    之前我也纠结过写html的时候是用<meta charset="UTF-8"/> 或者是 <meta charset="utf-8"/> ...

  2. Activex调试以及m_hWnd为空 解决办法

    1. 点击[开始]->[运行] 命令:regedit.2. 定位到HKEY_LOCALMACHINE -> SOFTWARE -> Microsoft -> Internet ...

  3. [Javascript] Validate Data with the Every() Method

    The every method returns true or false based on whether or not every item in the array passes the co ...

  4. Pandoc —— 标记语言转换工具(中文乱码问题)

    今次毕业设计,来个逼格高的,用 latex 编写.谁曾想,学院首先要收一份 word 版的.辣么多的 latex 公式如何转呀. Pandoc 是由 John MacFarlane 开发的标记语言转换 ...

  5. JVM调优2

    原文地址:https://blog.csdn.net/sun1021873926/article/details/78002118 一.什么是JVM  JVM是Java Virtual Machine ...

  6. 解决Eclipse中的卡死现象

    解决Eclipse中的卡死现象 取消验证 windows–>perferences–>validation 把 除了manual 下面的全部点掉,build下只留 classpath de ...

  7. ios开发事件处理之 :二:事件的产生与传递

    1.事件是怎么样产生与传递的? 当发生一个触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中.(队列是先进先出,而栈是先进后出) UIApplication会从事件队列中 ...

  8. linux文件管理小结之自己定义more

    1.more命令功能 more命令用于查看内容超过一屏的文本(相似于cat) 基本功能: 1.输入backspace :内容翻一屏 2.输入enter : 内容翻一行 3.输入q:退出 4.实时显示已 ...

  9. 于 Android NDK 的学习之旅-----数据传输(基本数据类型和数组传输)

    之前的一些文章都有涉及到上层和中间层的数据传输,简单来说,也就是参数和返回值的使用.因为中间层要做的最多的也就是数据传输与转换,下面来介绍下这方面的知识. 数据传输可分为 基本数据类型传输 和 引用数 ...

  10. 主从同步设置的重要参数log_slave_updates

    说明:最近部署了mysql的集群环境,详细如下M01和M02为主主复制,M01和R01为主从复制:在测试的过程中发现了以下问题: 1.M01和M02的主主复制是没有问题的(从M01写入数据能同步到M0 ...