Merge remote branch 'origin/master' into lp-binning
[mesa.git] / src / gallium / auxiliary / util / u_debug_stack.c
index 76068a65091744f747c083b81d291dfdd2e6a0f9..528a1c394befa0bf1dbb810f1c184cd968d9a5d7 100644 (file)
@@ -33,6 +33,7 @@
  */
 
 #include "u_debug.h"
+#include "u_debug_symbol.h"
 #include "u_debug_stack.h"
 
 
@@ -49,7 +50,7 @@ debug_backtrace_capture(struct debug_stack_frame *backtrace,
 
 #if defined(PIPE_CC_GCC)
    frame_pointer = ((const void **)__builtin_frame_address(1));
-#elif defined(PIPE_CC_MSVC)
+#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
    __asm {
       mov frame_pointer, ebp
    }
@@ -61,6 +62,8 @@ debug_backtrace_capture(struct debug_stack_frame *backtrace,
    
 #ifdef PIPE_ARCH_X86
    while(nr_frames) {
+      const void **next_frame_pointer;
+
       if(!frame_pointer)
          break;
       
@@ -71,7 +74,14 @@ debug_backtrace_capture(struct debug_stack_frame *backtrace,
          --nr_frames;
       }
       
-      frame_pointer = (const void **)frame_pointer[0];
+      next_frame_pointer = (const void **)frame_pointer[0];
+      
+      /* Limit the stack walk to avoid referencing undefined memory */
+      if((uintptr_t)next_frame_pointer <= (uintptr_t)frame_pointer ||
+         (uintptr_t)next_frame_pointer > (uintptr_t)frame_pointer + 64*1024)
+         break;
+      
+      frame_pointer = next_frame_pointer;
    }
 #endif
    
@@ -91,7 +101,7 @@ debug_backtrace_dump(const struct debug_stack_frame *backtrace,
    for(i = 0; i < nr_frames; ++i) {
       if(!backtrace[i].function)
          break;
-      debug_printf("\t%p\n", backtrace[i].function);
+      debug_symbol_print(backtrace[i].function);
    }
 }