Chinaunix首页 | 论坛 | 博客
  • 博客访问: 346961
  • 博文数量: 88
  • 博客积分: 1695
  • 博客等级: 上尉
  • 技术积分: 1380
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-06 15:48
个人简介

喜欢美食, 旅行..

文章分类

全部博文(88)

文章存档

2014年(2)

2013年(12)

2012年(14)

2010年(8)

2009年(52)

我的朋友

分类: C/C++

2012-11-11 21:21:58

1. 程序运行时缺陷跟踪.
1.1. 内存泄漏跟踪 < 请参考我的另一博文 windows下的内存泄漏排查 >
1.2. 最好还是避免手动分配内存的方式.<详细情况请查阅相关文档>
1.2.1. 使用智能指针(shared_ptr和unique_ptr已经是C++11的一部分)
std::auto_ptr && boost::share_ptr && boost::weak_ptr && boost::unique_ptr && boost::intrusive_ptr
1.2.2. 使用内存池 boost::pool && boost:object_pool && boost::signgleton_pool
1.2.3. 将C++11的Lambda Function和tr1::function结合起 
     < 请参考文章末尾的样例代码ScopeGuard.cpp >

2. 利用结构异常还原现场
2.1. 没有性能损失的简单方案
   < 请参考文章末尾的样例代码dumpminidump.cpp >
2.1.1. 运行时异常.MiniDumpWriteDump && GetExceptionInformation
2.1.2. 未捕获异常. SetUnhandledException() < 程序崩溃 >

3. 调试
3.1. WINDUB基本调试命令
 kb 显示call stack 内容  :kb 50, k, kb, kc, kd, kp, kP, kv(Display Stack Backtrace)
 !analyze -v 显示分析的详细信息。
 r 可以显示系统崩溃时的寄存器,和最后的命令状态。
 dd 显示当前内存地址,dd 参数:显示参数处的内存。
 u 可以显示反汇编的指令
 kv.bugcheck 可以显示出错的代码
3.2. 调试跟踪 Windows API < call 汇编指令是调用函数的意思 >
第一步:设置windows符号文件
第二步:symchk 获取符号文件(PDB)
获得c:\windows\system32下的所有文件的符号
symchk /r c:\windows\system32 /s SRV*c:\symbols\*
获得 c:\windows\system32\secur32.dll 的符号
symchk /r c:\windows\system32\secur32.dll /s SRV*c:\symbols\*
工具 http://files.cnblogs.com/ahuo/SymRetriever.zip
第三步:遇到 call、jmp指令,我们可以继续进去看看,从函数名中我们可以看到非常多的信息

ScopeGuard.cpp
  1. class ScopeGuard
  2. {
  3. public:
  4.     explicit ScopeGuard(std::function<void()> onExitScope)
  5.         : onExitScope_(onExitScope), dismissed_(false) }
  6.     ~ScopeGuard() {
  7.         if(!dismissed_) { onExitScope_(); }
  8.     }
  9.     void Dismiss() { dismissed_ = true}
  10. private:
  11.     std::function<void()> onExitScope_;
  12.     bool dismissed_;
  13. private: // noncopyable
  14.     ScopeGuard(ScopeGuard const&);
  15.     ScopeGuard& operator=(ScopeGuard const&);
  16. };

  17. int /*__stdcall _cdecl*/ main(int arc,char ** arv)
  18. {
  19.     HANDLE h1 = CreateFile(...);
  20.     ScopeGuard onExit([&] { CloseHandle(h1); });   
  21.     return 0;
  22. }
dumpminidump.cpp
  1. #include "dbghelp.h"
  2. #pragma comment(lib,"Dbghelp.lib")
  3. void _DumpMiniDump(LPTSTR fileName,PEXCEPTION_POINTERS excpInfo)
  4. {
  5.     wstring dumpFileName = fileName;
  6.     dumpFileName += L".dmp";

  7.     HANDLE hFile = CreateFile( dumpFileName.c_str(), GENERIC_READ | GENERIC_WRITE, 
  8.         0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 

  9.     MINIDUMP_EXCEPTION_INFORMATION eInfo;
  10.     eInfo.ThreadId = GetCurrentThreadId(); //把需要的信息添进去
  11.     eInfo.ExceptionPointers = excpInfo;
  12.     eInfo.ClientPointers = FALSE;

  13.     // Dump的类型是小型的, 节省空间. 可以参考MSDN生成更详细的Dump.
  14.     MiniDumpWriteDump(
  15.         GetCurrentProcess(),
  16.         GetCurrentProcessId(),
  17.         hFile,
  18.         MiniDumpNormal,
  19.         excpInfo ? &eInfo : NULL,
  20.         NULL,
  21.         NULL);

  22.     CloseHandle( hFile );
  23. }

  24. void DumpMiniDump(LPTSTR fileName)
  25. {
  26.     __try {
  27.         OutputDebugString(L"raising exception\r\n");
  28.         RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
  29.         // throw L"";
  30.     } __except(
  31.         _DumpMiniDump(fileName,GetExceptionInformation()),
  32.         EXCEPTION_EXECUTE_HANDLER ) {}
  33. }

  34. void test()
  35. {
  36.     __try {
  37.         DumpMiniDump(L"MiniDump");
  38.     }
  39.     __except(EXCEPTION_CONTINUE_EXECUTION)
  40.     {
  41.     }
  42. }
阅读(2129) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~