diff --git a/Sources/Plasma/Apps/CMakeLists.txt b/Sources/Plasma/Apps/CMakeLists.txt index 0140ce05..be2b1d1f 100644 --- a/Sources/Plasma/Apps/CMakeLists.txt +++ b/Sources/Plasma/Apps/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(plClient) add_subdirectory(plClientPatcher) +add_subdirectory(plCrashHandler) add_subdirectory(plPythonPack) add_subdirectory(plUruLauncher) add_subdirectory(plFileSecure) diff --git a/Sources/Plasma/Apps/plClient/CMakeLists.txt b/Sources/Plasma/Apps/plClient/CMakeLists.txt index c38be9da..6f33c40d 100644 --- a/Sources/Plasma/Apps/plClient/CMakeLists.txt +++ b/Sources/Plasma/Apps/plClient/CMakeLists.txt @@ -79,6 +79,7 @@ target_link_libraries(plClient pfCharacter) target_link_libraries(plClient pfConditional) target_link_libraries(plClient pfConsole) target_link_libraries(plClient pfConsoleCore) +target_link_libraries(plClient pfCrashHandler) target_link_libraries(plClient pfCsrSrv) target_link_libraries(plClient pfGameGUIMgr) target_link_libraries(plClient pfGameMgr) diff --git a/Sources/Plasma/Apps/plClient/winmain.cpp b/Sources/Plasma/Apps/plClient/winmain.cpp index b762daf2..e7fb564d 100644 --- a/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/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 "plClientResMgr/plClientResMgr.h" +#include "pfCrashHandler/plCrashCli.h" #include "plNetClient/plNetClientMgr.h" #include "plNetClient/plNetLinkingMgr.h" #include "plInputCore/plInputManager.h" @@ -120,6 +121,10 @@ plClient *gClient; bool gPendingActivate = false; bool gPendingActivateFlag = false; +#ifndef HS_DEBUGGING +static plCrashCli s_crash; +#endif + static bool s_loginDlgRunning = false; static CEvent s_statusEvent(kEventManualReset); static UINT s_WmTaskbarList = RegisterWindowMessage("TaskbarButtonCreated"); @@ -1343,10 +1348,6 @@ BOOL CALLBACK SplashDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l 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 ) { static char *sLastMsg = nil; @@ -1383,63 +1384,21 @@ BOOL CALLBACK ExceptionDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA return 0; } - +#ifndef HS_DEBUGGING LONG WINAPI plCustomUnhandledExceptionFilter( struct _EXCEPTION_POINTERS *ExceptionInfo ) { - const char *type = nil; - switch( ExceptionInfo->ExceptionRecord->ExceptionCode ) - { - 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)); + // Before we do __ANYTHING__, pass the exception to plCrashHandler + s_crash.ReportCrash(ExceptionInfo); - 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 ); - - /// 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 ); - } + // Trickle up the handlers return EXCEPTION_EXECUTE_HANDLER; } +#endif #include "pfConsoleCore/pfConsoleEngine.h" PF_CONSOLE_LINK_ALL() diff --git a/Sources/Plasma/Apps/plCrashHandler/CMakeLists.txt b/Sources/Plasma/Apps/plCrashHandler/CMakeLists.txt new file mode 100644 index 00000000..db372c4b --- /dev/null +++ b/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) diff --git a/Sources/Plasma/Apps/plCrashHandler/main.cpp b/Sources/Plasma/Apps/plCrashHandler/main.cpp new file mode 100644 index 00000000..235564b2 --- /dev/null +++ b/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 . + +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; +} diff --git a/Sources/Plasma/FeatureLib/CMakeLists.txt b/Sources/Plasma/FeatureLib/CMakeLists.txt index 37f4763e..14797148 100644 --- a/Sources/Plasma/FeatureLib/CMakeLists.txt +++ b/Sources/Plasma/FeatureLib/CMakeLists.txt @@ -8,6 +8,7 @@ add_subdirectory(pfCharacter) add_subdirectory(pfConditional) add_subdirectory(pfConsole) add_subdirectory(pfConsoleCore) +add_subdirectory(pfCrashHandler) add_subdirectory(pfCsrSrv) add_subdirectory(pfGameGUIMgr) add_subdirectory(pfGameMgr) diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/CMakeLists.txt b/Sources/Plasma/FeatureLib/pfCrashHandler/CMakeLists.txt new file mode 100644 index 00000000..9915a600 --- /dev/null +++ b/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}) diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.cpp b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.cpp new file mode 100644 index 00000000..36444b50 --- /dev/null +++ b/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 . + +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); +} diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.h b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.h new file mode 100644 index 00000000..3dbc13d3 --- /dev/null +++ b/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 . + +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_ diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCli.cpp b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCli.cpp new file mode 100644 index 00000000..d5412d3b --- /dev/null +++ b/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 . + +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(); +} diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCli.h b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCli.h new file mode 100644 index 00000000..0308a586 --- /dev/null +++ b/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 . + +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_ diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCommon.h b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashCommon.h new file mode 100644 index 00000000..312cde03 --- /dev/null +++ b/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 . + +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_ diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.cpp b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.cpp new file mode 100644 index 00000000..0efae16b --- /dev/null +++ b/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 . + +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 +#include + +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 +} diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.h b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.h new file mode 100644 index 00000000..b8c5f8b4 --- /dev/null +++ b/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 . + +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_ diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrash_Private.h b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrash_Private.h new file mode 100644 index 00000000..e96f8dc9 --- /dev/null +++ b/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 . + +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_