1. 程序运行时缺陷跟踪.
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
- class ScopeGuard
- {
- public:
- explicit ScopeGuard(std::function<void()> onExitScope)
- : onExitScope_(onExitScope), dismissed_(false) { }
- ~ScopeGuard() {
- if(!dismissed_) { onExitScope_(); }
- }
- void Dismiss() { dismissed_ = true; }
- private:
- std::function<void()> onExitScope_;
- bool dismissed_;
- private: // noncopyable
- ScopeGuard(ScopeGuard const&);
- ScopeGuard& operator=(ScopeGuard const&);
- };
- int /*__stdcall _cdecl*/ main(int arc,char ** arv)
- {
- HANDLE h1 = CreateFile(...);
- ScopeGuard onExit([&] { CloseHandle(h1); });
- return 0;
- }
dumpminidump.cpp
- #include "dbghelp.h"
- #pragma comment(lib,"Dbghelp.lib")
- void _DumpMiniDump(LPTSTR fileName,PEXCEPTION_POINTERS excpInfo)
- {
- wstring dumpFileName = fileName;
- dumpFileName += L".dmp";
- HANDLE hFile = CreateFile( dumpFileName.c_str(), GENERIC_READ | GENERIC_WRITE,
- 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
- MINIDUMP_EXCEPTION_INFORMATION eInfo;
- eInfo.ThreadId = GetCurrentThreadId(); //把需要的信息添进去
- eInfo.ExceptionPointers = excpInfo;
- eInfo.ClientPointers = FALSE;
- // Dump的类型是小型的, 节省空间. 可以参考MSDN生成更详细的Dump.
- MiniDumpWriteDump(
- GetCurrentProcess(),
- GetCurrentProcessId(),
- hFile,
- MiniDumpNormal,
- excpInfo ? &eInfo : NULL,
- NULL,
- NULL);
- CloseHandle( hFile );
- }
- void DumpMiniDump(LPTSTR fileName)
- {
- __try {
- OutputDebugString(L"raising exception\r\n");
- RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
- // throw L"";
- } __except(
- _DumpMiniDump(fileName,GetExceptionInformation()),
- EXCEPTION_EXECUTE_HANDLER ) {}
- }
- void test()
- {
- __try {
- DumpMiniDump(L"MiniDump");
- }
- __except(EXCEPTION_CONTINUE_EXECUTION)
- {
- }
- }
阅读(2140) | 评论(0) | 转发(0) |