Skip to content

Commit

Permalink
Refactored xrDebug
Browse files Browse the repository at this point in the history
Engine will exit fullscreen mode when crash is happened

Under debugger you can press any key except Abort to trigger a debug
break when FATAL ERROR was triggered

Expanded minidump capabilities.You can use either -full_memory_dump (it
can be HUGE) or -detailed_minidump (should be acceptable size) to
produce more detailed dump

Crash report files folder will be set up right after filesystem initialized

Renamed X-Ray Engine to OpenXRay
  • Loading branch information
Xottab-DUTY committed May 14, 2019
1 parent d9066cd commit 2767faa
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 33 deletions.
1 change: 1 addition & 0 deletions src/xrCore/LocatorAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,7 @@ void CLocatorAPI::_initialize(u32 flags, pcstr target_folder, pcstr fs_name)
//-----------------------------------------------------------

CreateLog(nullptr != strstr(Core.Params, "-nolog"));
xrDebug::OnFilesystemInitialized();
}

void CLocatorAPI::_destroy()
Expand Down
112 changes: 84 additions & 28 deletions src/xrCore/xrDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ AssertionResult xrDebug::ShowMessage(pcstr title, pcstr message, bool simpleMode
#ifdef WINDOWS // because Windows default Message box is fancy
HWND hwnd = nullptr;

if (applicationWindow)
if (windowHandler)
{
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (SDL_GetWindowWMInfo(applicationWindow, &info))
if (SDL_GetWindowWMInfo(windowHandler->GetApplicationWindow(), &info))
{
switch (info.subsystem)
{
Expand Down Expand Up @@ -156,11 +156,13 @@ AssertionResult xrDebug::ShowMessage(pcstr title, pcstr message, bool simpleMode
#else
if (simpleMode)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, message, applicationWindow);
SDL_Window* parent = windowHandler ? windowHandler->GetApplicationWindow() : nullptr;
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, message, parent);
return AssertionResult::ok;
}

messageboxdata.window = applicationWindow;
if (windowHandler)
messageboxdata.window = windowHandler->GetApplicationWindow();
messageboxdata.title = title;
messageboxdata.message = message;
int button = -1;
Expand Down Expand Up @@ -200,7 +202,7 @@ SDL_AssertState SDLAssertionHandler(const SDL_AssertData* data,
}
}

SDL_Window* xrDebug::applicationWindow = nullptr;
IWindowHandler* xrDebug::windowHandler = nullptr;
xrDebug::UnhandledExceptionFilter xrDebug::PrevFilter = nullptr;
xrDebug::OutOfMemoryCallbackFunc xrDebug::OutOfMemoryCallback = nullptr;
xrDebug::CrashHandler xrDebug::OnCrash = nullptr;
Expand Down Expand Up @@ -521,6 +523,9 @@ AssertionResult xrDebug::Fail(bool& ignoreAlways, const ErrorLocation& loc, cons
OnDialog(true);
FlushLog();

if (windowHandler)
windowHandler->DisableFullscreen();

AssertionResult result = AssertionResult::abort;
if (Core.PluginMode)
/*result =*/ ShowMessage("X-Ray error", assertionInfo); // Do not assign 'result'
Expand Down Expand Up @@ -561,6 +566,11 @@ AssertionResult xrDebug::Fail(bool& ignoreAlways, const ErrorLocation& loc, cons
if (OnDialog)
OnDialog(false);

#ifdef USE_OWN_ERROR_MESSAGE_WINDOW
if (windowHandler)
windowHandler->ResetFullscreen();
#endif

lock.Leave();
return result;
}
Expand All @@ -573,11 +583,27 @@ AssertionResult xrDebug::Fail(bool& ignoreAlways, const ErrorLocation& loc, cons

void xrDebug::DoExit(const std::string& message)
{
if (windowHandler)
windowHandler->DisableFullscreen();

FlushLog();
ShowMessage("Error", message.c_str());

if (IsDebuggerPresent())
{
const auto result = ShowMessage("Error", message.c_str(), false);
if (result != AssertionResult::abort)
DEBUG_BREAK;
}
else
ShowMessage("Error", message.c_str());

#if defined(WINDOWS)
TerminateProcess(GetCurrentProcess(), 1);
#endif

volatile bool neverTrue = false; // if you're under debugger,
if (neverTrue && windowHandler) // you can jump here manually
windowHandler->ResetFullscreen(); // to reset fullscreen
}

LPCSTR xrDebug::ErrorToString(long code)
Expand Down Expand Up @@ -643,12 +669,6 @@ void WINAPI xrDebug::PreErrorHandler(INT_PTR)
if (*BugReportFile)
BT_AddLogFile(BugReportFile);

string_path dumpPath;
if (FS.path_exist("$app_data_root$"))
FS.update_path(dumpPath, "$app_data_root$", "");
xr_strcat(dumpPath, "reports");

BT_SetReportFilePath(dumpPath);
BT_SaveSnapshot(nullptr);
#endif
}
Expand All @@ -668,23 +688,27 @@ void xrDebug::SetupExceptionHandler()
else
BT_SetActivityType(BTA_SAVEREPORT);
BT_SetDialogMessage(BTDM_INTRO2,
"This is X-Ray Engine v1.6 crash reporting client. "
"This is OpenXRay crash reporting client. "
"To help the development process, "
"please Submit Bug or save report and email it manually (button More...)."
"\r\n"
"Many thanks in advance and sorry for the inconvenience.");
BT_SetPreErrHandler(PreErrorHandler, 0);
BT_SetAppName("X-Ray Engine");
BT_SetAppName("OpenXRay");
BT_SetReportFormat(BTRF_TEXT);
BT_SetFlags(BTF_DETAILEDMODE | BTF_ATTACHREPORT);

#ifdef MASTER_GOLD
auto minidumpFlags = MiniDumpFilterMemory | MiniDumpScanMemory;
auto minidumpFlags = MiniDumpWithDataSegs|
MiniDumpWithIndirectlyReferencedMemory |
MiniDumpScanMemory |
MiniDumpWithProcessThreadData |
MiniDumpWithThreadInfo;

if (strstr(commandLine, "-detailed_minidump"))
minidumpFlags = MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory;
#else
const auto minidumpFlags = MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory;
if (strstr(commandLine, "-full_memory_dump"))
minidumpFlags |= MiniDumpWithFullMemory | MiniDumpIgnoreInaccessibleMemory;
#ifdef MASTER_GOLD
else if (!strstr(commandLine, "-detailed_minidump"))
minidumpFlags |= MiniDumpFilterMemory;
#endif

BT_SetDumpType(minidumpFlags);
Expand All @@ -693,10 +717,19 @@ void xrDebug::SetupExceptionHandler()
#endif
}

void xrDebug::OnFilesystemInitialized()
{
string_path dumpPath;
if (FS.update_path(dumpPath, "$app_data_root$", "reports", false))
{
BT_SetReportFilePath(dumpPath);
}
}

void xrDebug::FormatLastError(char* buffer, const size_t& bufferSize)
{
#if defined(WINDOWS)
int lastErr = GetLastError();
const int lastErr = GetLastError();
if (lastErr == ERROR_SUCCESS)
{
*buffer = 0;
Expand Down Expand Up @@ -749,27 +782,50 @@ LONG WINAPI xrDebug::UnhandledFilter(EXCEPTION_POINTERS* exPtrs)
}
if (shared_str_initialized)
FlushLog();
#ifndef USE_OWN_ERROR_MESSAGE_WINDOW
#ifdef USE_OWN_MINI_DUMP
SaveMiniDump(exPtrs);
#endif
#else

if (windowHandler)
windowHandler->DisableFullscreen();

#ifdef USE_OWN_ERROR_MESSAGE_WINDOW
constexpr pcstr fatalError = "Fatal error";

AssertionResult msgRes = AssertionResult::abort;
if (!ErrorAfterDialog)
{
if (OnDialog)
OnDialog(true);

constexpr pcstr msg = "Fatal error occurred\n\n"
"Press OK to abort program execution";
ShowMessage("Fatal error", msg);
msgRes = ShowMessage(fatalError, msg);
}
#endif
ReportFault(exPtrs, 0);
BT_SetUserMessage(fatalError);
BT_SaveSnapshotEx(exPtrs, nullptr);

const auto reportRes = ReportFault(exPtrs, 0);
if (msgRes != AssertionResult::abort ||
reportRes == frrvLaunchDebugger)
{
while (true)
{
if (IsDebuggerPresent())
DEBUG_BREAK;
}
}

if (PrevFilter)
PrevFilter(exPtrs);

#ifdef USE_OWN_ERROR_MESSAGE_WINDOW
if (OnDialog)
OnDialog(false);
#endif

volatile bool neverTrue = false; // if you're under debugger,
if (neverTrue && windowHandler) // you can manually
windowHandler->ResetFullscreen(); // reset fullscreen

return EXCEPTION_CONTINUE_SEARCH;
#else
return 0;
Expand Down
15 changes: 12 additions & 3 deletions src/xrCore/xrDebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ class ErrorLocation
}
};

class IWindowHandler
{
public:
virtual SDL_Window* GetApplicationWindow() = 0;
virtual void DisableFullscreen() = 0;
virtual void ResetFullscreen() = 0;
};

class XRCORE_API xrDebug
{
public:
Expand All @@ -57,7 +65,7 @@ class XRCORE_API xrDebug
using UnhandledExceptionFilter = LONG(WINAPI*)(EXCEPTION_POINTERS* exPtrs);

private:
static SDL_Window* applicationWindow;
static IWindowHandler* windowHandler;
static UnhandledExceptionFilter PrevFilter;
static OutOfMemoryCallbackFunc OutOfMemoryCallback;
static CrashHandler OnCrash;
Expand All @@ -70,9 +78,10 @@ class XRCORE_API xrDebug
static void Initialize();
static void Destroy();
static void OnThreadSpawn();
static void OnFilesystemInitialized();

static SDL_Window* GetApplicationWindow() { return applicationWindow; }
static void SetApplicationWindow(SDL_Window* window) { applicationWindow = window; }
static IWindowHandler* GetWindowHandler() { return windowHandler; }
static void SetWindowHandler(IWindowHandler* handler) { windowHandler = handler; }
static OutOfMemoryCallbackFunc GetOutOfMemoryCallback() { return OutOfMemoryCallback; }
static void SetOutOfMemoryCallback(OutOfMemoryCallbackFunc cb) { OutOfMemoryCallback = cb; }
static CrashHandler GetCrashHandler() { return OnCrash; }
Expand Down
2 changes: 1 addition & 1 deletion src/xrEngine/Device_Initialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void CRenderDevice::Initialize()
R_ASSERT3(m_sdlWnd, "Unable to create SDL window", SDL_GetError());
SDL_SetWindowHitTest(m_sdlWnd, WindowHitTest, nullptr);
SDL_SetWindowMinimumSize(m_sdlWnd, 256, 192);
xrDebug::SetApplicationWindow(m_sdlWnd);
xrDebug::SetWindowHandler(this);
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/xrEngine/Device_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,18 @@ void CRenderDevice::SelectResolution(const bool windowed)
dwHeight = psCurrentVidMode[1];
}
}

SDL_Window* CRenderDevice::GetApplicationWindow()
{
return m_sdlWnd;
}

void CRenderDevice::DisableFullscreen()
{
SDL_SetWindowFullscreen(m_sdlWnd, SDL_FALSE);
}

void CRenderDevice::ResetFullscreen()
{
UpdateWindowProps(!psDeviceFlags.test(rsFullscreen));
}
6 changes: 5 additions & 1 deletion src/xrEngine/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class ENGINE_API CRenderDeviceBase : public IRenderDevice, public CRenderDeviceD

#pragma pack(pop)
// refs
class ENGINE_API CRenderDevice : public CRenderDeviceBase
class ENGINE_API CRenderDevice : public CRenderDeviceBase, public IWindowHandler
{
public:
class ENGINE_API CSecondVPParams //--#SM+#-- +SecondVP+
Expand Down Expand Up @@ -279,6 +279,10 @@ class ENGINE_API CRenderDevice : public CRenderDeviceBase
virtual const RenderDeviceStatictics& GetStats() const override { return stats; }
virtual void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) override;

SDL_Window* GetApplicationWindow() override;
void DisableFullscreen() override;
void ResetFullscreen() override;

void time_factor(const float& time_factor)
{
Timer.time_factor(time_factor);
Expand Down

0 comments on commit 2767faa

Please sign in to comment.