Patch level : 12.0 nopatch

Files correlati     :
Commento        :

Aggiunto stack trace in caso di eccezione nel file stack.log
This commit is contained in:
Alessandro Bonazzi 2021-10-17 23:40:20 +02:00
parent 870c3b85d1
commit b7a4218972

View File

@ -5,6 +5,211 @@
#include <wx/filename.h>
#include <wx/snglinst.h>
#ifdef __WXMSW__
#include <windows.h>
#include <stdio.h>
#include <imagehlp.h>
static FILE * f = nullptr;
void print_stack_element(STACKFRAME frame)
{
//------------------------------------------------------------------
// Declare an image help symbol structure to hold symbol info and
// name up to 256 chars This struct is of variable lenght though so
// it must be declared as a raw byte buffer.
//------------------------------------------------------------------
static char symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 255];
memset(symbolBuffer, 0, sizeof(IMAGEHLP_SYMBOL) + 255);
// Cast it to a symbol struct:
IMAGEHLP_SYMBOL * symbol = (IMAGEHLP_SYMBOL*)symbolBuffer;
// Need to set the first two fields of this symbol before obtaining name info:
symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL) + 255;
symbol->MaxNameLength = 254;
// The displacement from the beginning of the symbol is stored here: pretty useless
unsigned displacement = 0;
// Get the symbol information from the address of the instruction pointer register:
if (SymGetSymFromAddr(GetCurrentProcess(), // Process to get symbol information for
frame.AddrPC.Offset, // Address to get symbol for: instruction pointer register
(DWORD*)& displacement, // Displacement from the beginning of the symbol: whats this for ?
symbol)) // Where to save the symbol
{
// Add the name of the function to the function list:
fprintf(f, "0x%08x %s\n", frame.AddrPC.Offset, symbol->Name);
}
else
{
// Print an unknown location:
// functionNames.push_back("unknown location");
fprintf(f, "0x%08x\n", frame.AddrPC.Offset);
}
}
void windows_print_stacktrace(CONTEXT* context)
{
SymInitialize(GetCurrentProcess(), 0, true);
STACKFRAME frame = { 0 };
/* setup initial stack frame */
frame.AddrPC.Offset = context->Eip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = context->Esp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context->Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
while (StackWalk(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), &frame,
context, 0, SymFunctionTableAccess, SymGetModuleBase, 0))
print_stack_element(frame);
SymCleanup(GetCurrentProcess());
}
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS * ExceptionInfo)
{
fopen_s(&f, "stack.log", xvt_fsys_file_exists("stack.log") != 0 ? "a+tc" : "wtc");
if (f != nullptr)
{
switch (ExceptionInfo->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
fprintf(f, "Error: EXCEPTION_ACCESS_VIOLATION");
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
fprintf(f, "Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
break;
case EXCEPTION_BREAKPOINT:
fprintf(f, "Error: EXCEPTION_BREAKPOINT");
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
fprintf(f, "Error: EXCEPTION_DATATYPE_MISALIGNMENT");
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
fprintf(f, "Error: EXCEPTION_FLT_DENORMAL_OPERAND");
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
fprintf(f, "Error: EXCEPTION_FLT_DIVIDE_BY_ZERO");
break;
case EXCEPTION_FLT_INEXACT_RESULT:
fprintf(f, "Error: EXCEPTION_FLT_INEXACT_RESULT");
break;
case EXCEPTION_FLT_INVALID_OPERATION:
fprintf(f, "Error: EXCEPTION_FLT_INVALID_OPERATION");
break;
case EXCEPTION_FLT_OVERFLOW:
fprintf(f, "Error: EXCEPTION_FLT_OVERFLOW");
break;
case EXCEPTION_FLT_STACK_CHECK:
fprintf(f, "Error: EXCEPTION_FLT_STACK_CHECK");
break;
case EXCEPTION_FLT_UNDERFLOW:
fprintf(f, "Error: EXCEPTION_FLT_UNDERFLOW");
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
fprintf(f, "Error: EXCEPTION_ILLEGAL_INSTRUCTION");
break;
case EXCEPTION_IN_PAGE_ERROR:
fprintf(f, "Error: EXCEPTION_IN_PAGE_ERROR");
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
fprintf(f, "Error: EXCEPTION_INT_DIVIDE_BY_ZERO");
break;
case EXCEPTION_INT_OVERFLOW:
fprintf(f, "Error: EXCEPTION_INT_OVERFLOW");
break;
case EXCEPTION_INVALID_DISPOSITION:
fprintf(f, "Error: EXCEPTION_INVALID_DISPOSITION");
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
fprintf(f, "Error: EXCEPTION_NONCONTINUABLE_EXCEPTION");
break;
case EXCEPTION_PRIV_INSTRUCTION:
fprintf(f, "Error: EXCEPTION_PRIV_INSTRUCTION");
break;
case EXCEPTION_SINGLE_STEP:
fprintf(f, "Error: EXCEPTION_SINGLE_STEP");
break;
case EXCEPTION_STACK_OVERFLOW:
fprintf(f, "Error: EXCEPTION_STACK_OVERFLOW");
break;
default:
return EXCEPTION_EXECUTE_HANDLER; // per ora non mi interessa;
break;
}
/* If this is a stack overflow then we can't walk the stack, so just show
where the error happened */
if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
windows_print_stacktrace(ExceptionInfo->ContextRecord);
else
{
STACKFRAME frame = { 0 };
frame.AddrPC.Offset = ExceptionInfo->ContextRecord->Eip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = ExceptionInfo->ContextRecord->Esp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = ExceptionInfo->ContextRecord->Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
print_stack_element(frame);
}
fflush(f);
}
return EXCEPTION_EXECUTE_HANDLER;
}
static BOOL PreventSetUnhandledExceptionFilter()
{
HMODULE hKernelbase = LoadLibrary(_T("KernelBase.dll"));
HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
if (hKernel32 == nullptr) return false;
void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");
if (pOrgEntry == nullptr) return false;
#ifdef _M_IX86
// Code for x86:
// 33 C0 xor eax,eax
// C2 04 00 ret 4
unsigned char szExecute[] = { 0x33, 0xC0, 0xC2, 0x04, 0x00 };
#elif _M_X64
// 33 C0 xor eax,eax
// C3 ret
unsigned char szExecute[] = { 0x33, 0xC0, 0xC3 };
#else
#error "The following code only works for x86 and x64!"
#endif
SIZE_T bytesWritten = 0;
BOOL bRet = WriteProcessMemory(GetCurrentProcess(),
pOrgEntry, szExecute, sizeof(szExecute), &bytesWritten);
return bRet;
}
void OSWin32_set_signal_handler()
{
AddVectoredExceptionHandler(1L, windows_exception_handler);
// SetUnhandledExceptionFilter(windows_exception_handler);
PreventSetUnhandledExceptionFilter();
}
#else
void OSLinux_set_signal_handler()
{
}
#endif
extern int xvt_main(int argc, char** argv);
class TMainApp : public wxApp
@ -15,8 +220,9 @@ protected:
virtual bool OnInit();
virtual int OnExit();
void OnTimer(wxTimerEvent& evt);
DECLARE_EVENT_TABLE()
// void OnUnhandledException();
DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(TMainApp);
};
@ -32,13 +238,20 @@ END_EVENT_TABLE()
void TMainApp::OnTimer(wxTimerEvent& evt)
{
xvt_app_pre_create();
xvt_main(argc, argv);
xvt_app_pre_create();
xvt_main(argc, argv);
}
bool TMainApp::OnInit()
{
wxFileName strWrk = argv[0];
#ifdef __WXMSW__
OSWin32_set_signal_handler();
#else
OSLinux_set_signal_handler();
#endif
wxFileName strWrk = argv[0];
//const wxString strApp = strWrk.GetName().Lower();
strWrk.MakeAbsolute();
wxString strApp = strWrk.GetFullPath().Lower();
@ -52,6 +265,12 @@ bool TMainApp::OnInit()
return true;
}
/*void TMainApp::OnUnhandledException()
{
windows_exception_handler(nullptr);
}
*/
int TMainApp::OnExit()
{
delete m_sic;