hur.cn - 华软网

 热门搜索

MFC 无法生成dump的问题

  作者:未知    来源:网络    更新时间:2011/9/7
C++">
网上的2个异常捕获类

struct MiniDumperCritialSection
{
CRITICAL_SECTION cls;
BOOL bInit;
MiniDumperCritialSection()
{
}
~MiniDumperCritialSection()
{
if(bInit == TRUE)
{
DeleteCriticalSection(&cls);
bInit = FALSE;
}
}
void Init()
{
InitializeCriticalSection(&cls);
bInit = TRUE;
}
void Enter()
{
EnterCriticalSection(&cls);
}
void Leave()
{
LeaveCriticalSection(&cls);
}
}m_clsMiniDumper;

class MiniDumper
{
protected:
    MiniDumper() 

m_clsMiniDumper.Init();
::SetErrorMode(SEM_NOGPFAULTERRORBOX);
::SetUnhandledExceptionFilter(&MiniDumper::TopLevelExceptionFilter); 
}
    ~MiniDumper() {};
private:
    MiniDumper(const MiniDumper&);
    const MiniDumper& operator=(const MiniDumper&);

public:
    static MiniDumper* Get()
    {
m_clsMiniDumper.Init();
        static MiniDumper dumper;
        return &dumper;
    }

    void Init(const String& dumpFilePath = String(), const String& appVersion = _T("1.0.0.0"))
    {
        if (!dumpFilePath.empty() && ::PathIsDirectory(dumpFilePath.c_str()))
            m_DumpFilePath = dumpFilePath;
        else
        {
            TCHAR appPath[MAX_PATH];
            ::GetModuleFileName(NULL, appPath, MAX_PATH);
            ::PathRemoveFileSpec(appPath);
            m_DumpFilePath = appPath;
        }

        m_AppVersion = appVersion;
    }

    String GetDumpFile() const
    {
        SYSTEMTIME st;
        ::GetLocalTime(&st);
        TCHAR dt[11];
        wsprintf(dt, _T("%02d%02d%02d%02d%02d"), st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);

        TCHAR appPath[MAX_PATH];
        ::GetModuleFileName(NULL, appPath, MAX_PATH);
        ::PathRemoveExtension(appPath);

        String file(m_DumpFilePath);
        file += _T("\\");
        file += ::PathFindFileName(appPath);
        file += _T("_") + m_AppVersion + _T("_");
        file += dt;
        file += _T(".dmp");
        return file;
    }

//private:
public:
    static LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS* ep)
    {
DWL(_T("MINI"),_T("Start"));
m_clsMiniDumper.Enter();
        LONG ret = EXCEPTION_CONTINUE_SEARCH;

        TCHAR dbgHelpDLL[MAX_PATH];
        ::GetModuleFileName(NULL, dbgHelpDLL, MAX_PATH);

        ::PathRemoveFileSpec(dbgHelpDLL);
        ::PathAppend(dbgHelpDLL, _T("dbghelp.dll"));

        HMODULE module = ::LoadLibrary(dbgHelpDLL);
        if (module == NULL)
{
//AfxMessageBox("Load dbghelp.dll Error!");
DWL(_T("MINI"),_T("Load dbghelp.dll Error!"));
m_clsMiniDumper.Leave();
            return ret;
}

        PFNWRITEDUMP MiniDumpWriteDump = (PFNWRITEDUMP)::GetProcAddress(module, "MiniDumpWriteDump");
        if (MiniDumpWriteDump != NULL)
        {
            String dumpFile = MiniDumper::Get()->GetDumpFile();
            HANDLE file = ::CreateFile(dumpFile.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
                                       FILE_ATTRIBUTE_NORMAL, NULL);
            if (file == INVALID_HANDLE_VALUE)
{
m_clsMiniDumper.Leave();
DWL(_T("MINI"),_T("INVALID_HANDLE_VALUE Stop"));
                return ret;
}

            _MINIDUMP_EXCEPTION_INFORMATION mdei;
            mdei.ThreadId = ::GetCurrentThreadId();
            mdei.ExceptionPointers = ep;
            mdei.ClientPointers = NULL;

            MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)(MiniDumpWithPrivateReadWriteMemory |
                                                MiniDumpWithDataSegs |
                                                MiniDumpWithHandleData |
                                                /*MiniDumpWithFullMemoryInfo |*/
                                                MiniDumpWithThreadInfo /*|
                                                MiniDumpWithUnloadedModules*/);

            if (MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), file, mdt, &mdei, NULL, NULL))
            {
                //::MessageBox(NULL, dumpFile.c_str(), _T("Crash Report!"), MB_TOPMOST | MB_ICONSTOP);
                const String openDmp(_T("/select,") + dumpFile);
                ::ShellExecute(NULL, _T("open"), _T("explorer.exe"), openDmp.c_str(), NULL, SW_SHOWNORMAL);
                ret = EXCEPTION_EXECUTE_HANDLER;
            }
else
{
//AfxMessageBox(_T("MiniDumpWriteDump Result Failure!"));
DWL(_T("MINI"),_T("MiniDumpWriteDump Result Failure!"));
ret = EXCEPTION_EXECUTE_HANDLER;
}

            CloseHandle(file);
        }
m_clsMiniDumper.Leave();
DWL(_T("MINI"),_T("Stop"));
        return ret;
    }

private:
    String m_DumpFilePath;
    String m_AppVersion;
};

}


class Exception
{
public:
static void MapSEtoCE(void ) {_set_se_translator(TranslateSEtoCE); }
operator DWORD() { return er.ExceptionCode; }
PEXCEPTION_POINTERS GetPEXCEPTION_POINTERS(){return pExp;}
private:
Exception(PEXCEPTION_POINTERS pep)
{
er = *pep->ExceptionRecord;
tx = *pep->ContextRecord;
pExp = pep;
}

static void _cdecl TranslateSEtoCE(UINT dwEC, PEXCEPTION_POINTERS pep)
{
throw Exception(pep );
}
private:
EXCEPTION_RECORD er;
CONTEXT tx;
PEXCEPTION_POINTERS pExp;
};

//实际调用
qp::MiniDumper::Get()->Init();
Exception::MapSEtoCE();
try
{
CMyDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
//  “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
//  “取消”来关闭对话框的代码
}
}
catch(Exception se)
{
DWL(_T("Mini"),_T("catch"));
qp::MiniDumper::TopLevelExceptionFilter(se.GetPEXCEPTION_POINTERS());
}


这样还是没办法产生dump文件。。
---华软 网友回答---
没人回
---华软网友回复---
异常回调要在入口函数设置的,我的DUMP一直在WIN32下使用,没有问题,

只要是用到了C++库,异常都会生成DUMP文件,以前遇到过DELPH写的DLL,里面异常时没有写。

先确定你找的代码没问题,生成DUMP几条语句就可以了。

还有就是回调设置在MFC的入口,看看能不能生成。
---华软网友回复---
常规异常都能捕获到,DUMP能够生成,某些异常不能(大概是多线程并发访问没有上锁之类的)

MFC 入口被封装了
_tWinMain
调用
AfxWinMain
调用
CMyApp::InitInstance()

InitInstance我在这方法里 DoModal 产生消息循环之前截取的
现在改到InitInstance方法内顶端 回调设置 并 try catch 试试
---华软网友回复---
InitInstance 在 Run 方法之前执行。。
InitInstance 里设置不太好

我把_tWinMain 那个 appmodul.cpp 拷贝到自己的cpp里 设置回调,并try catch 
再看看结果
---华软网友回复---
还是只能写在MyApp::InitInstance()

自定义appmodul.cpp Release版有很多错误

悲剧      
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。