qmathe@club-internet.fr
)A debug utility to record stack traces in relation to an instance.
Copyright: (C) 2010 Quentin Mathe
- Declared in:
- ETStackTraceRecorder.h
@group Debugging
Represents a stack trace built from an array of call stack symbols.
You usually don't need to instantiate stack trace objects directly, ETStackTraceRecorder does it.
Returns a new stack trace initialized with the call stack symbols of the current thread.
- Declared in:
- ETStackTraceRecorder.h
@group Debugging
A stack trace recorder allows to snapshot the call stack symbols and inspect these snapshots later on.
You invoke -recordForObject: to snapshot the current call stack symbols and -recordedStackTracesForObject: to get all the call stack traces recorded until now.
A stack trace recorder is very handy to debug memory
management issues. e.g. You can easily discover
where an over-released object was allocated in a vein
similar to malloc_history on Mac OS X.
Take note that
+enableAllocationRecordingForClass:
is only available on GNUstep and the example detailed below doesn't apply to Mac OS X where you must use malloc_history instead.
To get meaningfull backtrace on GNUstep, you must install the GNU bin utils (e.g. binutils-dev package on Ubuntu) and configure GNUstep Base with --enable-bfd.
Be aware that the resulting gnustep-base library will be GPL-licensed and transively all the code that links it will become GPL-licensed too.
@section Use Case Example
For a retain/release crash, note the instance class that got double-released, then add in main() or equivalent:
[[ETStackTraceRecorder sharedInstance] enableAllocationRecordingForClass: [MyClass class]];
To prevent the instance to be deallocated, set
NSZombieEnabled to YES
(e.g.
export NSZombieEnabled YES
in
the shell). Finally compile and run the program in GDB
and at crash time, type on the GDB prompt:
po [[ETStackTraceRecorder sharedInstance] recordedStackTracesForObject: instance] firstObject]
Where instance is the instance address or a
variable pointing on the instance. Then GDB prints
the stack trace which points back to the code that
allocated the instance.
You can also put a
breakpoint on -[NSZombie forwardInvocation:],
but take note that NSZombie doesn't respond to
-recordedStackTraces
(at least on GNUstep).
@section Thread Safety
ETStackTraceRecorder is thread-safe (not fully yet), multiple threads can invoke -recordForObject: .
@taskunit Initialization
Returns the shared stack trace recorder.
Returns the shared stack trace recorder.
Disables the recording of the stack trace every time +allocWithZone: is called on the given class.
Doesn't apply subclasses. See -enableAllocationRecordingForClass: for more details.
@taskunit Object Allocation Recording
Enables the recording of the stack trace every time +allocWithZone: is called on the given class.
Doesn't apply to subclasses. e.g. Using NSObject
as argument won't trigger the allocation recording for
every instances.
You must pass concrete
subclasses to record class cluster
allocations. e.g. GSDictionary for
NSDictionary.
For now, using this method on other recorders than the one returned by +sharedInstance is not supported.
To detect object allocations, the receiver sets up alloc/dealloc callbacks with GSSetDebugAllocationFunctions() . You cannot use these hooks in your code and at the same time record the allocation with ETStackTraceRecorder.
Enables the recording of the stack trace every time +allocWithZone: is called on the given class.
Doesn't apply to subclasses. e.g. Using NSObject
as argument won't trigger the allocation recording for
every instances.
You must pass concrete
subclasses to record class cluster
allocations. e.g. GSDictionary for
NSDictionary.
For now, using this method on other recorders than the one returned by +sharedInstance is not supported.
To detect object allocations, the receiver sets up alloc/dealloc callbacks with GSSetDebugAllocationFunctions() . You cannot use these hooks in your code and at the same time record the allocation with ETStackTraceRecorder.
Initializes and returns a new stack trace recorder.
@taskunit Recording and Accessing Stack Traces
Records the call stack symbols in relation to the given object.
Records the call stack symbols in relation to the given object.
Returns an array of stack traces previous recorded with -recordForObject: for the given object.
When no stack traces have been recorded for the given object, returns an empty array.
- Declared in:
- ETStackTraceRecorder.h
@group Debugging
Some conveniency methods which makes easier to work with the shared stack trace recorder instance.
For example, in GDB you can type [self
recordStackTrace] to keep a trace of the
current call stack.
And you can print all
the stack traces recorded for the current object with
'po [[self recordedStackTraces] stringValue]'.
Records the call stack symbols with the shared stack trace recorder.
Returns an array of stack traces previously recorded with the shared stack trace recorded for the receiver.