mirror of
https://github.com/glest/glest-source.git
synced 2025-08-18 14:11:15 +02:00
- try to improve error handling on windows for better stack traces
This commit is contained in:
@@ -278,15 +278,113 @@ void fatal(const char *s, ...) // failure exit
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void write_module_name(string &out, HANDLE process, DWORD64 program_counter) {
|
||||||
|
DWORD64 module_base = SymGetModuleBase64(process, program_counter);
|
||||||
|
if (module_base) {
|
||||||
|
std::string module_name = get_module_path(reinterpret_cast<HMODULE>(module_base));
|
||||||
|
if (!module_name.empty())
|
||||||
|
out += module_name + "|";
|
||||||
|
else
|
||||||
|
os += "Unknown module|";
|
||||||
|
} else {
|
||||||
|
os += "Unknown module|";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_function_name(string &out, HANDLE process, DWORD64 program_counter) {
|
||||||
|
SYMBOL_INFO_PACKAGE sym = { sizeof(sym) };
|
||||||
|
sym.si.MaxNameLen = MAX_SYM_NAME;
|
||||||
|
if (SymFromAddr(process, program_counter, 0, &sym.si)) {
|
||||||
|
os += sym.si.Name += "()";
|
||||||
|
} else {
|
||||||
|
os += "Unknown function";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_file_and_line(std::ostream & os, HANDLE process, DWORD64 program_counter) {
|
||||||
|
IMAGEHLP_LINE64 ih_line = { sizeof(IMAGEHLP_LINE64) };
|
||||||
|
DWORD dummy = 0;
|
||||||
|
if (SymGetLineFromAddr64(process, program_counter, &dummy, &ih_line)) {
|
||||||
|
os += "|" += ih_line.FileName += ":" += ih_line.LineNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void generate_stack_trace(string &out, CONTEXT ctx, int skip) {
|
||||||
|
STACKFRAME64 sf = {};
|
||||||
|
sf.AddrPC.Offset = ctx.Eip;
|
||||||
|
sf.AddrPC.Mode = AddrModeFlat;
|
||||||
|
sf.AddrStack.Offset = ctx.Esp;
|
||||||
|
sf.AddrStack.Mode = AddrModeFlat;
|
||||||
|
sf.AddrFrame.Offset = ctx.Ebp;
|
||||||
|
sf.AddrFrame.Mode = AddrModeFlat;
|
||||||
|
|
||||||
|
HANDLE process = GetCurrentProcess();
|
||||||
|
HANDLE thread = GetCurrentThread();
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
SetLastError(0);
|
||||||
|
BOOL stack_walk_ok = StackWalk64(IMAGE_FILE_MACHINE_I386, process, thread, &sf,
|
||||||
|
&ctx, 0, &SymFunctionTableAccess64,
|
||||||
|
&SymGetModuleBase64, 0);
|
||||||
|
if (!stack_walk_ok || !sf.AddrFrame.Offset) return;
|
||||||
|
|
||||||
|
if (skip) {
|
||||||
|
--skip;
|
||||||
|
} else {
|
||||||
|
// write the address
|
||||||
|
out += reinterpret_cast<void *>(sf.AddrPC.Offset) + "|";
|
||||||
|
|
||||||
|
write_module_name(out, process, sf.AddrPC.Offset);
|
||||||
|
write_function_name(out, process, sf.AddrPC.Offset);
|
||||||
|
write_file_and_line(out, process, sf.AddrPC.Offset);
|
||||||
|
|
||||||
|
out += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep) {
|
void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep) {
|
||||||
if(!ep) fatal("unknown type");
|
if(!ep) fatal("unknown type");
|
||||||
EXCEPTION_RECORD *er = ep->ExceptionRecord;
|
EXCEPTION_RECORD *er = ep->ExceptionRecord;
|
||||||
CONTEXT *context = ep->ContextRecord;
|
CONTEXT *context = ep->ContextRecord;
|
||||||
stringType out, t;
|
//stringType out, t;
|
||||||
formatstring(out)("%s Exception: 0x%x [0x%x]\n\n", mg_app_name, er->ExceptionCode, er->ExceptionCode==EXCEPTION_ACCESS_VIOLATION ? er->ExceptionInformation[1] : -1);
|
//formatstring(out)("%s Exception: 0x%x [0x%x]\n\n", mg_app_name, er->ExceptionCode, er->ExceptionCode==EXCEPTION_ACCESS_VIOLATION ? er->ExceptionInformation[1] : -1);
|
||||||
|
string out="";
|
||||||
|
//char szBuf[8096]="";
|
||||||
|
//snsprintf(szBuf,"%s Exception: 0x%x [0x%x]\n\n", mg_app_name, er->ExceptionCode, er->ExceptionCode==EXCEPTION_ACCESS_VIOLATION ? er->ExceptionInformation[1] : -1);
|
||||||
|
//out = szBuf;
|
||||||
|
|
||||||
|
int skip = 0;
|
||||||
|
switch (er->ExceptionCode) {
|
||||||
|
case 0xE06D7363: { // C++ exception
|
||||||
|
UntypedException ue(er);
|
||||||
|
if (std::exception * e = exception_cast<std::exception>(ue)) {
|
||||||
|
const std::type_info & ti = typeid(*e);
|
||||||
|
out += ti.name() += ":" += e->what();
|
||||||
|
} else {
|
||||||
|
out += "Unknown C++ exception thrown.";
|
||||||
|
}
|
||||||
|
skip = 2; // skip RaiseException and _CxxThrowException
|
||||||
|
} break;
|
||||||
|
case EXCEPTION_ACCESS_VIOLATION: {
|
||||||
|
out += "Access violation. Illegal "
|
||||||
|
+ (er.ExceptionInformation[0] ? "write" : "read")
|
||||||
|
+ " by "
|
||||||
|
+ er.ExceptionAddress
|
||||||
|
+ " at "
|
||||||
|
+ reinterpret_cast<void *>(er.ExceptionInformation[1]);
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
out += "SEH exception thrown. Exception code: "
|
||||||
|
+ er.ExceptionCode
|
||||||
|
+ " at "
|
||||||
|
+ er.ExceptionAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
STACKFRAME sf = {{context->Eip, 0, AddrModeFlat}, {}, {context->Ebp, 0, AddrModeFlat}, {context->Esp, 0, AddrModeFlat}, 0};
|
STACKFRAME sf = {{context->Eip, 0, AddrModeFlat}, {}, {context->Ebp, 0, AddrModeFlat}, {context->Esp, 0, AddrModeFlat}, 0};
|
||||||
SymInitialize(GetCurrentProcess(), NULL, TRUE);
|
SymInitialize(GetCurrentProcess(), NULL, TRUE);
|
||||||
|
|
||||||
|
generate_stack_trace(out, CONTEXT ctx, skip);
|
||||||
|
/*
|
||||||
while(::StackWalk(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), &sf, context, NULL, ::SymFunctionTableAccess, ::SymGetModuleBase, NULL)) {
|
while(::StackWalk(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), &sf, context, NULL, ::SymFunctionTableAccess, ::SymGetModuleBase, NULL)) {
|
||||||
struct { IMAGEHLP_SYMBOL sym; stringType n; }
|
struct { IMAGEHLP_SYMBOL sym; stringType n; }
|
||||||
si = { { sizeof( IMAGEHLP_SYMBOL ), 0, 0, 0, sizeof(stringType) } };
|
si = { { sizeof( IMAGEHLP_SYMBOL ), 0, 0, 0, sizeof(stringType) } };
|
||||||
@@ -300,6 +398,8 @@ void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep) {
|
|||||||
concatstring(out, t);
|
concatstring(out, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
fatal(out);
|
fatal(out);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user