2010/11/26 Christoph Cullmann <cullm...@absint.de>: > Hi, > > I would like to create automagically backtraces (including function names or > line info, given debug info is around) on crashs. > > I found some code that seems to work ok for 32bit mingw: > http://code.google.com/p/backtrace-mingw/ > > Is there some similar stuff around for the 64bit version? > I searched bit the mailing list archives and the net, but found nothing > working. > > Greetings > Christoph
This small example could give you a good idea how to implement a backtrace for x64 windows. #include <windows.h> #include <stdio.h> #ifdef __cplusplus extern "C" { #endif // Define the function prototypes and structures used by the unwind routines // not included in the Platform SDK headers // ??? typedef PVOID PEXCEPTION_ROUTINE; // http://msdg.microsoft.com/en-us/library/ms680617(VS.85).aspx typedef struct _KNONVOLATILE_CONTEXT_POINTERS { PM128A FloatingContext[16]; PULONG64 IntegerContext[16]; } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; PEXCEPTION_ROUTINE WINAPI RtlVirtualUnwind (ULONG HandlerType, ULONG64 ImageBase, ULONG64 ControlPc, PRUNTIME_FUNCTION FunctionEntry, PCONTEXT ContextRecord, PVOID *HandlerData, PULONG64 EstablisherFrame, PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL); #define UNWIND_HISTORY_TABLE_SIZE 12 typedef struct _UNWIND_HISTORY_TABLE_ENTRY { ULONG64 ImageBase; PRUNTIME_FUNCTION FunctionEntry; } UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY; #define UNWIND_HISTORY_TABLE_NONE 0 #define UNWIND_HISTORY_TABLE_GLOBAL 1 #define UNWIND_HISTORY_TABLE_LOCAL 2 typedef struct _UNWIND_HISTORY_TABLE { ULONG Count; UCHAR Search; ULONG64 LowAddress; ULONG64 HighAddress; UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE]; } UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE; PRUNTIME_FUNCTION WINAPI RtlLookupFunctionEntry (ULONG64 ControlPc, PULONG64 ImageBase, PUNWIND_HISTORY_TABLE HistoryTable OPTIONAL); #ifdef __cplusplus } #endif static void dump_context (CONTEXT *c) { int i; printf("ACDBx : %016I64x %016I64x %016I64x %016I64x\n", c->Rax, c->Rcx, c->Rdx, c->Rbx); printf("SBpSDi: %016I64x %016I64x %016I64x %016I64x\n", c->Rsp, c->Rbp, c->Rsi, c->Rdi); printf("r8-11 : %016I64x %016I64x %016I64x %016I64x\n", c->R8, c->R9, c->R10, c->R11); printf("r12-15: %016I64x %016I64x %016I64x %016I64x\n", c->R12, c->R13, c->R14, c->R15); for (i = 0; i < 16; i += 2) printf("x%02d-%02d: %016I64x.%016I64x %016I64x.%016I64x\n", i, i+1, c->FloatSave.XmmRegisters[i].High, c->FloatSave.XmmRegisters[i].Low, c->FloatSave.XmmRegisters[i + 1].High, c->FloatSave.XmmRegisters[i + 1].Low); fflush (stdout); } void backtrace (void) { CONTEXT context; int i; context.ContextFlags = CONTEXT_ALL; RtlCaptureContext (&context); for (i = 0; ; i++) { PRUNTIME_FUNCTION entry; ULONG64 ControlPC; ULONG64 ImageBase; PVOID HandlerData; ULONG64 EstablisherFrame; ControlPC = context.Rip; entry = RtlLookupFunctionEntry (ControlPC, &ImageBase, NULL); if (entry == NULL) break; printf ("\n#%d %016I64x %p%s\n", i, ControlPC, entry, (i == 0 ? "(backtrace)" : "")); dump_context (&context); RtlVirtualUnwind (0, ImageBase, ControlPC, entry, &context, &HandlerData, &EstablisherFrame, NULL); } } Regards, Kai -- | (\_/) This is Bunny. Copy and paste | (='.'=) Bunny into your signature to help | (")_(") him gain world domination ------------------------------------------------------------------------------ Increase Visibility of Your 3D Game App & Earn a Chance To Win $500! Tap into the largest installed PC base & get more eyes on your game by optimizing for Intel(R) Graphics Technology. Get started today with the Intel(R) Software Partner Program. Five $500 cash prizes are up for grabs. http://p.sf.net/sfu/intelisp-dev2dev _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public