Patch level : 12.0 nopatch
Files correlati : Commento : Aggiunto stack trace in caso di eccezione nel file stack.log
This commit is contained in:
parent
870c3b85d1
commit
b7a4218972
@ -5,6 +5,211 @@
|
|||||||
#include <wx/filename.h>
|
#include <wx/filename.h>
|
||||||
#include <wx/snglinst.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);
|
extern int xvt_main(int argc, char** argv);
|
||||||
|
|
||||||
class TMainApp : public wxApp
|
class TMainApp : public wxApp
|
||||||
@ -15,8 +220,9 @@ protected:
|
|||||||
virtual bool OnInit();
|
virtual bool OnInit();
|
||||||
virtual int OnExit();
|
virtual int OnExit();
|
||||||
void OnTimer(wxTimerEvent& evt);
|
void OnTimer(wxTimerEvent& evt);
|
||||||
|
// void OnUnhandledException();
|
||||||
DECLARE_EVENT_TABLE()
|
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
DECLARE_DYNAMIC_CLASS(TMainApp);
|
DECLARE_DYNAMIC_CLASS(TMainApp);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -32,13 +238,20 @@ END_EVENT_TABLE()
|
|||||||
|
|
||||||
void TMainApp::OnTimer(wxTimerEvent& evt)
|
void TMainApp::OnTimer(wxTimerEvent& evt)
|
||||||
{
|
{
|
||||||
xvt_app_pre_create();
|
xvt_app_pre_create();
|
||||||
xvt_main(argc, argv);
|
xvt_main(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TMainApp::OnInit()
|
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();
|
//const wxString strApp = strWrk.GetName().Lower();
|
||||||
strWrk.MakeAbsolute();
|
strWrk.MakeAbsolute();
|
||||||
wxString strApp = strWrk.GetFullPath().Lower();
|
wxString strApp = strWrk.GetFullPath().Lower();
|
||||||
@ -52,6 +265,12 @@ bool TMainApp::OnInit()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*void TMainApp::OnUnhandledException()
|
||||||
|
{
|
||||||
|
windows_exception_handler(nullptr);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
int TMainApp::OnExit()
|
int TMainApp::OnExit()
|
||||||
{
|
{
|
||||||
delete m_sic;
|
delete m_sic;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user