diff options
author | marha <marha@users.sourceforge.net> | 2013-06-26 15:01:24 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2013-06-26 15:01:24 +0200 |
commit | 2fe2056807d1304de86deb2b59992d51d9252ad0 (patch) | |
tree | 665d730ee19df03e4dfca01371009ec778a343af /mesalib/src/gallium/auxiliary/util/u_debug_stack.c | |
parent | fa791414601df61d20d860299dba80fdb62565df (diff) | |
download | vcxsrv-2fe2056807d1304de86deb2b59992d51d9252ad0.tar.gz vcxsrv-2fe2056807d1304de86deb2b59992d51d9252ad0.tar.bz2 vcxsrv-2fe2056807d1304de86deb2b59992d51d9252ad0.zip |
libXext mesa git update 29 June 20013
libXext commit 7378d4bdbd33ed49ed6cfa5c4f73d7527982aab4
mesa commit 9aebad618c0aab527a0b838ce0a79ffa6dd426bb
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; |