You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
4.5 KiB
C++
138 lines
4.5 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
// Description : Support for Windows Error Reporting (WER)
|
|
|
|
|
|
#include "CrySystem_precompiled.h"
|
|
|
|
#ifdef WIN32
|
|
|
|
#include "System.h"
|
|
#include <windows.h>
|
|
#include <tchar.h>
|
|
#include "errorrep.h"
|
|
#include "ISystem.h"
|
|
|
|
#include <DbgHelp.h>
|
|
|
|
static WCHAR szPath[MAX_PATH + 1];
|
|
static WCHAR szFR[] = L"\\System32\\FaultRep.dll";
|
|
|
|
WCHAR* GetFullPathToFaultrepDll(void)
|
|
{
|
|
UINT rc = GetSystemWindowsDirectoryW(szPath, ARRAYSIZE(szPath));
|
|
if (rc == 0 || rc > ARRAYSIZE(szPath) - ARRAYSIZE(szFR) - 1)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
wcscat_s(szPath, szFR);
|
|
return szPath;
|
|
}
|
|
|
|
|
|
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
|
|
);
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
LONG WINAPI CryEngineExceptionFilterMiniDump(struct _EXCEPTION_POINTERS* pExceptionPointers, const char* szDumpPath, MINIDUMP_TYPE DumpType)
|
|
{
|
|
// note: In debug mode, this dll is loaded on startup anyway, so this should not incur an additional load unless it crashes
|
|
// very early during startup.
|
|
|
|
fflush(nullptr); // according to MSDN on fflush, calling fflush on null flushes all buffers.
|
|
HMODULE hndDBGHelpDLL = LoadLibraryA("DBGHELP.DLL");
|
|
|
|
if (!hndDBGHelpDLL)
|
|
{
|
|
CryLogAlways("Failed to record DMP file: Could not open DBGHELP.DLL");
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
|
|
MINIDUMPWRITEDUMP dumpFnPtr = (MINIDUMPWRITEDUMP)::GetProcAddress(hndDBGHelpDLL, "MiniDumpWriteDump");
|
|
if (!dumpFnPtr)
|
|
{
|
|
CryLogAlways("Failed to record DMP file: Unable to find MiniDumpWriteDump in DBGHELP.DLL");
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
|
|
HANDLE hFile = ::CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
CryLogAlways("Failed to record DMP file: could not open file '%s' for writing - error code: %d", szDumpPath, GetLastError());
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
|
|
_MINIDUMP_EXCEPTION_INFORMATION ExInfo;
|
|
ExInfo.ThreadId = ::GetCurrentThreadId();
|
|
ExInfo.ExceptionPointers = pExceptionPointers;
|
|
ExInfo.ClientPointers = NULL;
|
|
|
|
BOOL bOK = dumpFnPtr(GetCurrentProcess(), GetCurrentProcessId(), hFile, DumpType, &ExInfo, NULL, NULL);
|
|
::CloseHandle(hFile);
|
|
|
|
if (bOK)
|
|
{
|
|
CryLogAlways("Successfully recorded DMP file: '%s'", szDumpPath);
|
|
return EXCEPTION_EXECUTE_HANDLER; // SUCCESS! you can execute your handlers now
|
|
}
|
|
else
|
|
{
|
|
CryLogAlways("Failed to record DMP file: '%s' - error code: %d", szDumpPath, GetLastError());
|
|
}
|
|
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers)
|
|
{
|
|
if (g_cvars.sys_WER > 1)
|
|
{
|
|
char szScratch [_MAX_PATH];
|
|
const char* szDumpPath = gEnv->pCryPak->AdjustFileName("@log@/CE2Dump.dmp", szScratch, AZ_ARRAY_SIZE(szScratch), 0);
|
|
|
|
MINIDUMP_TYPE mdumpValue = (MINIDUMP_TYPE)(MiniDumpNormal);
|
|
if (g_cvars.sys_WER > 1)
|
|
{
|
|
mdumpValue = (MINIDUMP_TYPE)(g_cvars.sys_WER - 2);
|
|
}
|
|
|
|
return CryEngineExceptionFilterMiniDump(pExceptionPointers, szDumpPath, mdumpValue);
|
|
}
|
|
|
|
LONG lRet = EXCEPTION_CONTINUE_SEARCH;
|
|
WCHAR* psz = GetFullPathToFaultrepDll();
|
|
if (psz)
|
|
{
|
|
HMODULE hFaultRepDll = LoadLibraryW(psz);
|
|
if (hFaultRepDll)
|
|
{
|
|
pfn_REPORTFAULT pfn = (pfn_REPORTFAULT)GetProcAddress(hFaultRepDll, "ReportFault");
|
|
if (pfn)
|
|
{
|
|
pfn(pExceptionPointers, 0);
|
|
lRet = EXCEPTION_EXECUTE_HANDLER;
|
|
}
|
|
FreeLibrary(hFaultRepDll);
|
|
}
|
|
}
|
|
return lRet;
|
|
}
|
|
|
|
#endif // WIN32
|