diff options
author | csilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50> | 2007-11-29 23:39:24 +0000 |
---|---|---|
committer | csilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50> | 2007-11-29 23:39:24 +0000 |
commit | 11b02f7aebd05cf39f6f93bdd48786909f99f34e (patch) | |
tree | 660c613e74cffd643ee4a7d0f0cb170057abbf7d /src/stacktrace_generic-inl.h | |
parent | 49b74b9508797f8aafe6b86e62e7efc4ec200e48 (diff) | |
download | gperftools-11b02f7aebd05cf39f6f93bdd48786909f99f34e.tar.gz |
Thu Nov 29 07:59:43 2007 Google Inc. <opensource@google.com>
* google-perftools: version 0.94 release
* PORTING: MinGW/Msys support -- runs same code as MSVC does (csilvers)
* PORTING: Add NumCPUs support for Mac OS X (csilvers)
* Work around a sscanf bug in glibc(?) (waldemar)
* Fix Windows MSVC bug triggered by thread deletion (csilvers)
* Fix bug that triggers in MSVC /O2: missing volatile (gpike)
* March-of-time support: quiet warnings/errors for gcc 4.2, OS X 10.5
* Modify pprof so it works without nm: useful for windows (csilvers)
* pprof: Support filtering for CPU profiles (cgd)
* Bugfix: have realloc report to hooks in all situations (maxim)
* Speed improvement: replace slow memcpy with std::copy (soren)
* Speed: better iterator efficiency in RecordRegionRemoval (soren)
* Speed: minor speed improvements via better bitfield alignment (gpike)
* Documentation: add documentation of binary profile output (cgd)
git-svn-id: http://gperftools.googlecode.com/svn/trunk@40 6b5cf1ce-ec42-a296-1ba9-69fdba395a50
Diffstat (limited to 'src/stacktrace_generic-inl.h')
-rw-r--r-- | src/stacktrace_generic-inl.h | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/stacktrace_generic-inl.h b/src/stacktrace_generic-inl.h index 3375ada..9392ffc 100644 --- a/src/stacktrace_generic-inl.h +++ b/src/stacktrace_generic-inl.h @@ -38,6 +38,7 @@ #include <stdlib.h> #include "google/stacktrace.h" +// If you change this function, also change GetStackFrames below. int GetStackTrace(void** result, int max_depth, int skip_count) { static const int kStackLength = 64; void * stack[kStackLength]; @@ -55,3 +56,51 @@ int GetStackTrace(void** result, int max_depth, int skip_count) { return result_count; } + +// If you change this function, also change GetStackTrace above: +// +// This GetStackFrames routine shares a lot of code with GetStackTrace +// above. This code could have been refactored into a common routine, +// and then both GetStackTrace/GetStackFrames could call that routine. +// There are two problems with that: +// +// (1) The performance of the refactored-code suffers substantially - the +// refactored needs to be able to record the stack trace when called +// from GetStackTrace, and both the stack trace and stack frame sizes, +// when called from GetStackFrames - this introduces enough new +// conditionals that GetStackTrace performance can degrade by as much +// as 50%. +// +// (2) Whether the refactored routine gets inlined into GetStackTrace and +// GetStackFrames depends on the compiler, and we can't guarantee the +// behavior either-way, even with "__attribute__ ((always_inline))" +// or "__attribute__ ((noinline))". But we need this guarantee or the +// frame counts may be off by one. +// +// Both (1) and (2) can be addressed without this code duplication, by +// clever use of template functions, and by defining GetStackTrace and +// GetStackFrames as macros that expand to these template functions. +// However, this approach comes with its own set of problems - namely, +// macros and preprocessor trouble - for example, if GetStackTrace +// and/or GetStackFrames is ever defined as a member functions in some +// class, we are in trouble. +int GetStackFrames(void** pcs, int* sizes, int max_depth, int skip_count) { + static const int kStackLength = 64; + void * stack[kStackLength]; + int size; + + size = backtrace(stack, kStackLength); + skip_count++; // we want to skip the current frame as well + int result_count = size - skip_count; + if (result_count < 0) + result_count = 0; + if (result_count > max_depth) + result_count = max_depth; + for (int i = 0; i < result_count; i++) + pcs[i] = stack[i + skip_count]; + + // No implementation for finding out the stack frame sizes yet. + memset(sizes, 0, sizeof(*sizes) * result_count); + + return result_count; +} |