mirror of
https://github.com/rehlds/rehlds.git
synced 2025-05-04 10:49:39 +03:00
Catch crashes and write minidumps on windows (#703)
* Catch crashes and write minidumps on windows * Allow to enable/disable writing mini dumps as in other Source games * Fix gradle build - write minidumps * Appends application version to mini dump name Makes easier to reproduce issues via mini dumps. New mini dump file name format: <exe name>_<app version>_crash_<date YYYYMMDD>_<time HHMMSS>_<unique counter>.mdmp Example: hlds_3.6.0.675-dev+m_crash_20190702_005019_1.mdmp
This commit is contained in:
parent
f01bfdcdcb
commit
0232d99726
@ -116,6 +116,7 @@ model {
|
|||||||
include "ObjectList.cpp"
|
include "ObjectList.cpp"
|
||||||
include "TokenLine.cpp"
|
include "TokenLine.cpp"
|
||||||
include "textconsole.cpp"
|
include "textconsole.cpp"
|
||||||
|
include "minidump.cpp"
|
||||||
if (GradleCppUtils.windows) {
|
if (GradleCppUtils.windows) {
|
||||||
include "TextConsoleWin32.cpp"
|
include "TextConsoleWin32.cpp"
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
<ClInclude Include="..\..\..\common\ObjectList.h" />
|
<ClInclude Include="..\..\..\common\ObjectList.h" />
|
||||||
<ClInclude Include="..\..\..\common\textconsole.h" />
|
<ClInclude Include="..\..\..\common\textconsole.h" />
|
||||||
<ClInclude Include="..\..\..\common\TokenLine.h" />
|
<ClInclude Include="..\..\..\common\TokenLine.h" />
|
||||||
|
<ClInclude Include="..\..\..\common\minidump.h" />
|
||||||
<ClInclude Include="..\..\..\engine\mem.h" />
|
<ClInclude Include="..\..\..\engine\mem.h" />
|
||||||
<ClInclude Include="..\..\..\game_shared\bitvec.h" />
|
<ClInclude Include="..\..\..\game_shared\bitvec.h" />
|
||||||
<ClInclude Include="..\..\..\game_shared\perf_counter.h" />
|
<ClInclude Include="..\..\..\game_shared\perf_counter.h" />
|
||||||
@ -60,6 +61,11 @@
|
|||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Swds|Win32'">Use</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Swds|Win32'">Use</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\common\minidump.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Swds|Win32'">Use</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\engine\mem.cpp" />
|
<ClCompile Include="..\..\..\engine\mem.cpp" />
|
||||||
<ClCompile Include="..\..\common\common.cpp">
|
<ClCompile Include="..\..\common\common.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||||
|
@ -58,6 +58,9 @@
|
|||||||
<ClInclude Include="..\..\..\engine\mem.h">
|
<ClInclude Include="..\..\..\engine\mem.h">
|
||||||
<Filter>engine</Filter>
|
<Filter>engine</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\common\minidump.h">
|
||||||
|
<Filter>common</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\src\precompiled.cpp">
|
<ClCompile Include="..\src\precompiled.cpp">
|
||||||
@ -96,6 +99,9 @@
|
|||||||
<ClCompile Include="..\..\..\engine\mem.cpp">
|
<ClCompile Include="..\..\..\engine\mem.cpp">
|
||||||
<Filter>engine</Filter>
|
<Filter>engine</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\common\minidump.cpp">
|
||||||
|
<Filter>common</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="icon.ico" />
|
<Image Include="icon.ico" />
|
||||||
|
@ -1092,8 +1092,15 @@ unsigned char *System::LoadFile(const char *name, int *length)
|
|||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
||||||
{
|
{
|
||||||
gSystem.BuildCommandLine(lpCmdLine);
|
#ifdef HLTV_FIXES
|
||||||
return gSystem.Run();
|
return CatchAndWriteMiniDump([=]()
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
gSystem.BuildCommandLine(lpCmdLine);
|
||||||
|
return gSystem.Run();
|
||||||
|
#ifdef HLTV_FIXES
|
||||||
|
}, lpCmdLine);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::BuildCommandLine(char *argv)
|
void System::BuildCommandLine(char *argv)
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "version/appversion.h"
|
||||||
|
|
||||||
#include "basetypes.h"
|
#include "basetypes.h"
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "strtools.h"
|
#include "strtools.h"
|
||||||
@ -16,3 +18,7 @@
|
|||||||
// Console stuff
|
// Console stuff
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
#include "common/random.h"
|
#include "common/random.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "minidump.h"
|
||||||
|
#endif
|
||||||
|
203
rehlds/common/minidump.cpp
Normal file
203
rehlds/common/minidump.cpp
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#if defined(HLTV_FIXES) || defined(LAUNCHER_FIXES)
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && !defined(_IMAGEHLP_)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4091) // A microsoft header has warnings. Very nice.
|
||||||
|
#include <DbgHelp.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Gets last error.
|
||||||
|
static inline HRESULT GetLastHresult()
|
||||||
|
{
|
||||||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WIDE_TEXT_HELPER_(quote) L##quote
|
||||||
|
#define WIDE_TEXT(quote) WIDE_TEXT_HELPER_(quote)
|
||||||
|
|
||||||
|
// Gets application version which is safe for use in minidump file name. Can be entirely constexpr with C++17 and std::array.
|
||||||
|
template<size_t appVersionSize>
|
||||||
|
static wchar_t* GetAppVersionForMiniDumpName(wchar_t (&appVersion)[appVersionSize]) {
|
||||||
|
constexpr wchar_t rawAppVersion[]{WIDE_TEXT(APP_VERSION "-" APP_COMMIT_SHA)};
|
||||||
|
|
||||||
|
static_assert(appVersionSize >= ARRAYSIZE(rawAppVersion), "App version buffer size should be enough to store app version.");
|
||||||
|
|
||||||
|
// See https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-pathcleanupspec#remarks for details.
|
||||||
|
constexpr wchar_t invalidPathChars[]{L'\\', L'/', L':', L'*', L'?', L'"', L'<', L'>', L'|', L';', L','};
|
||||||
|
|
||||||
|
size_t outIt{0};
|
||||||
|
for (size_t rawIt{0}; rawIt < ARRAYSIZE(rawAppVersion); ++rawIt)
|
||||||
|
{
|
||||||
|
const wchar_t currentRawIt{rawAppVersion[rawIt]};
|
||||||
|
bool isValidRaw{true};
|
||||||
|
|
||||||
|
for (size_t invalidIt{0}; invalidIt < ARRAYSIZE(invalidPathChars); ++invalidIt)
|
||||||
|
{
|
||||||
|
isValidRaw = invalidPathChars[invalidIt] != currentRawIt;
|
||||||
|
|
||||||
|
if (!isValidRaw)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValidRaw) {
|
||||||
|
appVersion[outIt++] = currentRawIt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return appVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a new minidump file and dumps the exception info into it.
|
||||||
|
static HRESULT WriteMiniDumpUsingExceptionInfo(unsigned int exceptionCode,
|
||||||
|
struct _EXCEPTION_POINTERS *exceptionInfo, MINIDUMP_TYPE minidumpType)
|
||||||
|
{
|
||||||
|
// Counter used to make sure minidump names are unique.
|
||||||
|
static int minidumpsWrittenCount{0};
|
||||||
|
|
||||||
|
HMODULE dbghelpModule{LoadLibraryW(L"DbgHelp.dll")};
|
||||||
|
HRESULT errorCode{dbghelpModule ? S_OK : GetLastHresult()};
|
||||||
|
|
||||||
|
using MiniDumpWriteDumpFn = decltype(&MiniDumpWriteDump);
|
||||||
|
MiniDumpWriteDumpFn miniDumpWriteDump{nullptr};
|
||||||
|
if (SUCCEEDED(errorCode))
|
||||||
|
{
|
||||||
|
miniDumpWriteDump = reinterpret_cast<MiniDumpWriteDumpFn>(GetProcAddress(
|
||||||
|
dbghelpModule, "MiniDumpWriteDump"));
|
||||||
|
errorCode = miniDumpWriteDump ? S_OK : GetLastHresult();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a unique filename for the minidump based on the current time and
|
||||||
|
// module name.
|
||||||
|
const time_t timeNow{time(nullptr)};
|
||||||
|
tm *localTimeNow{localtime(&timeNow)};
|
||||||
|
if (localTimeNow == nullptr)
|
||||||
|
{
|
||||||
|
errorCode = E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip off the rest of the path from the .exe name.
|
||||||
|
wchar_t moduleName[MAX_PATH];
|
||||||
|
if (SUCCEEDED(errorCode))
|
||||||
|
{
|
||||||
|
::SetLastError(NOERROR);
|
||||||
|
::GetModuleFileNameW(nullptr, moduleName, static_cast<DWORD>(ARRAYSIZE(moduleName)));
|
||||||
|
|
||||||
|
errorCode = GetLastHresult();
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t fileName[MAX_PATH];
|
||||||
|
HANDLE minidumpFile{nullptr};
|
||||||
|
|
||||||
|
if (SUCCEEDED(errorCode))
|
||||||
|
{
|
||||||
|
wchar_t *strippedModuleName{wcsrchr(moduleName, L'.')};
|
||||||
|
if (strippedModuleName) *strippedModuleName = L'\0';
|
||||||
|
|
||||||
|
strippedModuleName = wcsrchr(moduleName, L'\\');
|
||||||
|
// Move past the last slash.
|
||||||
|
if (strippedModuleName) ++strippedModuleName;
|
||||||
|
|
||||||
|
wchar_t appVersion[ARRAYSIZE(APP_VERSION) + ARRAYSIZE(APP_COMMIT_SHA) + 2];
|
||||||
|
// <exe name>_<app version-app hash build>_crash_<date YYYYMMDD>_<time HHMMSS>_<unique counter>.mdmp
|
||||||
|
swprintf(fileName, ARRAYSIZE(fileName), L"%s_%s_crash_%d%.2d%.2d_%.2d%.2d%.2d_%d.mdmp",
|
||||||
|
strippedModuleName ? strippedModuleName : L"unknown",
|
||||||
|
GetAppVersionForMiniDumpName(appVersion),
|
||||||
|
localTimeNow->tm_year + 1900, /* Year less 2000 */
|
||||||
|
localTimeNow->tm_mon + 1, /* month (0 - 11 : 0 = January) */
|
||||||
|
localTimeNow->tm_mday, /* day of month (1 - 31) */
|
||||||
|
localTimeNow->tm_hour, /* hour (0 - 23) */
|
||||||
|
localTimeNow->tm_min, /* minutes (0 - 59) */
|
||||||
|
localTimeNow->tm_sec, /* seconds (0 - 59) */
|
||||||
|
++minidumpsWrittenCount); // ensures the filename is unique
|
||||||
|
|
||||||
|
minidumpFile = CreateFileW(fileName, GENERIC_WRITE, FILE_SHARE_WRITE,
|
||||||
|
nullptr, CREATE_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
errorCode = minidumpFile != INVALID_HANDLE_VALUE ? S_OK : GetLastHresult();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(errorCode) && miniDumpWriteDump)
|
||||||
|
{
|
||||||
|
// Dump the exception information into the file.
|
||||||
|
MINIDUMP_EXCEPTION_INFORMATION exInfo;
|
||||||
|
exInfo.ThreadId = GetCurrentThreadId();
|
||||||
|
exInfo.ExceptionPointers = exceptionInfo;
|
||||||
|
exInfo.ClientPointers = FALSE;
|
||||||
|
|
||||||
|
const BOOL wasWrittenMinidump{miniDumpWriteDump(
|
||||||
|
GetCurrentProcess(), GetCurrentProcessId(), minidumpFile,
|
||||||
|
minidumpType, &exInfo, nullptr, nullptr)};
|
||||||
|
|
||||||
|
// If the function succeeds, the return value is TRUE; otherwise, the
|
||||||
|
// return value is FALSE. To retrieve extended error information, call
|
||||||
|
// GetLastError. Note that the last error will be an HRESULT value. If
|
||||||
|
// the operation is canceled, the last error code is HRESULT_FROM_WIN32(ERROR_CANCELLED).
|
||||||
|
// See
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/minidumpapiset/nf-minidumpapiset-minidumpwritedump
|
||||||
|
errorCode = wasWrittenMinidump ? S_OK : static_cast<HRESULT>(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minidumpFile && minidumpFile != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
CloseHandle(minidumpFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dbghelpModule)
|
||||||
|
{
|
||||||
|
FreeLibrary(dbghelpModule);
|
||||||
|
}
|
||||||
|
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writes process mini dump by exception code and info.
|
||||||
|
void WriteMiniDump(unsigned int exceptionCode,
|
||||||
|
struct _EXCEPTION_POINTERS *exceptionInfo)
|
||||||
|
{
|
||||||
|
// First try to write it with all the indirectly referenced memory (ie: a
|
||||||
|
// large file). If that doesn't work, then write a smaller one.
|
||||||
|
auto minidumpType = static_cast<MINIDUMP_TYPE>(
|
||||||
|
MiniDumpWithDataSegs | MiniDumpWithHandleData | MiniDumpWithThreadInfo |
|
||||||
|
MiniDumpWithIndirectlyReferencedMemory);
|
||||||
|
|
||||||
|
if (FAILED(WriteMiniDumpUsingExceptionInfo(exceptionCode, exceptionInfo, minidumpType)))
|
||||||
|
{
|
||||||
|
minidumpType = MiniDumpWithDataSegs;
|
||||||
|
|
||||||
|
WriteMiniDumpUsingExceptionInfo(exceptionCode, exceptionInfo, minidumpType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determines either debugger attached to a process or not.
|
||||||
|
bool HasDebuggerPresent()
|
||||||
|
{
|
||||||
|
return ::IsDebuggerPresent() != FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determines either writing mini dumps is enabled or not (-nominidumps). Same as in Source games.
|
||||||
|
bool IsWriteMiniDumpsEnabled(const char *commandLine)
|
||||||
|
{
|
||||||
|
if (!commandLine)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *noMiniDumps{strstr(commandLine, "-nominidumps")};
|
||||||
|
if (!noMiniDumps)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *nextCharAfterNoMiniDumps{noMiniDumps + ARRAYSIZE("-nominidumps") - 1};
|
||||||
|
// Command line ends with -nominidumps or has space after -nominidumps -> not mini dump.
|
||||||
|
return !(nextCharAfterNoMiniDumps[0] == '\0' || isspace(nextCharAfterNoMiniDumps[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _WIN32
|
||||||
|
#endif // HLTV_FIXES || LAUNCHER_FIXES
|
66
rehlds/common/minidump.h
Normal file
66
rehlds/common/minidump.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(HLTV_FIXES) || defined(LAUNCHER_FIXES)
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
// Writes process mini dump by exception code and info.
|
||||||
|
void WriteMiniDump(unsigned int exceptionCode,
|
||||||
|
struct _EXCEPTION_POINTERS *exceptionInfo);
|
||||||
|
|
||||||
|
// Determines either debugger attached to a process or not.
|
||||||
|
bool HasDebuggerPresent();
|
||||||
|
|
||||||
|
// Determines either writing mini dumps is enabled or not. Same as in Source games.
|
||||||
|
bool IsWriteMiniDumpsEnabled(const char *commandLine);
|
||||||
|
|
||||||
|
// Catches and writes out any exception thrown by the specified function.
|
||||||
|
template <typename F>
|
||||||
|
int CatchAndWriteMiniDump(F function, const char *commandLine)
|
||||||
|
{
|
||||||
|
// Don't mask exceptions when mini dumps disabled (-nominidumps) or running in the debugger.
|
||||||
|
if (!IsWriteMiniDumpsEnabled(commandLine) || HasDebuggerPresent())
|
||||||
|
{
|
||||||
|
return function();
|
||||||
|
}
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
return function();
|
||||||
|
} __except (WriteMiniDump(GetExceptionCode(), GetExceptionInformation()),
|
||||||
|
EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
// Write the minidump from inside the filter.
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _WIN32
|
||||||
|
#endif // HLTV_FIXES || LAUNCHER_FIXES
|
@ -24,7 +24,7 @@ void setupToolchain(NativeBinarySpec b) {
|
|||||||
boolean useGcc = project.hasProperty("useGcc")
|
boolean useGcc = project.hasProperty("useGcc")
|
||||||
|
|
||||||
def cfg = rootProject.createToolchainConfig(b);
|
def cfg = rootProject.createToolchainConfig(b);
|
||||||
cfg.projectInclude(project, '/src', '/../engine', '/../common', '/../public', '/../public/rehlds');
|
cfg.projectInclude(project, '/src', '/../engine', '/../common', '/../public', '/../public/rehlds', '/../');
|
||||||
|
|
||||||
cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'DEDICATED', 'LAUNCHER_FIXES', '_CONSOLE'
|
cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'DEDICATED', 'LAUNCHER_FIXES', '_CONSOLE'
|
||||||
|
|
||||||
@ -121,6 +121,7 @@ model {
|
|||||||
include "SteamAppStartUp.cpp"
|
include "SteamAppStartUp.cpp"
|
||||||
include "textconsole.cpp"
|
include "textconsole.cpp"
|
||||||
include "commandline.cpp"
|
include "commandline.cpp"
|
||||||
|
include "minidump.cpp"
|
||||||
if (GradleCppUtils.windows) {
|
if (GradleCppUtils.windows) {
|
||||||
include "TextConsoleWin32.cpp"
|
include "TextConsoleWin32.cpp"
|
||||||
}
|
}
|
||||||
|
@ -201,6 +201,7 @@
|
|||||||
</CustomBuildStep>
|
</CustomBuildStep>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\common\minidump.h" />
|
||||||
<ClInclude Include="..\..\common\ObjectList.h" />
|
<ClInclude Include="..\..\common\ObjectList.h" />
|
||||||
<ClInclude Include="..\..\common\SteamAppStartUp.h" />
|
<ClInclude Include="..\..\common\SteamAppStartUp.h" />
|
||||||
<ClInclude Include="..\..\common\textconsole.h" />
|
<ClInclude Include="..\..\common\textconsole.h" />
|
||||||
@ -222,6 +223,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\common\commandline.cpp" />
|
<ClCompile Include="..\..\common\commandline.cpp" />
|
||||||
|
<ClCompile Include="..\..\common\minidump.cpp" />
|
||||||
<ClCompile Include="..\..\common\ObjectList.cpp" />
|
<ClCompile Include="..\..\common\ObjectList.cpp" />
|
||||||
<ClCompile Include="..\..\common\SteamAppStartUp.cpp" />
|
<ClCompile Include="..\..\common\SteamAppStartUp.cpp" />
|
||||||
<ClCompile Include="..\..\common\textconsole.cpp" />
|
<ClCompile Include="..\..\common\textconsole.cpp" />
|
||||||
|
@ -47,6 +47,9 @@
|
|||||||
<ClInclude Include="..\..\common\SteamAppStartUp.h">
|
<ClInclude Include="..\..\common\SteamAppStartUp.h">
|
||||||
<Filter>common</Filter>
|
<Filter>common</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\common\minidump.h">
|
||||||
|
<Filter>common</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\src\sys_ded.cpp">
|
<ClCompile Include="..\src\sys_ded.cpp">
|
||||||
@ -94,6 +97,9 @@
|
|||||||
<ClCompile Include="..\..\common\commandline.cpp">
|
<ClCompile Include="..\..\common\commandline.cpp">
|
||||||
<Filter>src</Filter>
|
<Filter>src</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\common\minidump.cpp">
|
||||||
|
<Filter>common</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="icon.ico" />
|
<Image Include="icon.ico" />
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "version/appversion.h"
|
||||||
|
|
||||||
#include "basetypes.h"
|
#include "basetypes.h"
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "strtools.h"
|
#include "strtools.h"
|
||||||
@ -23,6 +25,7 @@
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "conproc.h"
|
#include "conproc.h"
|
||||||
|
#include "minidump.h"
|
||||||
#include <mmsystem.h> // timeGetTime
|
#include <mmsystem.h> // timeGetTime
|
||||||
#else
|
#else
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -239,11 +239,18 @@ void Sys_WriteProcessIdFile()
|
|||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
||||||
{
|
{
|
||||||
if (ShouldLaunchAppViaSteam(lpCmdLine, STDIO_FILESYSTEM_LIB, STDIO_FILESYSTEM_LIB))
|
#ifdef LAUNCHER_FIXES
|
||||||
return 0;
|
return CatchAndWriteMiniDump([=]()
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
if (ShouldLaunchAppViaSteam(lpCmdLine, STDIO_FILESYSTEM_LIB, STDIO_FILESYSTEM_LIB))
|
||||||
|
return 0;
|
||||||
|
|
||||||
//auto command = CommandLineToArgvW(GetCommandLineW(), (int *)&lpCmdLine);
|
//auto command = CommandLineToArgvW(GetCommandLineW(), (int *)&lpCmdLine);
|
||||||
auto ret = StartServer(lpCmdLine);
|
auto ret = StartServer(lpCmdLine);
|
||||||
//LocalFree(command);
|
//LocalFree(command);
|
||||||
return ret;
|
return ret;
|
||||||
|
#ifdef LAUNCHER_FIXES
|
||||||
|
}, lpCmdLine);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user