软件Release 版本 Crash 堆栈信息收集

 
软件Release 版本 Crash 堆栈信息收集

比较详细的地址是:http://www.codeproject.com/debug/XCrashReportPt3.asp

不过作者考虑了没有vc等情况。
其实如果有vc使用ms 的 MiniDumpWriteDump 将会非常简单. 如下面100行左右搞定,理解、转换为unicode 编码都简单很多.只需要装入相应的头文件即可记录crash dump 文件。用vc打开dump 文件。按F5即可运行到crash地点
vc Release 工程必须设置:
链接器 ->调试-> 生成调试信息 是(/DEBUG)
链接器->优化->引用->消除未引用数据(/OPT:REF)

头文件 minidump.h

#pragma once
#include <windows.h>
#include <tchar.h>
#if _MSC_VER < 1300
#define DECLSPEC_DEPRECATED
// VC6: change this path to your Platform SDK headers
#include "c://dev7//vs//devtools//common//win32sdk//include//dbghelp.h"            // must be XP version of file
#else
// VC7: ships with updated headers
#include "dbghelp.h"
#endif

// based on dbghelp.h

class MiniDumper
{
    typedef BOOL (WINAPI* MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,
                                            CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
                                            CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
                                            CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
private:
    static LPCTSTR m_szAppName;
    static LONG WINAPI TopLevelFilter(struct _EXCEPTION_POINTERS *pExceptionInfo);
public:
    MiniDumper(LPCTSTR szAppName);
    ~MiniDumper();
};


//源文件 minidump.cpp

#include "minidump.h"
#include <assert.h>
#include <stdio.h>
#include <direct.h>

LPCTSTR MiniDumper::m_szAppName;
#ifndef _DEBUG
MiniDumper dumper(_T("xyj2007"));
#endif

MiniDumper::MiniDumper(LPCTSTR szAppName)
{
    // if this assert fires then you have two instances of MiniDumper which is not allowed
    assert( m_szAppName==NULL );            //确认只创建一个 minidumper
    m_szAppName =_tcsdup(szAppName);
    ::SetUnhandledExceptionFilter(TopLevelFilter);
}

MiniDumper::~MiniDumper()
{
    if(m_szAppName)
    {
        free( (void *) m_szAppName);
        m_szAppName = NULL;
    }
}

LONG MiniDumper::TopLevelFilter( struct _EXCEPTION_POINTERS *pExceptionInfo )
{
    LONG retval = EXCEPTION_CONTINUE_SEARCH;
    HWND hParent = NULL;                        // find a better value for your app

    // firstly see if dbghelp.dll is around and has the function we need
    // look next to the EXE first, as the one in System32 might be old
    // (e.g. Windows 2000)
    HMODULE hDll = NULL;
    TCHAR szDbgHelpPath[_MAX_PATH];

    if (GetModuleFileName( NULL, szDbgHelpPath, _MAX_PATH ))
    {
        TCHAR *pSlash = _tcsrchr( szDbgHelpPath, _T('//') );
        if (pSlash)
        {
            _tcscpy(pSlash+1, _T("DBGHELP.DLL"));
            hDll = ::LoadLibrary( szDbgHelpPath );
        }
    }

    if (hDll==NULL)
    {
        // load any version we can
        hDll = ::LoadLibrary(_T("DBGHELP.DLL"));
    }

    LPCTSTR szResult = NULL;

    if (hDll)
    {
        MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDll,"MiniDumpWriteDump");
        if (pDump)
        {
            TCHAR szDumpPath[_MAX_PATH];
            TCHAR szScratch [_MAX_PATH];

            // work out a good place for the dump file
            _tgetcwd(szDumpPath,_MAX_PATH);
            _tcscat( szDumpPath, _T("//"));

            _tcscat( szDumpPath, m_szAppName );
            _tcscat( szDumpPath, _T(".dmp"));

            // ask the user if they want to save a dump file
            if (::MessageBox(NULL,_T("程序发生意外,是否保存一个文件用于诊断?"),m_szAppName,MB_YESNO)==IDYES)
            {
                // create the file
                HANDLE hFile = ::CreateFile( szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
                                            FILE_ATTRIBUTE_NORMAL, NULL );

                if (hFile!=INVALID_HANDLE_VALUE)
                {
                    _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
                    ExInfo.ThreadId = ::GetCurrentThreadId();
                    ExInfo.ExceptionPointers = pExceptionInfo;
                    ExInfo.ClientPointers = NULL;

                    // write the dump
                    BOOL bOK = pDump( GetCurrentProcess(),GetCurrentProcessId(),hFile,MiniDumpNormal,&ExInfo,NULL,NULL);
                    if (bOK)
                    {
                        _stprintf( szScratch, _T("保存文件到:'%s'"), szDumpPath );
                        szResult = szScratch;
                        retval = EXCEPTION_EXECUTE_HANDLER;
                    }
                    else
                    {
                        _stprintf( szScratch, _T("保存文件到 '%s'失败,(错误号: %d)"), szDumpPath, GetLastError() );
                        szResult = szScratch;
                    }
                    ::CloseHandle(hFile);
                }
                else
                {
                    _stprintf( szScratch, _T("在'%s'创建 dump 文件失败,(错误号 %d)"), szDumpPath, GetLastError() );
                    szResult = szScratch;
                }
            }
        }
        else
        {
            szResult = _T("dbghelp.dll 文件太旧,不能支持MiniDumpWriteDump函数");
        }
    }
    else
    {
        szResult = _T("dbghelp.dll 文件不存在");
    }

    if (szResult)
    {
        ::MessageBox( NULL, szResult, m_szAppName, MB_OK );
    }

    return retval;
}

 

引用地址:http://hi.baidu.com/elseif/blog/item/c1124823d9e7894a9258079a.html 文章版权归原作者所有

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值