資源簡介
在用qt編寫程序時經常會遇到崩潰問題,如果抓取不到crash堆棧信息就會對崩潰問題束手無策,只能對其進行復現,推斷。
該程序展示如何獲取crash堆棧信息

代碼片段和文件信息
#include?“ccrashstack.h“
#include?
#include?
//
//??ccrashstack.cpp
//
//
//??Created?by?Lan?huaiyu?on?9/27/13.
//??Copyright?2013?CCrashStack.?All?rights?reserved.
//
CCrashStack::CCrashStack(PEXCEPTION_POINTERS?pException)
{
????m_pException?=?pException;
}
QString?CCrashStack::GetModuleByRetAddr(PBYTE?Ret_Addr?PBYTE?&?Module_Addr)
{
????MODULEENTRY32 M?=?{sizeof(M)};
????HANDLE hSnapshot;
????wchar_t?Module_Name[MAX_PATH]?=?{0};
????hSnapshot?=?CreateToolhelp32Snapshot(TH32CS_SNAPMODULE?0);
????if?((hSnapshot?!=?INVALID_HANDLE_VALUE)?&&
????????????Module32First(hSnapshot?&M))
????{
????????????do
????????????{
????????????????????if?(DWORD(Ret_Addr?-?M.modbaseAddr)?seSize)
????????????????????{
????????????????????????????lstrcpyn(Module_Name?M.szExePath?MAX_PATH);
????????????????????????????Module_Addr?=?M.modbaseAddr;
????????????????????????????break;
????????????????????}
????????????}?while?(Module32Next(hSnapshot?&M));
????}
????CloseHandle(hSnapshot);
????QString?sRet?=?QString::fromWCharArray(Module_Name);
????return?sRet;
}
QString?CCrashStack::GetCallStack(PEXCEPTION_POINTERS?pException)
{
????????PBYTE Module_Addr_1;
????????char?bufer[256]={0};
????????QString?sRet;
????????typedef?struct?STACK
????????{
????????????????STACK?* Ebp;
????????????????PBYTE Ret_Addr;
????????????????DWORD Param[0];
????????}?STACK?*?PSTACK;
????????STACK Stack?=?{0?0};
????????PSTACK Ebp;
????????if?(pException) //fake?frame?for?exception?address
????????{
????????????????Stack.Ebp?=?(PSTACK)pException->ContextRecord->Ebp;
????????????????Stack.Ret_Addr?=?(PBYTE)pException->ExceptionRecord->ExceptionAddress;
????????????????Ebp?=?&Stack;
????????}
????????else
????????{
????????????????Ebp?=?(PSTACK)&pException?-?1; //frame?addr?of?Get_Call_Stack()
????????????????//?Skip?frame?of?Get_Call_Stack().
????????????????if?(!IsBadReadPtr(Ebp?sizeof(PSTACK)))
????????????????????????Ebp?=?Ebp->Ebp; //caller?ebp
????????}
????????//?Break?trace?on?wrong?stack?frame.
????????for?(;?!IsBadReadPtr(Ebp?sizeof(PSTACK))?&&?!IsBadCodePtr(FARPROC(Ebp->Ret_Addr));
?????????????????Ebp?=?Ebp->Ebp)
????????{
????????????????//?If?module?with?Ebp->Ret_Addr?found.
????????????????memset(bufer0?sizeof(0));
????????????????sprintf(bufer?“\n%08X??“?(unsigned?int)Ebp->Ret_Addr);
????????????????sRet.append(bufer);
????????????????QString?moduleName?=?this->GetModuleByRetAddr(Ebp->Ret_Addr?Module_Addr_1)?;
????????????????if?(moduleName.length()?>?0)
????????????????{
????????????????????sRet.append(moduleName);
????????????????}
????????}
????????return?sRet;
}?//Get_Call_Stack
QString?CCrashStack::GetVersionStr()
{
????????OSVERSIONINFOEX V?=?{sizeof(OSVERSIONINFOEX)}; //EX?for?NT?5.0?and?later
????????if?(!GetVersionEx((POSVERSIONINFO)&V))
????????{
????????????????ZeroMemory(&V?sizeof(V));
???????????????
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????文件???????6604??2013-09-30?11:27??TestCrash\ccrashstack.cpp
?????文件????????593??2013-09-30?11:26??TestCrash\ccrashstack.h
?????文件????????301??2013-09-30?11:16??TestCrash\dialog.cpp
?????文件????????332??2013-09-30?10:33??TestCrash\dialog.h
?????文件????????738??2013-09-30?10:32??TestCrash\dialog.ui
?????文件????????943??2013-09-30?11:01??TestCrash\main.cpp
?????文件????????465??2013-09-30?10:53??TestCrash\TestCrash.pro
?????文件??????23496??2013-09-30?11:25??TestCrash\TestCrash.pro.user
?????目錄??????????0??2013-09-30?10:28??TestCrash
-----------?---------??----------?-----??----
????????????????33472????????????????????9
- 上一篇:物聯網信息安全
- 下一篇:QT下實現類似QQ聊天窗口tab控件
評論
共有 條評論