diff options
Diffstat (limited to 'Foundation/GTMStackTrace.m')
-rw-r--r-- | Foundation/GTMStackTrace.m | 94 |
1 files changed, 2 insertions, 92 deletions
diff --git a/Foundation/GTMStackTrace.m b/Foundation/GTMStackTrace.m index 3e34ed0..4470a11 100644 --- a/Foundation/GTMStackTrace.m +++ b/Foundation/GTMStackTrace.m @@ -19,8 +19,9 @@ #include <stdlib.h> #include <dlfcn.h> #include <mach-o/nlist.h> +#include <objc/runtime.h> + #include "GTMStackTrace.h" -#include "GTMObjC2Runtime.h" struct GTMClassDescription { const char *class_name; @@ -202,73 +203,10 @@ static NSString *GTMStackTraceFromAddressDescriptors(struct GTMAddressDescriptor #pragma mark Public functions -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 -// Before 10.5, we have to do this ourselves. 10.5 adds -// +[NSThread callStackReturnAddresses]. - -// Structure representing a small portion of a stack, starting from the saved -// frame pointer, and continuing through the saved program counter. -struct GTMStackFrame { - void *saved_fp; -#if defined (__ppc__) || defined(__ppc64__) - void *padding; -#endif - void *saved_pc; -}; - -// __builtin_frame_address(0) is a gcc builtin that returns a pointer to the -// current frame pointer. We then use the frame pointer to walk the stack -// picking off program counters and other saved frame pointers. This works -// great on i386, but PPC requires a little more work because the PC (or link -// register) isn't always stored on the stack. -// -NSUInteger GTMGetStackProgramCounters(void *outPcs[], NSUInteger count) { - if (!outPcs || (count < 1)) return 0; - - struct GTMStackFrame *fp; -#if defined (__ppc__) || defined(__ppc64__) - outPcs[0] = __builtin_return_address(0); - fp = (struct GTMStackFrame *)__builtin_frame_address(1); -#elif defined (__i386__) || defined(__x86_64__) - fp = (struct GTMStackFrame *)__builtin_frame_address(0); -#else -#error architecture not supported -#endif - - NSUInteger level = 0; - while (level < count) { - if (fp == NULL) { - level--; - break; - } - outPcs[level] = fp->saved_pc; - level++; - fp = (struct GTMStackFrame *)fp->saved_fp; - } - - return level; -} -#endif // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - NSUInteger GTMGetStackAddressDescriptors(struct GTMAddressDescriptor outDescs[], NSUInteger count) { if (count < 1 || !outDescs) return 0; NSUInteger result = 0; - -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - // Before 10.5, we collect the stack ourselves. - - void **pcs = calloc(count, sizeof(void*)); - if (!pcs) return 0; - - NSUInteger newSize = GTMGetStackProgramCounters(pcs, count); - - result = GTMGetStackAddressDescriptorsForAddresses(pcs, outDescs, newSize); - free(pcs); - -#else // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - // Use +[NSThread callStackReturnAddresses] - NSArray *addresses = [NSThread callStackReturnAddresses]; NSUInteger addrCount = [addresses count]; if (addrCount) { @@ -288,7 +226,6 @@ NSUInteger GTMGetStackAddressDescriptors(struct GTMAddressDescriptor outDescs[], } free(pcs); } -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 return result; } @@ -296,27 +233,6 @@ NSUInteger GTMGetStackAddressDescriptors(struct GTMAddressDescriptor outDescs[], NSString *GTMStackTrace(void) { // If we don't have enough frames, return an empty string NSString *result = @""; - -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - // Before 10.5, we collect the stack ourselves. - - // The maximum number of stack frames that we will walk. We limit this so - // that super-duper recursive functions (or bugs) don't send us for an - // infinite loop. - struct GTMAddressDescriptor descs[100]; - size_t depth = sizeof(descs) / sizeof(struct GTMAddressDescriptor); - depth = GTMGetStackAddressDescriptors(descs, depth); - - // Start at the second item so that GTMStackTrace and it's utility calls (of - // which there is currently 1) is not included in the output. - const size_t kTracesToStrip = 2; - if (depth > kTracesToStrip) { - result = GTMStackTraceFromAddressDescriptors(&descs[kTracesToStrip], - (depth - kTracesToStrip)); - } -#else // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - // Use +[NSThread callStackReturnAddresses] - NSArray *addresses = [NSThread callStackReturnAddresses]; NSUInteger count = [addresses count]; if (count) { @@ -344,14 +260,10 @@ NSString *GTMStackTrace(void) { free(pcs); free(descs); } -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 return result; } -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 || \ - (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ - (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_2_0)) NSString *GTMStackTraceFromException(NSException *e) { NSString *trace = @""; @@ -382,5 +294,3 @@ NSString *GTMStackTraceFromException(NSException *e) { return trace; } -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - //__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_2_0 |