diff options
author | marha <marha@users.sourceforge.net> | 2013-06-28 16:49:07 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2013-06-28 16:49:07 +0200 |
commit | 3c204c4a20943586532ce477ced827d108f3b4b0 (patch) | |
tree | c9891fdc315c41cc90806634589231172572b2ba /mesalib/src/gallium/auxiliary/util/u_debug_stack.c | |
parent | 73a26452133415b7e3bf54836d23995d59a7bac4 (diff) | |
parent | ced1a6b8f5a750fcd3b8d3d0d9bbdee830064e6c (diff) | |
download | vcxsrv-3c204c4a20943586532ce477ced827d108f3b4b0.tar.gz vcxsrv-3c204c4a20943586532ce477ced827d108f3b4b0.tar.bz2 vcxsrv-3c204c4a20943586532ce477ced827d108f3b4b0.zip |
Merge remote-tracking branch 'origin/released'
* origin/released:
fontconfig mesa git update 28 June 2013
libXext mesa git update 29 June 20013
Diffstat (limited to 'mesalib/src/gallium/auxiliary/util/u_debug_stack.c')
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_debug_stack.c | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_stack.c b/mesalib/src/gallium/auxiliary/util/u_debug_stack.c index 50a248a97..68961d351 100644 --- a/mesalib/src/gallium/auxiliary/util/u_debug_stack.c +++ b/mesalib/src/gallium/auxiliary/util/u_debug_stack.c @@ -36,7 +36,17 @@ #include "u_debug_symbol.h" #include "u_debug_stack.h" +#if defined(PIPE_OS_WINDOWS) +#include <windows.h> +#endif + +/** + * Capture stack backtrace. + * + * NOTE: The implementation of this function is quite big, but it is important not to + * break it down in smaller functions to avoid adding new frames to the calling stack. + */ void debug_backtrace_capture(struct debug_stack_frame *backtrace, unsigned start_frame, @@ -45,8 +55,50 @@ debug_backtrace_capture(struct debug_stack_frame *backtrace, const void **frame_pointer = NULL; unsigned i = 0; - if(!nr_frames) + if (!nr_frames) { return; + } + + /* + * On Windows try obtaining the stack backtrace via CaptureStackBackTrace. + * + * It works reliably both for x86 for x86_64. + */ +#if defined(PIPE_OS_WINDOWS) + { + typedef USHORT (WINAPI *PFNCAPTURESTACKBACKTRACE)(ULONG, ULONG, PVOID *, PULONG); + static PFNCAPTURESTACKBACKTRACE pfnCaptureStackBackTrace = NULL; + + if (!pfnCaptureStackBackTrace) { + static HMODULE hModule = NULL; + if (!hModule) { + hModule = LoadLibraryA("kernel32"); + assert(hModule); + } + if (hModule) { + pfnCaptureStackBackTrace = (PFNCAPTURESTACKBACKTRACE)GetProcAddress(hModule, + "RtlCaptureStackBackTrace"); + } + } + if (pfnCaptureStackBackTrace) { + /* + * Skip this (debug_backtrace_capture) function's frame. + */ + + start_frame += 1; + + assert(start_frame + nr_frames < 63); + i = pfnCaptureStackBackTrace(start_frame, nr_frames, (PVOID *) &backtrace->function, NULL); + + /* Pad remaing requested frames with NULL */ + while (i < nr_frames) { + backtrace[i++].function = NULL; + } + + return; + } + } +#endif #if defined(PIPE_CC_GCC) frame_pointer = ((const void **)__builtin_frame_address(1)); @@ -86,7 +138,7 @@ debug_backtrace_capture(struct debug_stack_frame *backtrace, #else (void) frame_pointer; #endif - + while(nr_frames) { backtrace[i++].function = NULL; --nr_frames; |