Browse Source

Implement pfCrashHandler

pfCrashHandler includes a client that watches plClient for crashes. When
it detects a crash, it lets the plCrashSrv (plCrashHandler.exe) know about
it. We then produce a mninidump, then signal the client that it's OK to
show a crash dialog. See http://www.nynaeve.net/?p=128 for a good
explanation of why I split the crash logic into another process.
Adam Johnson 13 years ago
parent
commit
14279794f7
  1. 1
      Sources/Plasma/Apps/CMakeLists.txt
  2. 1
      Sources/Plasma/Apps/plClient/CMakeLists.txt
  3. 69
      Sources/Plasma/Apps/plClient/winmain.cpp
  4. 22
      Sources/Plasma/Apps/plCrashHandler/CMakeLists.txt
  5. 72
      Sources/Plasma/Apps/plCrashHandler/main.cpp
  6. 1
      Sources/Plasma/FeatureLib/CMakeLists.txt
  7. 21
      Sources/Plasma/FeatureLib/pfCrashHandler/CMakeLists.txt
  8. 60
      Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.cpp
  9. 58
      Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.h
  10. 138
      Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCli.cpp
  11. 70
      Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCli.h
  12. 52
      Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCommon.h
  13. 117
      Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.cpp
  14. 68
      Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.h
  15. 70
      Sources/Plasma/FeatureLib/pfCrashHandler/plCrash_Private.h

1
Sources/Plasma/Apps/CMakeLists.txt

@ -1,5 +1,6 @@
add_subdirectory(plClient) add_subdirectory(plClient)
add_subdirectory(plClientPatcher) add_subdirectory(plClientPatcher)
add_subdirectory(plCrashHandler)
add_subdirectory(plPythonPack) add_subdirectory(plPythonPack)
add_subdirectory(plUruLauncher) add_subdirectory(plUruLauncher)
add_subdirectory(plFileSecure) add_subdirectory(plFileSecure)

1
Sources/Plasma/Apps/plClient/CMakeLists.txt

@ -79,6 +79,7 @@ target_link_libraries(plClient pfCharacter)
target_link_libraries(plClient pfConditional) target_link_libraries(plClient pfConditional)
target_link_libraries(plClient pfConsole) target_link_libraries(plClient pfConsole)
target_link_libraries(plClient pfConsoleCore) target_link_libraries(plClient pfConsoleCore)
target_link_libraries(plClient pfCrashHandler)
target_link_libraries(plClient pfCsrSrv) target_link_libraries(plClient pfCsrSrv)
target_link_libraries(plClient pfGameGUIMgr) target_link_libraries(plClient pfGameGUIMgr)
target_link_libraries(plClient pfGameMgr) target_link_libraries(plClient pfGameMgr)

69
Sources/Plasma/Apps/plClient/winmain.cpp

@ -56,6 +56,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plClient.h" #include "plClient.h"
#include "plClientResMgr/plClientResMgr.h" #include "plClientResMgr/plClientResMgr.h"
#include "pfCrashHandler/plCrashCli.h"
#include "plNetClient/plNetClientMgr.h" #include "plNetClient/plNetClientMgr.h"
#include "plNetClient/plNetLinkingMgr.h" #include "plNetClient/plNetLinkingMgr.h"
#include "plInputCore/plInputManager.h" #include "plInputCore/plInputManager.h"
@ -120,6 +121,10 @@ plClient *gClient;
bool gPendingActivate = false; bool gPendingActivate = false;
bool gPendingActivateFlag = false; bool gPendingActivateFlag = false;
#ifndef HS_DEBUGGING
static plCrashCli s_crash;
#endif
static bool s_loginDlgRunning = false; static bool s_loginDlgRunning = false;
static CEvent s_statusEvent(kEventManualReset); static CEvent s_statusEvent(kEventManualReset);
static UINT s_WmTaskbarList = RegisterWindowMessage("TaskbarButtonCreated"); static UINT s_WmTaskbarList = RegisterWindowMessage("TaskbarButtonCreated");
@ -1343,10 +1348,6 @@ BOOL CALLBACK SplashDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
return 0; return 0;
} }
static char sStackTraceMsg[ 10240 ] = "";
void printStackTrace( char* buffer, int bufferSize, unsigned long stackPtr = 0, unsigned long opPtr = 0 );
//void StackTraceFromContext( HANDLE hThread, CONTEXT *context, char *outputBuffer );
BOOL CALLBACK ExceptionDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) BOOL CALLBACK ExceptionDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{ {
static char *sLastMsg = nil; static char *sLastMsg = nil;
@ -1383,63 +1384,21 @@ BOOL CALLBACK ExceptionDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA
return 0; return 0;
} }
#ifndef HS_DEBUGGING
LONG WINAPI plCustomUnhandledExceptionFilter( struct _EXCEPTION_POINTERS *ExceptionInfo ) LONG WINAPI plCustomUnhandledExceptionFilter( struct _EXCEPTION_POINTERS *ExceptionInfo )
{ {
const char *type = nil; // Before we do __ANYTHING__, pass the exception to plCrashHandler
switch( ExceptionInfo->ExceptionRecord->ExceptionCode ) s_crash.ReportCrash(ExceptionInfo);
{
case EXCEPTION_ACCESS_VIOLATION: type = "Access violation"; break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: type = "Array bounds exceeded"; break;
case EXCEPTION_BREAKPOINT: type = "Breakpoint"; break;
case EXCEPTION_DATATYPE_MISALIGNMENT: type = "Datatype misalignment"; break;
case EXCEPTION_FLT_DENORMAL_OPERAND: type = "Floating operand denormal"; break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO: type = "Floating-point divide-by-zero"; break;
case EXCEPTION_FLT_INEXACT_RESULT: type = "Floating-point inexact result"; break;
case EXCEPTION_FLT_INVALID_OPERATION: type = "Floating-point invalid operation"; break;
case EXCEPTION_FLT_OVERFLOW: type = "Floating-point overflow"; break;
case EXCEPTION_FLT_STACK_CHECK: type = "Floating-point stack error"; break;
case EXCEPTION_FLT_UNDERFLOW: type = "Floating-point underflow"; break;
case EXCEPTION_ILLEGAL_INSTRUCTION: type = "Illegal instruction"; break;
case EXCEPTION_IN_PAGE_ERROR: type = "Exception in page"; break;
case EXCEPTION_INT_DIVIDE_BY_ZERO: type = "Integer divide-by-zero"; break;
case EXCEPTION_INT_OVERFLOW: type = "Integer overflow"; break;
case EXCEPTION_INVALID_DISPOSITION: type = "Invalid disposition"; break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION: type = "Noncontinuable exception"; break;
case EXCEPTION_PRIV_INSTRUCTION: type = "Private instruction"; break;
case EXCEPTION_SINGLE_STEP: type = "Single-step"; break;
case EXCEPTION_STACK_OVERFLOW: type = "Stack overflow"; break;
}
char prodName[256];
wchar_t productString[256];
ProductString(productString, arrsize(productString));
StrToAnsi(prodName, productString, arrsize(prodName));
sprintf( sStackTraceMsg, "%s\r\nException type: %s\r\n", prodName, ( type != nil ) ? type : "(unknown)" ); // Now, try to create a nice exception dialog after plCrashHandler is done.
s_crash.WaitForHandle();
HWND parentHwnd = (gClient == nil) ? GetActiveWindow() : gClient->GetWindowHandle();
DialogBoxParam(gHInst, MAKEINTRESOURCE(IDD_EXCEPTION), parentHwnd, ExceptionDialogProc, NULL);
printStackTrace( sStackTraceMsg, sizeof( sStackTraceMsg ), ExceptionInfo->ContextRecord->Ebp, (unsigned long)ExceptionInfo->ExceptionRecord->ExceptionAddress ); // Trickle up the handlers
/// Print the info out to a log file as well
hsUNIXStream log;
wchar_t fileAndPath[MAX_PATH];
PathGetLogDirectory(fileAndPath, arrsize(fileAndPath));
PathAddFilename(fileAndPath, fileAndPath, L"stackDump.log", arrsize(fileAndPath));
if( log.Open( fileAndPath, L"wt" ) )
{
log.WriteString( sStackTraceMsg );
log.Close();
}
/// Hopefully we can access this resource, even given the exception (i.e. very-bad-error) we just experienced
if(TGIsCider || (::DialogBoxParam( gHInst, MAKEINTRESOURCE( IDD_EXCEPTION ), ( gClient != nil ) ? gClient->GetWindowHandle() : nil,
ExceptionDialogProc, (LPARAM)sStackTraceMsg ) == -1) )
{
// The dialog failed, so just fallback to a standard message box
hsMessageBox( sStackTraceMsg, "UruExplorer Exception", hsMessageBoxNormal );
}
return EXCEPTION_EXECUTE_HANDLER; return EXCEPTION_EXECUTE_HANDLER;
} }
#endif
#include "pfConsoleCore/pfConsoleEngine.h" #include "pfConsoleCore/pfConsoleEngine.h"
PF_CONSOLE_LINK_ALL() PF_CONSOLE_LINK_ALL()

22
Sources/Plasma/Apps/plCrashHandler/CMakeLists.txt

@ -0,0 +1,22 @@
include_directories("../../CoreLib")
include_directories("../../NucleusLib")
include_directories("../../FeatureLib")
set(plCrashHandler_SOURCES
main.cpp
)
add_executable(plCrashHandler ${plCrashHandler_SOURCES})
if(PLASMA_EXTERNAL_RELEASE)
set_target_properties(plClient PROPERTIES OUTPUT_NAME "UruCrashHandler")
endif(PLASMA_EXTERNAL_RELEASE)
target_link_libraries(plCrashHandler CoreLib)
target_link_libraries(plCrashHandler pfCrashHandler)
target_link_libraries(plCrashHandler plFile)
target_link_libraries(plCrashHandler pnProduct)
target_link_libraries(plCrashHandler pnUtils)
# Platform specific libs
if(WIN32)
target_link_libraries(plCrashHandler Dbghelp)
endif(WIN32)

72
Sources/Plasma/Apps/plCrashHandler/main.cpp

@ -0,0 +1,72 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "HeadSpin.h"
#include "pfCrashHandler/plCrashSrv.h"
#include "pnUtils/pnUtils.h"
enum
{
kArgMemFile
};
static const CmdArgDef s_cmdLineArgs[] =
{
{ (kCmdArgRequired | kCmdTypeString), nil, kArgMemFile },
};
int main(int argc, char* argv[])
{
// Parse command line arguments. We MUST have the file argument
CCmdParser cmdParser(s_cmdLineArgs, arrsize(s_cmdLineArgs));
if (!cmdParser.Parse())
{
hsMessageBox("You should never run this manually.", "Error", hsMessageBoxNormal, hsMessageBoxIconExclamation);
return 1;
}
char* file = hsWStringToString(cmdParser.GetString(kArgMemFile));
plCrashSrv srv(file);
delete[] file;
srv.HandleCrash();
return 0;
}

1
Sources/Plasma/FeatureLib/CMakeLists.txt

@ -8,6 +8,7 @@ add_subdirectory(pfCharacter)
add_subdirectory(pfConditional) add_subdirectory(pfConditional)
add_subdirectory(pfConsole) add_subdirectory(pfConsole)
add_subdirectory(pfConsoleCore) add_subdirectory(pfConsoleCore)
add_subdirectory(pfCrashHandler)
add_subdirectory(pfCsrSrv) add_subdirectory(pfCsrSrv)
add_subdirectory(pfGameGUIMgr) add_subdirectory(pfGameGUIMgr)
add_subdirectory(pfGameMgr) add_subdirectory(pfGameMgr)

21
Sources/Plasma/FeatureLib/pfCrashHandler/CMakeLists.txt

@ -0,0 +1,21 @@
include_directories(../../CoreLib)
include_directories(../../NucleusLib)
include_directories(../../PubUtilLib)
set(pfCrashHandler_HEADERS
plCrashCli.h
plCrashBase.h
plCrash_Private.h
plCrashSrv.h
)
set(pfCrashHandler_SOURCES
plCrashCli.cpp
plCrashBase.cpp
plCrashSrv.cpp
)
add_library(pfCrashHandler STATIC ${pfCrashHandler_SOURCES} ${pfCrashHandler_HEADERS})
source_group("Source Files" FILES ${pfCrashHandler_SOURCES})
source_group("Header Files" FILES ${pfCrashHandler_HEADERS})

60
Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.cpp

@ -0,0 +1,60 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "plCrashBase.h"
#include "plCrash_Private.h"
plCrashBase::~plCrashBase()
{
delete fCrashed;
delete fHandled;
}
void plCrashBase::IInit(const char* file)
{
char sema[128];
snprintf(sema, arrsize(sema), "%s-%s", file, CRASH_NOTIFY_SUFFIX);
fCrashed = new hsSemaphore(0, sema);
snprintf(sema, arrsize(sema), "%s-%s", file, CRASH_HANDLE_SUFFIX);
fHandled = new hsSemaphore(0, sema);
}

58
Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.h

@ -0,0 +1,58 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef _pfCrashBase_h_
#define _pfCrashBase_h_
#include "hsThread.h"
class plCrashBase
{
protected:
hsSemaphore* fCrashed;
hsSemaphore* fHandled;
~plCrashBase();
void IInit(const char* file);
};
#endif // _pfCrashBase_h_

138
Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCli.cpp

@ -0,0 +1,138 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "plCrashCli.h"
#include "plCrash_Private.h"
#include "plString.h"
#ifdef HS_BUILD_FOR_WIN32
plCrashCli::plCrashCli()
: fLink(nil), fLinkH(nil)
{
char mapname[128];
char cmdline[128];
snprintf(mapname, arrsize(mapname), "Plasma20CrashHandler-%u", GetCurrentProcessId());
snprintf(cmdline, arrsize(cmdline), "%s %s", CRASH_HANDLER_EXE, mapname);
memset(&fCrashSrv, 0, sizeof(PROCESS_INFORMATION));
// Initialize the semas
IInit(mapname);
// Initialize the shared memory
fLinkH = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(plCrashMemLink), mapname);
hsAssert(fLinkH, "Failed to create plCrashHandler mapping");
if (!fLinkH)
return;
// Map the shared memory
fLink = (plCrashMemLink*)MapViewOfFile(fLinkH, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(plCrashMemLink));
hsAssert(fLink, "Failed to map plCrashLinkedMem");
if (!fLink)
return;
memset(fLink, 0, sizeof(plCrashMemLink));
fLink->fClientProcessID = GetCurrentProcessId();
// Start the plCrashHandler before a crash
STARTUPINFOA info; memset(&info, 0, sizeof(info));
info.cb = sizeof(STARTUPINFOA);
CreateProcessA(
CRASH_HANDLER_EXE, // plCrashHandler.exe
cmdline, // plCrashHandler.exe Plasma20CrashHandler-%u
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW, // Don't create any new windows or consoles
NULL,
NULL, // Use the directory of the current plClient
&info,
&fCrashSrv // Save the CrashSrv handles
);
HANDLE curProc = GetCurrentProcess();
DuplicateHandle(curProc, // Handle to the source process
curProc, // Handle that we want duplicated
fCrashSrv.hProcess, // Handle to target process
&fLink->fClientProcess, // Pointer to Handle to dupliicate to
0, // Ignored
FALSE,
DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS
);
}
plCrashCli::~plCrashCli()
{
fCrashed->Signal(); // forces the CrashSrv to exit, if it's still running
if (fCrashSrv.hProcess)
{
TerminateProcess(fCrashSrv.hProcess, 0);
CloseHandle(fCrashSrv.hProcess);
}
if (fCrashSrv.hThread)
CloseHandle(fCrashSrv.hThread);
if (fLink)
UnmapViewOfFile((LPCVOID)fLink);
if (fLinkH)
CloseHandle(fLinkH);
}
void plCrashCli::ReportCrash(PEXCEPTION_POINTERS e)
{
hsAssert(fLink, "plCrashMemLink is nil");
if (fLink)
{
fLink->fClientThreadID = GetCurrentThreadId();
fLink->fCrashed = true;
fLink->fExceptionPtrs = e;
}
fCrashed->Signal();
}
#else
# error "Implement plCrashCli for this platform"
#endif
void plCrashCli::WaitForHandle()
{
fHandled->Wait();
}

70
Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCli.h

@ -0,0 +1,70 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef _pfCrashCli_h_
#define _pfCrashCli_h_
#include "HeadSpin.h"
#include "plCrashBase.h"
struct plCrashMemLink;
class plCrashCli : public plCrashBase
{
plCrashMemLink* fLink;
#ifdef HS_BUILD_FOR_WIN32
PROCESS_INFORMATION fCrashSrv;
HANDLE fLinkH;
#endif
public:
plCrashCli();
~plCrashCli();
#ifdef HS_BUILD_FOR_WIN32
void ReportCrash(PEXCEPTION_POINTERS);
#endif
void WaitForHandle();
};
#endif // _pfCrashCli_h_

52
Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCommon.h

@ -0,0 +1,52 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef _pnCrashCommon_h_
#define _pnCrashCommon_h_
#include "HeadSpin.h"
struct plCrashLink
{
};
#endif // _pnCrashCommon_h_

117
Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.cpp

@ -0,0 +1,117 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "plCrashSrv.h"
#include "plCrash_Private.h"
#include "plFile/plFileUtils.h"
#include "pnProduct/pnProduct.h"
#ifdef HS_BUILD_FOR_WIN32
#include <DbgHelp.h>
#include <ShlObj.h>
plCrashSrv::plCrashSrv(const char* file)
: fLink(nil), fLinkH(nil)
{
// Init semas
IInit(file);
// Open the linked memory
fLinkH = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, file);
hsAssert(fLinkH, "Failed to open plCrashHandler mapping");
if (!fLinkH)
return;
// Try to map it
fLink = (plCrashMemLink*)MapViewOfFile(fLinkH, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(plCrashMemLink));
hsAssert(fLink, "Failed to map plCrashMemLink");
}
plCrashSrv::~plCrashSrv()
{
if (fLink)
UnmapViewOfFile((LPCVOID)fLink);
if (fLinkH)
CloseHandle(fLinkH);
}
void plCrashSrv::IHandleCrash()
{
// Begin Hackiness
wchar_t dumpPath[1024];
SHGetSpecialFolderPathW(NULL, dumpPath, CSIDL_LOCAL_APPDATA, TRUE);
plFileUtils::ConcatFileName(dumpPath, ProductLongName());
plFileUtils::ConcatFileName(dumpPath, L"Log");
plFileUtils::EnsureFilePathExists(dumpPath);
plFileUtils::ConcatFileName(dumpPath, L"crash.dmp");
HANDLE file = CreateFileW(dumpPath,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
// End Hackiness
MINIDUMP_EXCEPTION_INFORMATION e;
e.ClientPointers = TRUE;
e.ExceptionPointers = fLink->fExceptionPtrs;
e.ThreadId = fLink->fClientThreadID;
MiniDumpWriteDump(fLink->fClientProcess, fLink->fClientProcessID, file, MiniDumpNormal, &e, NULL, NULL);
CloseHandle(file);
}
#else
# error "Implement plCrashSrv for this platform"
#endif
void plCrashSrv::HandleCrash()
{
fCrashed->Wait(); // Wait for a crash
if (!fLink)
FATAL("plCrashMemLink is nil!");
else if (fLink->fCrashed)
IHandleCrash();
fHandled->Signal(); // Tell CrashCli we handled it
}

68
Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.h

@ -0,0 +1,68 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef _pfCrashSrv_h_
#define _pfCrashSrv_h_
#include "HeadSpin.h"
#include "plCrashBase.h"
struct plCrashMemLink;
class plCrashSrv : public plCrashBase
{
plCrashMemLink* fLink;
#ifdef HS_BUILD_FOR_WIN32
HANDLE fLinkH;
#endif
void IHandleCrash();
public:
plCrashSrv(const char* file);
~plCrashSrv();
void HandleCrash();
};
#endif // _pfCrashSrv_h_

70
Sources/Plasma/FeatureLib/pfCrashHandler/plCrash_Private.h

@ -0,0 +1,70 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef _pfCrash_Private_h_
#define _pfCrash_Private_h_
#include "HeadSpin.h"
#define CRASH_NOTIFY_SUFFIX "CrashNotify"
#define CRASH_HANDLE_SUFFIX "CrashHandled"
#ifdef HS_BUILD_FOR_WIN32
# ifdef PLASMA_EXTERNAL_RELEASE
# define CRASH_HANDLER_EXE "UruCrashHandler.exe"
# else
# define CRASH_HANDLER_EXE "plCrashHandler.exe"
# endif // PLASMA_EXTERNAL_RELEASE
#endif // HS_BUILD_FOR_WIN32
struct plCrashMemLink
{
bool fCrashed;
#ifdef HS_BUILD_FOR_WIN32
HANDLE fClientProcess;
uint32_t fClientProcessID;
uint32_t fClientThreadID;
PEXCEPTION_POINTERS fExceptionPtrs;
#endif
};
#endif // _pfCrash_Private_h_
Loading…
Cancel
Save