From ee4e4a6b964a3a91fcb922d4e82abff62da39102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 20 Feb 2009 11:35:23 +0000 Subject: [PATCH] util: Stack backtracing facilities. Not much useful until we have symbol lookup. --- src/gallium/auxiliary/util/SConscript | 1 + src/gallium/auxiliary/util/u_debug_memory.c | 7 ++ src/gallium/auxiliary/util/u_debug_stack.c | 97 +++++++++++++++++++++ src/gallium/auxiliary/util/u_debug_stack.h | 65 ++++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 src/gallium/auxiliary/util/u_debug_stack.c create mode 100644 src/gallium/auxiliary/util/u_debug_stack.h diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 84e4c484761..5d336ea082a 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -8,6 +8,7 @@ util = env.ConvenienceLibrary( 'u_debug.c', 'u_debug_memory.c', 'u_debug_profile.c', + 'u_debug_stack.c', 'u_draw_quad.c', 'u_gen_mipmap.c', 'u_handle_table.c', diff --git a/src/gallium/auxiliary/util/u_debug_memory.c b/src/gallium/auxiliary/util/u_debug_memory.c index f6c136f6e5a..758541c2829 100644 --- a/src/gallium/auxiliary/util/u_debug_memory.c +++ b/src/gallium/auxiliary/util/u_debug_memory.c @@ -45,10 +45,12 @@ #endif #include "util/u_debug.h" +#include "util/u_debug_stack.h" #include "util/u_double_list.h" #define DEBUG_MEMORY_MAGIC 0x6e34090aU +#define DEBUG_MEMORY_STACK 0 /* XXX: disabled until we have symbol lookup */ #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && !defined(WINCE) @@ -71,7 +73,9 @@ struct debug_memory_header const char *file; unsigned line; const char *function; + struct debug_stack_frame backtrace[DEBUG_MEMORY_STACK]; size_t size; + unsigned magic; }; @@ -136,6 +140,8 @@ debug_malloc(const char *file, unsigned line, const char *function, hdr->size = size; hdr->magic = DEBUG_MEMORY_MAGIC; + debug_backtrace_capture(hdr->backtrace, 0, DEBUG_MEMORY_STACK); + ftr = footer_from_header(hdr); ftr->magic = DEBUG_MEMORY_MAGIC; @@ -290,6 +296,7 @@ debug_memory_end(unsigned long start_no) debug_printf("%s:%u:%s: %u bytes at %p not freed\n", hdr->file, hdr->line, hdr->function, hdr->size, ptr); + debug_backtrace_dump(hdr->backtrace, DEBUG_MEMORY_STACK); total_size += hdr->size; } diff --git a/src/gallium/auxiliary/util/u_debug_stack.c b/src/gallium/auxiliary/util/u_debug_stack.c new file mode 100644 index 00000000000..76068a65091 --- /dev/null +++ b/src/gallium/auxiliary/util/u_debug_stack.c @@ -0,0 +1,97 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Stack backtracing. + * + * @author Jose Fonseca + */ + +#include "u_debug.h" +#include "u_debug_stack.h" + + +void +debug_backtrace_capture(struct debug_stack_frame *backtrace, + unsigned start_frame, + unsigned nr_frames) +{ + const void **frame_pointer = NULL; + unsigned i = 0; + + if(!nr_frames) + return; + +#if defined(PIPE_CC_GCC) + frame_pointer = ((const void **)__builtin_frame_address(1)); +#elif defined(PIPE_CC_MSVC) + __asm { + mov frame_pointer, ebp + } + frame_pointer = (const void **)frame_pointer[0]; +#else + frame_pointer = NULL; +#endif + + +#ifdef PIPE_ARCH_X86 + while(nr_frames) { + if(!frame_pointer) + break; + + if(start_frame) + --start_frame; + else { + backtrace[i++].function = frame_pointer[1]; + --nr_frames; + } + + frame_pointer = (const void **)frame_pointer[0]; + } +#endif + + while(nr_frames) { + backtrace[i++].function = NULL; + --nr_frames; + } +} + + +void +debug_backtrace_dump(const struct debug_stack_frame *backtrace, + unsigned nr_frames) +{ + unsigned i; + + for(i = 0; i < nr_frames; ++i) { + if(!backtrace[i].function) + break; + debug_printf("\t%p\n", backtrace[i].function); + } +} + diff --git a/src/gallium/auxiliary/util/u_debug_stack.h b/src/gallium/auxiliary/util/u_debug_stack.h new file mode 100644 index 00000000000..f50f04e0f7b --- /dev/null +++ b/src/gallium/auxiliary/util/u_debug_stack.h @@ -0,0 +1,65 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef U_DEBUG_STACK_H_ +#define U_DEBUG_STACK_H_ + + +/** + * @file + * Stack backtracing. + * + * @author Jose Fonseca + */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct debug_stack_frame +{ + const void *function; +}; + + +void +debug_backtrace_capture(struct debug_stack_frame *backtrace, + unsigned start_frame, + unsigned nr_frames); + +void +debug_backtrace_dump(const struct debug_stack_frame *backtrace, + unsigned nr_frames); + + +#ifdef __cplusplus +} +#endif + +#endif /* U_DEBUG_STACK_H_ */