如何让QT应用程序编写崩溃日志

问题描述:

我正在开发Qt,Windows中的项目, 我使用Qt版本4.1.4和VC6 IDE编译项目,产品的大部分使用都在WindowsXP上。如何让QT应用程序编写崩溃日志

我经常收到来自测试人员和客户的崩溃报告,这些报告没有修复模式,也没有在我的开发环境中重现。

所以我得出结论,我需要从我的程序中编写一个崩溃日志,以便在程序崩溃时总是收到调用堆栈。

在linux中,我知道它可以做到与一些信号处理分段故障。但如何在Windows/C++中做同样的事情?

我试图在谷歌搜索找到一些现成的解决方案,但没有任何运气。

关于任何第三方工具/库(免费或许可)的建议也被接受,但请不要建议任何方法,我必须修改我的模块中的每个功能来获取日志,因为该项目是巨大的,我可以买不起。

在此先感谢。

更新。 我已经将StackWalker附加到了我的代码中(有点麻烦_MBCS & UNICODE),但至少设法附加它。

我的主要文件看起来像下面,

class MyStackWalker : public StackWalker 
{ 
    FILE *sgLogFile; 
    public: 
    MyStackWalker() : StackWalker() 
    { 
    sgLogFile = fopen("ThisIsWhatIcallLog.log", "w"); 
    } 
    MyStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) 
    { 
    } 
    virtual void OnOutput(LPCSTR szText) 
    { 
     printf(szText); 
     fprintf(sgLogFile, "%s",szText); 
     fclose(sgLogFile); 
     StackWalker::OnOutput(szText); 
    } 
}; 

LONG Win32FaultHandler(struct _EXCEPTION_POINTERS * ExInfo) 
{ 
    MyStackWalker sw; 
    sw.ShowCallstack(); 
    return EXCEPTION_EXECUTE_HANDLER; 
} 

void InstallFaultHandler() 
{ 
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) Win32FaultHandler); 
} 

,但我得到链接错误,现在符号都没有找到,

main.obj : error LNK2001: unresolved external symbol "public: int __thiscall StackWalker::ShowCallstack(void *,struct _CONTEXT const *,int (__stdcall*)(void *,unsigned __int64,void *,int,unsigned long *,void *),void *)" ([email protected]@@[email protected]@[email protected]@Z) 
main.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall StackWalker::OnDbgHelpErr(char const *,int,unsigned __int64)([email protected]@@[email protected]) 
main.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall StackWalker::OnLoadModule(char const *,char const *,unsigned __int64,int,int,char const *,char const *,unsigned __int64)" ([email protected]@@[email protected]) 
main.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall StackWalker::OnSymInit(char const *,int,char const *)" ([email protected]@@[email protected]) 
main.obj : error LNK2001: unresolved external symbol "public: __thiscall StackWalker::StackWalker(int,char const *,int,void *)" ([email protected]@[email protected]@Z) 
release/Prog.exe : fatal error LNK1120: 5 unresolved externals 
Error executing link.exe. 

我已经修改了StackWalker.cpp文件,以适应UNICODE支持,将“_tcscat_s”替换为“wcscat”。

你能看到,这里怎么回事?

+0

请记住,您的用户可能会调用任何意外行动“死机”。这包括挂起,图形损坏,甚至错误的数据。崩溃日志只会捕获真正的崩溃。 – MSalters

+0

你好MSalters,谢谢你的回复,是的,我明白,只有“真正崩溃”,休息我可以管理用户提供的错误跟踪系统中的信息 – maxchirag

对于跨平台应用程序Breakpad可能是更好的解决方案。但Windows的简单方法是通过SetUnhandledExceptionFilter设置未处理的异常处理程序,并在处理程序中使用WriteMiniDumpEx写入小型转储(需要配置)。

example

+0

你好,我尝试了一些基于SetUnHandledExceptionFilter的解决方案,但他们似乎没有什么帮助,谷歌的breakpad在获取崩溃日志(它要求设置服务器和这些东西,基本上很差的文档)方面似乎非常复杂,任何简单的容易与Qt + Windows一起使用会非常好。仍然在寻找一个好的答案 – maxchirag

+0

添加了示例链接。两件事你要检查。首先 - 你有安装dbghelp.dll吗?它并未安装在旧的MS操作系统上,因此您必须将其与您的应用程序一起分发。其次 - 确保QT不处理未处理的异常(或者在这种情况下手动处理QT处理程序中的TopLevelFilter(0)) - 如果不是异常信息,您仍将获得堆栈。 – elevener

Google Breakpad是一个跨平台的崩溃报告库,看起来很有用。

另请参阅StackWalker了解用于获取堆栈跟踪的一些仅限于Windows的代码。

此外,通过覆盖QCoreApplication::notify并捕获所有异常(包括异常情况,如Windows上的堆栈溢出和访问冲突)来安装事件过滤器是个不错的主意。

+0

我会尝试使用谷歌breakpad首先,让我们希望最好的,其他明智的我会去QCoreApplicaton ::通知,...无论如何感谢您的回答 – maxchirag

+0

再次,我尝试了一些基于SetUnHandledExceptionFilter的解决方案,但他们似乎没有太大的帮助,Google的breakpad在获取崩溃日志方面似乎非常复杂(它要求设置服务器等等,基本上很差文档),任何与Qt + Windows一起使用的简单易用的应用程序都非常好。仍然在寻找一个好的答案 – maxchirag

+0

@maxchirag:我已经添加了一个适用于Windows的解决方案的链接,您应该可以将它集成到您​​的Qt应用程序中。 – Macke