The message " How to generate stacktrace when a gcc C ++ application crashes " explains how a stack trace can be generated when an application crashes. But the gcc version does not work on Windows MinGW. In fact, it does not even compile due to the missing execinfo.h header.
Is there something already available for MinGW on xp windows and above?
EDIT
Using the steps below, stop varnishing was possible. But I do not get the desired result when I try to go through the stack in a catch block after an exception. I can only get the name of the function throwing the exception, and after that it shows the list β main β etc.
Steps:
First answer provided by post of Win32 API stack using MinGW / MSYS? Jose Luis Sebriana led to a link where the stack trace of Mr.Edd library can be found http://www.mr-edd.co.uk/code/stack_trace
The stack vulnerability available in the link above depends on dbghelp.dll. Since MinGW does not provide an import library, it was generated using dlltool of mingw. The team for which is located
dlltool -k -d dbghelp.def -l dbghelp.a
Note1: .def file was found in the Wine project
Note2: library generation does not work with all versions of MinGW. I am having trouble creating it using version 4.4.1, but it worked fine with 4.6.1
The -lbfd, -lintl, and -liberty libraries were also used to link with -ldbghelp
Structured exception handling was used from the link http://www.programmingunlimited.net/siteexec/content.cgi?page=mingw-seh
Code view
Try as shown below. This part registers an exception handler
{ __SEH_EXCEPTION_REGISTRATION _lseh_er; __SEH_HANDLER _lseh_handler; _lseh_er.handler = reinterpret_cast<PEXCEPTION_HANDLER>(__SEH_HANDLER::ExceptionRouter); _lseh_er.exthandler = &_lseh_handler; asm volatile ("movl %%fs:0, %0" : "=r" (_lseh_er.prev)); asm volatile ("movl %0, %%fs:0" : : "r" (&_lseh_er)); int _lseh_setjmp_res = setjmp(_lseh_handler.context); while(true) { if(_lseh_setjmp_res != 0) { break; }
The ExceptionRounter function calls another ExceptionHandler function, where context and record are copied. The implementation is as follows.
EXCEPTION_DISPOSITION __SEH_HANDLER::ExceptionHandler(PEXCEPTION_RECORD pRecord, __SEH_EXCEPTION_REGISTRATION* pReg, PCONTEXT pContext, PEXCEPTION_RECORD pRecord2) { CopyMemory(&excContext, pContext, sizeof(_CONTEXT)); CopyMemory(&excRecord, pRecord, sizeof(_EXCEPTION_RECORD));
After that, my code that throws an exception
Next, the implementation of catch or seh_excep is executed.
break; } PEXCEPTION_RECORD rec = &_lseh_handler.excRecord; PCONTEXT ctx = &_lseh_handler.excContext; asm volatile ("movl %0, %%fs:0" : : "r" (_lseh_er.prev)); if(_lseh_setjmp_res != 0)
Then the code appears to go to the stack from the Mr.Edd stackupler server.
lock lk(g_fill_frames_mtx); symbol_context sc; bfd_context bfdc; STACKFRAME frame = empty_pod; CONTEXT context = empty_pod; context.ContextFlags = CONTEXT_FULL; context = _lseh_handler.excContex; 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; HANDLE process = GetCurrentProcess(); HANDLE thread = GetCurrentThread(); bool skip = true; bool has_limit = limit != 0; char symbol_buffer[sizeof(IMAGEHLP_SYMBOL) + 255]; char module_name_raw[MAX_PATH]; const DWORD machine = IMAGE_FILE_MACHINE_I386; while(StackWalk(machine, process, thread, &frame, &context, 0, SymFunctionTableAccess, SymGetModuleBase, 0)) { if (skip) { skip = false; continue; } if (has_limit && limit-- == 0) break; IMAGEHLP_SYMBOL *symbol = reinterpret_cast<IMAGEHLP_SYMBOL *>(symbol_buffer); symbol->SizeOfStruct = (sizeof *symbol) + 255; symbol->MaxNameLength = 254; DWORD module_base = SymGetModuleBase(process, frame.AddrPC.Offset); std::string module_name = unknown_module; if (module_base && GetModuleFileNameA(reinterpret_cast<HINSTANCE>(module_base), module_name_raw, MAX_PATH)) module_name = module_name_raw; std::string func = bfdc.get_function_name(frame.AddrPC.Offset); if (func.empty()) { DWORD dummy = 0; BOOL got_symbol = SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol); func = got_symbol ? symbol->Name : unknown_function; } dbg::stack_frame f(reinterpret_cast<const void *>(frame.AddrPC.Offset), func, module_name); frames.push_back(f); } } } std::copy(frames.begin(), frames.end(), std::ostream_iterator<dbg::stack_frame>(std::cout, "\n"));
Regards, Shreias
source share