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/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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user