mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-06 06:32:56 +01:00
Merge pull request #3236 from janisozaur/breakpad
Implement crash / exception handling using Google Breakpad. This also includes updating the AppVeyor script to upload symbols.
This commit is contained in:
3
.github/ISSUE_TEMPLATE.md
vendored
3
.github/ISSUE_TEMPLATE.md
vendored
@@ -11,6 +11,9 @@ Explanation of the issue...
|
||||
1.
|
||||
2.
|
||||
|
||||
**Dump file**
|
||||
If you have a dump file, zip it and drag&drop it here.
|
||||
|
||||
**Screenshots / Video:**
|
||||
Drag / drop screenshots here. Use https://vid.me to upload video.
|
||||
|
||||
|
||||
@@ -143,6 +143,16 @@ if (STATIC)
|
||||
endif (WIN32)
|
||||
endif ()
|
||||
|
||||
option(WITH_BREAKPAD "Enable breakpad")
|
||||
if (WITH_BREAKPAD)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_BREAKPAD")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_BREAKPAD")
|
||||
set(BREAKPAD_DIR "/home/janisozaur/workspace/breakpad/src")
|
||||
set(BREAKPAD_INCLUDE_DIR "${BREAKPAD_DIR}/src")
|
||||
set(BREAKPAD_LIBRARY_DIR "${BREAKPAD_DIR}/src/client/linux")
|
||||
set(BREAKPAD_LIBS breakpad_client pthread)
|
||||
endif (WITH_BREAKPAD)
|
||||
|
||||
# find and include SDL2
|
||||
PKG_CHECK_MODULES(SDL2 REQUIRED sdl2 SDL2_ttf)
|
||||
if (STATIC)
|
||||
@@ -180,9 +190,9 @@ if (UNIX)
|
||||
set(DLLIB dl)
|
||||
endif (UNIX)
|
||||
|
||||
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${LIBCURL_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS} ${SPEEX_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS})
|
||||
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${LIBCURL_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS} ${SPEEX_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} ${BREAKPAD_INCLUDE_DIR})
|
||||
|
||||
LINK_DIRECTORIES(${SDL2_LIBRARY_DIRS} ${JANSSON_LIBRARY_DIRS} ${LIBCURL_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS} ${ZLIB_LIBRARY_DIRS})
|
||||
LINK_DIRECTORIES(${SDL2_LIBRARY_DIRS} ${JANSSON_LIBRARY_DIRS} ${LIBCURL_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS} ${ZLIB_LIBRARY_DIRS} ${BREAKPAD_LIBRARY_DIR})
|
||||
|
||||
if (WIN32)
|
||||
# build as library for now, replace with add_executable
|
||||
@@ -215,7 +225,7 @@ endif (UNIX AND NOT APPLE)
|
||||
# libopenrct2.dll -> openrct2.dll
|
||||
set_target_properties(${PROJECT} PROPERTIES PREFIX "")
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2LIBS} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB} ${REQUIREDLIBS})
|
||||
TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2LIBS} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB} ${REQUIREDLIBS} ${BREAKPAD_LIBS})
|
||||
|
||||
if (APPLE OR STATIC)
|
||||
FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
426da7e58564472ba1b7991f /* crash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = a9793fe06a4244938f5d4b61 /* crash.cpp */; };
|
||||
001085F01C90FD030075A2AD /* textinputbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 001085EE1C90FD030075A2AD /* textinputbuffer.c */; };
|
||||
C62A08D51C787C2A00F3AA76 /* drawing_fast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C62A08D41C787C2A00F3AA76 /* drawing_fast.cpp */; };
|
||||
D41B73EF1C2101890080A7B9 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D41B73EE1C2101890080A7B9 /* libcurl.tbd */; };
|
||||
@@ -222,6 +223,7 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
a9793fe06a4244938f5d4b61 /* crash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crash.cpp; path = src/platform/crash.cpp; sourceTree = "<group>"; };
|
||||
001085EE1C90FD030075A2AD /* textinputbuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = textinputbuffer.c; sourceTree = "<group>"; };
|
||||
001085EF1C90FD030075A2AD /* textinputbuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textinputbuffer.h; sourceTree = "<group>"; };
|
||||
C62A08D41C787C2A00F3AA76 /* drawing_fast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = drawing_fast.cpp; sourceTree = "<group>"; };
|
||||
@@ -655,7 +657,8 @@
|
||||
D4EC47711C26342F0024B507 /* title.c */,
|
||||
D4EC47721C26342F0024B507 /* title.h */,
|
||||
D4163F671C2A044D00B83136 /* version.h */,
|
||||
);
|
||||
a9793fe06a4244938f5d4b61 /* crash.cpp */,
|
||||
);
|
||||
name = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -1505,7 +1508,8 @@
|
||||
D4EC48721C26342F0024B507 /* balloon.c in Sources */,
|
||||
D4EC48571C26342F0024B507 /* save_prompt.c in Sources */,
|
||||
D4EC48701C26342F0024B507 /* viewport.c in Sources */,
|
||||
);
|
||||
426da7e58564472ba1b7991f /* crash.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
@@ -28,3 +28,5 @@ artifacts:
|
||||
name: OpenRCT2-portable
|
||||
- path: .\artifacts\*.exe
|
||||
name: OpenRCT2-installer
|
||||
- path: .\artifacts\openrct2-symbols.zip
|
||||
name: OpenRCT2 debug symbols
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
- Technical: lodepng dropped in return for libpng.
|
||||
- Technical: SDL2 upgraded from 2.0.3 to 2.0.4.
|
||||
- Technical: argparse dropped in return for bespoke command line parsing implementation.
|
||||
- Technical: Integrated breakpad for (manual) crash reporting
|
||||
- Improve: performance of rendering, particularly for highly populated parks.
|
||||
- Improve: performance of loading parks.
|
||||
- Improve: support for hacked parks.
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
<ClCompile Include="src\openrct2.c" />
|
||||
<ClCompile Include="src\peep\peep.c" />
|
||||
<ClCompile Include="src\peep\staff.c" />
|
||||
<ClCompile Include="src\platform\crash.cpp" />
|
||||
<ClCompile Include="src\platform\linux.c" />
|
||||
<ClCompile Include="src\platform\posix.c" />
|
||||
<ClCompile Include="src\platform\shared.c" />
|
||||
@@ -261,6 +262,7 @@
|
||||
<ClInclude Include="src\openrct2.h" />
|
||||
<ClInclude Include="src\peep\peep.h" />
|
||||
<ClInclude Include="src\peep\staff.h" />
|
||||
<ClInclude Include="src\platform\crash.h" />
|
||||
<ClInclude Include="src\platform\platform.h" />
|
||||
<ClInclude Include="src\rct1.h" />
|
||||
<ClInclude Include="src\rct2.h" />
|
||||
@@ -329,20 +331,26 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>$(SolutionDir)lib\include;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(SolutionDir)lib\include;$(SolutionDir)lib\include\breakpad;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)lib;$(LibraryPath)</LibraryPath>
|
||||
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IncludePath>$(SolutionDir)lib\include;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(SolutionDir)lib\include;$(SolutionDir)lib\include\breakpad;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)lib;$(LibraryPath)</LibraryPath>
|
||||
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Breakpad)'=='true'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>USE_BREAKPAD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<DisableSpecificWarnings>4091;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
@@ -363,6 +371,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<DisableSpecificWarnings>4091;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
@@ -388,4 +397,4 @@
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -587,6 +587,7 @@
|
||||
<ClCompile Include="src\core\textinputbuffer.c">
|
||||
<Filter>Source\Core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\platform\crash.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\management\award.h">
|
||||
@@ -896,5 +897,6 @@
|
||||
<ClInclude Include="src\core\textinputbuffer.h">
|
||||
<Filter>Source\Core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\platform\crash.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -40,10 +40,12 @@ if (${env:CODE-SIGN-KEY-OPENRCT2.ORG.PFX.PASSWORD} -ne $null)
|
||||
# Enable pushing builds to OpenRCT2.org if token environment variable is set
|
||||
$pushBuilds = $false
|
||||
$installer = $false
|
||||
$symbols = $false
|
||||
if (${env:OPENRCT2.ORG_TOKEN} -ne $null)
|
||||
{
|
||||
$pushBuilds = $true
|
||||
$installer = $true
|
||||
$symbols = $true
|
||||
}
|
||||
|
||||
# Write out summary of the build
|
||||
@@ -98,6 +100,18 @@ if ($installer)
|
||||
-CodeSign $codeSign
|
||||
}
|
||||
|
||||
if ($symbols)
|
||||
{
|
||||
publish package `
|
||||
-Symbols `
|
||||
-Server $server `
|
||||
-GitTag $tag `
|
||||
-GitBranch $env:APPVEYOR_REPO_BRANCH `
|
||||
-GitSha1 $env:APPVEYOR_REPO_COMMIT `
|
||||
-GitSha1Short $env:APPVEYOR_REPO_COMMIT_SHORT `
|
||||
-CodeSign $codeSign
|
||||
}
|
||||
|
||||
if ($pushBuilds)
|
||||
{
|
||||
$versionExtension = ""
|
||||
@@ -127,4 +141,14 @@ if ($pushBuilds)
|
||||
-version $version `
|
||||
-flavourId 2
|
||||
}
|
||||
|
||||
# Push symbols
|
||||
if ($symbols)
|
||||
{
|
||||
Write-Host "Sending symbols to OpenRCT2.org" -ForegroundColor Cyan
|
||||
Push-Build -file ".\artifacts\openrct2-symbols.zip" `
|
||||
-name "$pushFileName-symbols.zip" `
|
||||
-version $version `
|
||||
-flavourId 5
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,10 @@ param (
|
||||
[string]$Configuration = "Release",
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$Rebuild = $false
|
||||
[switch]$Rebuild = $false,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$Breakpad = $false
|
||||
)
|
||||
|
||||
# Setup
|
||||
@@ -40,7 +43,7 @@ function Build-OpenRCT2()
|
||||
{
|
||||
$target = "/t:rebuild"
|
||||
}
|
||||
msbuild $rootPath\openrct2.sln /p:Configuration=$Configuration /p:Platform=Win32 $target /v:minimal | Write-Host
|
||||
msbuild $rootPath\openrct2.sln /p:Breakpad=$Breakpad /p:Configuration=$Configuration /p:Platform=Win32 $target /v:minimal | Write-Host
|
||||
return $LASTEXITCODE
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Import-Module "$scriptsPath\common.psm1" -DisableNameChecking
|
||||
|
||||
# Constants
|
||||
$libsUrl = "https://openrct2.website/files/openrct2-libs-vs2015.zip"
|
||||
$libsVersion = 6
|
||||
$libsVersion = 7
|
||||
|
||||
# Get paths
|
||||
$rootPath = Get-RootPath
|
||||
|
||||
@@ -14,7 +14,8 @@ param (
|
||||
[string]$GitSha1 = "",
|
||||
[string]$GitSha1Short = "",
|
||||
[bool] $CodeSign = $false,
|
||||
[switch]$Installer = $false
|
||||
[switch]$Installer = $false,
|
||||
[switch]$Symbols = $false
|
||||
)
|
||||
|
||||
if ($GitTag -eq "")
|
||||
@@ -77,7 +78,7 @@ function Do-PrepareSource()
|
||||
function Do-Build()
|
||||
{
|
||||
Write-Host "Building OpenRCT2..." -ForegroundColor Cyan
|
||||
& "$scriptsPath\build.ps1" all -Rebuild
|
||||
& "$scriptsPath\build.ps1" all -Rebuild -Breakpad
|
||||
if ($LASTEXITCODE -ne 0)
|
||||
{
|
||||
Write-Host "Failed to build OpenRCT2" -ForegroundColor Red
|
||||
@@ -97,6 +98,38 @@ function Do-Build()
|
||||
return 0
|
||||
}
|
||||
|
||||
# Symbols
|
||||
function Do-Symbols()
|
||||
{
|
||||
Write-Host "Publishing OpenRCT2 debug symbols as zip..." -ForegroundColor Cyan
|
||||
$artifactsDir = "$rootPath\artifacts"
|
||||
$releaseDir = "$rootPath\bin"
|
||||
$outZip = "$rootPath\artifacts\openrct2-symbols.zip"
|
||||
|
||||
Copy-Item -Force "$releaseDir\openrct2.pdb" $artifactsDir -ErrorAction Stop
|
||||
|
||||
# Create archive using 7z (renowned for speed and compression)
|
||||
$7zcmd = "7za"
|
||||
if (-not (AppExists($7zcmd)))
|
||||
{
|
||||
# AppVeyor in particular uses '7z' instead
|
||||
$7zcmd = "7z"
|
||||
if (-not (AppExists($7zcmd)))
|
||||
{
|
||||
Write-Host "Publish script requires 7z to be in PATH" -ForegroundColor Red
|
||||
return 1
|
||||
}
|
||||
}
|
||||
& $7zcmd a -tzip -mx9 $outZip "$artifactsDir\openrct2.pdb" > $null
|
||||
if ($LASTEXITCODE -ne 0)
|
||||
{
|
||||
Write-Host "Failed to create zip." -ForegroundColor Red
|
||||
return 1
|
||||
}
|
||||
Remove-Item -Force -Recurse "$artifactsDir\openrct2.pdb" -ErrorAction SilentlyContinue
|
||||
return 0
|
||||
}
|
||||
|
||||
# Package
|
||||
function Do-Package()
|
||||
{
|
||||
@@ -209,6 +242,10 @@ function Do-Task-Package()
|
||||
{
|
||||
if (($result = (Do-Installer)) -ne 0) { return $result }
|
||||
}
|
||||
elseif ($Symbols)
|
||||
{
|
||||
if (($result = (Do-Symbols)) -ne 0) { return $result }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($result = (Do-Package)) -ne 0) { return $result }
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "network/http.h"
|
||||
#include "network/network.h"
|
||||
#include "openrct2.h"
|
||||
#include "platform/crash.h"
|
||||
#include "platform/platform.h"
|
||||
#include "ride/ride.h"
|
||||
#include "title.h"
|
||||
@@ -184,6 +185,8 @@ bool openrct2_initialise()
|
||||
return false;
|
||||
}
|
||||
|
||||
crash_init();
|
||||
|
||||
if (!openrct2_setup_rct2_segment()) {
|
||||
log_fatal("Unable to load RCT2 data sector");
|
||||
return false;
|
||||
|
||||
135
src/platform/crash.cpp
Normal file
135
src/platform/crash.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include <SDL_platform.h>
|
||||
#include "crash.h"
|
||||
|
||||
#ifdef USE_BREAKPAD
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
#include <breakpad/client/windows/handler/exception_handler.h>
|
||||
#include <string>
|
||||
#include <ShlObj.h>
|
||||
#elif defined(__LINUX__)
|
||||
#include <breakpad/client/linux/handler/exception_handler.h>
|
||||
#define BREAKPAD_PATH "/tmp"
|
||||
#else
|
||||
#error Breakpad support not implemented yet for this platform
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include "../localisation/language.h"
|
||||
#include "../scenario.h"
|
||||
#include "platform.h"
|
||||
}
|
||||
|
||||
#include "../core/Console.hpp"
|
||||
|
||||
#define WSZ(x) L"" x
|
||||
|
||||
static bool OnCrash(const wchar_t * dumpPath,
|
||||
const wchar_t * miniDumpId,
|
||||
void * context,
|
||||
EXCEPTION_POINTERS * exinfo,
|
||||
MDRawAssertionInfo * assertion,
|
||||
bool succeeded)
|
||||
{
|
||||
if (!succeeded)
|
||||
{
|
||||
constexpr char * DumpFailedMessage = "Failed to create the dump. Nothing left to do. Please file an issue with OpenRCT2 on Github and provide latest save.";
|
||||
printf("%s\n", DumpFailedMessage);
|
||||
MessageBoxA(NULL, DumpFailedMessage, OPENRCT2_NAME, MB_OK | MB_ICONERROR);
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
wchar_t dumpFilePath[MAX_PATH];
|
||||
wchar_t saveFilePath[MAX_PATH];
|
||||
wsprintfW(dumpFilePath, L"%s%s.dmp", dumpPath, miniDumpId);
|
||||
wsprintfW(saveFilePath, L"%s%s.sv6", dumpPath, miniDumpId);
|
||||
|
||||
wprintf(L"Dump Path: %s\n", dumpFilePath);
|
||||
wprintf(L"Dump Id: %s\n", miniDumpId);
|
||||
wprintf(L"Version: %s\n", WSZ(OPENRCT2_VERSION));
|
||||
wprintf(L"Commit: %s\n", WSZ(OPENRCT2_COMMIT_SHA1_SHORT));
|
||||
|
||||
utf8 * saveFilePathUTF8 = widechar_to_utf8(saveFilePath);
|
||||
SDL_RWops * rw = SDL_RWFromFile(saveFilePathUTF8, "wb+");
|
||||
free(saveFilePathUTF8);
|
||||
|
||||
bool savedGameDumped = false;
|
||||
if (rw != NULL) {
|
||||
scenario_save(rw, 0x80000000);
|
||||
savedGameDumped = true;
|
||||
SDL_RWclose(rw);
|
||||
}
|
||||
|
||||
constexpr wchar_t * MessageFormat = L"A crash has occurred and dump was created at\n%s.\n\nPlease create an issue with OpenRCT2 on Github and provide the dump and save.\n\nVersion: %s\nCommit: %s";
|
||||
wchar_t message[MAX_PATH * 2];
|
||||
swprintf_s(message,
|
||||
MessageFormat,
|
||||
dumpFilePath,
|
||||
WSZ(OPENRCT2_VERSION),
|
||||
WSZ(OPENRCT2_COMMIT_SHA1_SHORT));
|
||||
|
||||
// Cannot use platform_show_messagebox here, it tries to set parent window already dead.
|
||||
MessageBoxW(NULL, message, WSZ(OPENRCT2_NAME), MB_OK | MB_ICONERROR);
|
||||
HRESULT coInitializeResult = CoInitialize(NULL);
|
||||
if (SUCCEEDED(coInitializeResult))
|
||||
{
|
||||
ITEMIDLIST * pidl = ILCreateFromPathW(dumpPath);
|
||||
ITEMIDLIST * files[2];
|
||||
uint32 numFiles = 0;
|
||||
|
||||
files[numFiles++] = ILCreateFromPathW(dumpFilePath);
|
||||
if (savedGameDumped)
|
||||
{
|
||||
files[numFiles++] = ILCreateFromPathW(saveFilePath);
|
||||
}
|
||||
if (pidl != nullptr) {
|
||||
HRESULT result = SHOpenFolderAndSelectItems(pidl, numFiles, (LPCITEMIDLIST *)files, 0);
|
||||
ILFree(pidl);
|
||||
for (uint32 i = 0; i < numFiles; i++)
|
||||
{
|
||||
ILFree(files[i]);
|
||||
}
|
||||
}
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
// Return whether the dump was successful
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
static std::wstring GetDumpDirectory()
|
||||
{
|
||||
char userDirectory[MAX_PATH];
|
||||
platform_get_user_directory(userDirectory, NULL);
|
||||
|
||||
wchar_t * userDirectoryW = utf8_to_widechar(userDirectory);
|
||||
auto result = std::wstring(userDirectoryW);
|
||||
free(userDirectoryW);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_BREAKPAD
|
||||
|
||||
// Using non-null pipe name here lets breakpad try setting OOP crash handling
|
||||
constexpr wchar_t * PipeName = L"openrct2-bpad";
|
||||
|
||||
extern "C" CExceptionHandler crash_init()
|
||||
{
|
||||
#ifdef USE_BREAKPAD
|
||||
// Path must exist and be RW!
|
||||
auto exHandler = new google_breakpad::ExceptionHandler(
|
||||
GetDumpDirectory(),
|
||||
0,
|
||||
OnCrash,
|
||||
0,
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL,
|
||||
MiniDumpWithDataSegs,
|
||||
PipeName,
|
||||
0);
|
||||
return reinterpret_cast<CExceptionHandler>(exHandler);
|
||||
#else // USE_BREAKPAD
|
||||
return nullptr;
|
||||
#endif // USE_BREAKPAD
|
||||
}
|
||||
15
src/platform/crash.h
Normal file
15
src/platform/crash.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef _OPENRCT2_CRASH_
|
||||
#define _OPENRCT2_CRASH_
|
||||
|
||||
typedef void * CExceptionHandler;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
CExceptionHandler crash_init();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OPENRCT2_CRASH_ */
|
||||
@@ -811,7 +811,7 @@ void platform_free()
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
void platform_start_text_input(char* buffer, int max_length)
|
||||
void platform_start_text_input(utf8* buffer, int max_length)
|
||||
{
|
||||
// TODO This doesn't work, and position could be improved to where text entry is
|
||||
SDL_Rect rect = { 10, 10, 100, 100 };
|
||||
|
||||
@@ -573,7 +573,7 @@ void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory)
|
||||
}
|
||||
}
|
||||
|
||||
void platform_show_messagebox(char *message)
|
||||
void platform_show_messagebox(utf8 *message)
|
||||
{
|
||||
MessageBoxA(windows_get_window_handle(), message, "OpenRCT2", MB_OK);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user