Skip to content

Commit d6308c3

Browse files
committed
- make crash report work
- add Lua stack trace when crash occurs
1 parent 1da3467 commit d6308c3

File tree

4 files changed

+78
-21
lines changed

4 files changed

+78
-21
lines changed

DriverNGHook/CrashHandlerReporter.cpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
#include <DbgHelp.h>
44
#include "Logger.h"
55

6-
bool isExceptionRequierMiniDump(EXCEPTION_POINTERS* frame)
6+
static std::vector<ReHamster::CrashFunc> s_crashFuncs;
7+
8+
static bool isExceptionRequierMiniDump(EXCEPTION_POINTERS* frame)
79
{
810
if (frame->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT ||
911
frame->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
@@ -13,7 +15,7 @@ bool isExceptionRequierMiniDump(EXCEPTION_POINTERS* frame)
1315
return true;
1416
}
1517

16-
void WriteMiniDump(EXCEPTION_POINTERS* exception = nullptr)
18+
static void WriteMiniDump(EXCEPTION_POINTERS* exception = nullptr)
1719
{
1820
//
1921
// Credits https://stackoverflow.com/questions/5028781/how-to-write-a-sample-code-that-will-crash-and-produce-dump-file
@@ -57,7 +59,7 @@ void WriteMiniDump(EXCEPTION_POINTERS* exception = nullptr)
5759
CloseHandle(hFile);
5860
}
5961

60-
void NotifyAboutException(EXCEPTION_POINTERS* exceptionInfoFrame)
62+
static void NotifyAboutException(EXCEPTION_POINTERS* exceptionInfoFrame)
6163
{
6264
MessageBox(
6365
NULL,
@@ -84,21 +86,22 @@ void NotifyAboutException(EXCEPTION_POINTERS* exceptionInfoFrame)
8486
MsgError(" ESP : 0x%x\n", exceptionInfoFrame->ContextRecord->Esp);
8587
MsgError("******************************************************************************\n");
8688

89+
// Extra stuff
90+
for (auto& func : s_crashFuncs)
91+
{
92+
func();
93+
}
94+
8795
WriteMiniDump(exceptionInfoFrame);
8896
}
8997

90-
LONG WINAPI ExceptionFilterWin32(EXCEPTION_POINTERS* exceptionInfoFrame)
98+
static LONG WINAPI ExceptionFilterWin32(EXCEPTION_POINTERS* exceptionInfoFrame)
9199
{
92-
if (isExceptionRequierMiniDump(exceptionInfoFrame))
100+
if (exceptionInfoFrame->ExceptionRecord->ExceptionCode < 0x80000000)
93101
{
94-
NotifyAboutException(exceptionInfoFrame);
102+
return EXCEPTION_CONTINUE_EXECUTION;
95103
}
96104

97-
return EXCEPTION_EXECUTE_HANDLER;
98-
}
99-
100-
LONG WINAPI VectoredExceptionHandlerWin32(EXCEPTION_POINTERS* exceptionInfoFrame)
101-
{
102105
if (isExceptionRequierMiniDump(exceptionInfoFrame))
103106
{
104107
NotifyAboutException(exceptionInfoFrame);
@@ -126,18 +129,16 @@ namespace ReHamster
126129
void CrashHandlerReporter::Install()
127130
{
128131
_set_purecall_handler(PureCallhandler);
129-
m_prevHandler = reinterpret_cast<std::intptr_t>(SetUnhandledExceptionFilter(ExceptionFilterWin32));
132+
m_vectored = reinterpret_cast<std::intptr_t>(AddVectoredExceptionHandler(0UL, ExceptionFilterWin32));
133+
}
134+
135+
void CrashHandlerReporter::AddCrashFunc(CrashFunc onCrash)
136+
{
137+
s_crashFuncs.push_back(std::move(onCrash));
130138
}
131139

132140
CrashHandlerReporter::~CrashHandlerReporter()
133141
{
134-
if (m_prevHandler == 0)
135-
return;
136-
137-
SetUnhandledExceptionFilter(reinterpret_cast<LPTOP_LEVEL_EXCEPTION_FILTER>(m_prevHandler));
138-
if (!AddVectoredExceptionHandler(0UL, VectoredExceptionHandlerWin32))
139-
{
140-
MsgWarning("AddVectoredExceptionHandler failed!\n");
141-
}
142+
RemoveVectoredContinueHandler(reinterpret_cast<PVOID>(m_vectored));
142143
}
143144
}
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
#pragma once
22

33
#include <cstdint>
4+
#include <functional>
45

56
namespace ReHamster
67
{
8+
using CrashFunc = std::function<void()>;
9+
710
class CrashHandlerReporter
811
{
9-
std::intptr_t m_prevHandler{ 0 };
12+
std::intptr_t m_vectored{ 0 };
1013
public:
1114
CrashHandlerReporter();
1215
~CrashHandlerReporter();
1316

1417
void Install();
18+
19+
void AddCrashFunc(CrashFunc onCrash);
1520
};
1621
}

DriverNGHook/Delegates/LuaDelegate.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "Delegates/LuaDelegate.h"
33
#include "UI/DebugTools.h"
44
#include "IInputDelegate.h"
5+
#include "CrashHandlerReporter.h"
56

67
#include "Logger.h"
78

@@ -118,8 +119,15 @@ LuaAsyncQueue g_luaAsyncQueue;
118119

119120
//----------------------------------------------------------------------
120121

122+
namespace ReHamster
123+
{
124+
extern ReHamster::CrashHandlerReporter crashHandlerReporter;
125+
}
126+
121127
namespace DriverNG
122128
{
129+
130+
123131
namespace Consts
124132
{
125133
static const std::string luaScriptsPath = "plugins/DriverNGHook/scripts/";
@@ -166,6 +174,10 @@ namespace DriverNG
166174
if (!instance)
167175
{
168176
instance = new LuaDelegate();
177+
178+
ReHamster::crashHandlerReporter.AddCrashFunc([]() {
179+
instance->PrintLuaStackTrace();
180+
});
169181
}
170182

171183
return *instance;
@@ -396,4 +408,41 @@ namespace DriverNG
396408
{
397409
return m_callLuaFunc;
398410
}
411+
412+
void LuaDelegate::PrintLuaStackTrace()
413+
{
414+
if (!m_gameState)
415+
return;
416+
417+
lua_State* L = m_gameState;
418+
lua_Debug ar;
419+
int depth = 0;
420+
421+
Msg("\nLua stack trace:\n");
422+
423+
while (lua_getstack(L, depth, &ar))
424+
{
425+
int status = lua_getinfo(L, "Sln", &ar);
426+
assert(status);
427+
428+
Msg("\t %s:", ar.short_src);
429+
if (ar.currentline > 0)
430+
Msg("%d:", ar.currentline);
431+
if (*ar.namewhat != '\0') /* is there a name? */
432+
Msg(" in function '%s'", ar.name);
433+
else
434+
{
435+
if (*ar.what == 'm') /* main? */
436+
Msg(" in main chunk");
437+
else if (*ar.what == 'C' || *ar.what == 't')
438+
Msg(" ?"); /* C function or tail call */
439+
else
440+
Msg(" in function <%s:%d>",
441+
ar.short_src, ar.linedefined);
442+
}
443+
Msg("\n");
444+
depth++;
445+
}
446+
Msg("\n");
447+
}
399448
};

DriverNGHook/Delegates/LuaDelegate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace DriverNG
2626

2727
CallLuaFunction_t GetCallLuaFunction() override;
2828

29+
void PrintLuaStackTrace();
30+
2931
protected:
3032

3133
bool IsValidLuaState() const;

0 commit comments

Comments
 (0)