1 /* Interface to debugging utilities for GNUStep and OpenStep
2    Copyright (C) 1997,1999 Free Software Foundation, Inc.
3 
4    Written by:  Richard Frith-Macdonald <richard@brainstorm.co.uk>
5    Date: August 1997
6    Extended by: Nicola Pero <n.pero@mi.flashnet.it>
7    Date: December 2000, April 2001
8 
9    This file is part of the GNUstep Base Library.
10 
11    This library is free software; you can redistribute it and/or
12    modify it under the terms of the GNU Lesser General Public
13    License as published by the Free Software Foundation; either
14    version 2 of the License, or (at your option) any later version.
15 
16    This library is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    Lesser General Public License for more details.
20 
21    You should have received a copy of the GNU Lesser General Public
22    License along with this library; if not, write to the Free
23    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24    Boston, MA 02110 USA.
25    */
26 
27 #ifndef __NSDebug_h_GNUSTEP_BASE_INCLUDE
28 #define __NSDebug_h_GNUSTEP_BASE_INCLUDE
29 #import	<GNUstepBase/GSVersionMacros.h>
30 
31 #include <errno.h>
32 
33 #if	!NO_GNUSTEP
34 #  if	defined(GNUSTEP_BASE_INTERNAL)
35 #    import	"Foundation/NSObject.h"
36 #    import	"GNUstepBase/NSDebug+GNUstepBase.h"
37 #  else
38 #    import	<Foundation/NSObject.h>
39 #    import	<GNUstepBase/NSDebug+GNUstepBase.h>
40 #  endif
41 #endif
42 
43 #if	defined(__cplusplus)
44 extern "C" {
45 #endif
46 
47 /*
48  *	Functions for debugging object allocation/deallocation
49  *
50  *	Internal functions:
51  *	GSDebugAllocationAdd()		is used by NSAllocateObject()
52  *	GSDebugAllocationRemove()	is used by NSDeallocateObject()
53  *
54  *	Public functions:
55  *	GSDebugAllocationActive()
56  *	GSDebugAllocationBytes()
57  *	GSDebugAllocationCount()
58  *      GSDebugAllocationTotal()
59  *      GSDebugAllocationPeak()
60  *      GSDebugAllocationClassList()
61  *	GSDebugAllocationList()
62  *	GSDebugAllocationListAll()
63  *
64  *      GSSetDebugAllocationFunctions()
65  *
66  * When the previous functions have allowed you to find a memory leak,
67  * and you know that you are leaking objects of class XXX, but you are
68  * hopeless about actually finding out where the leak is, the
69  * following functions could come handy as they allow you to find
70  * exactly *what* objects you are leaking (warning! these functions
71  * could slow down your system appreciably - use them only temporarily
72  * and only in debugging systems):
73  *
74  *  GSDebugAllocationRecordObjects()
75  *  GSDebugAllocationListRecordedObjects()
76  *  GSDebugAllocationTagRecordedObject()
77  */
78 #ifndef	NDEBUG
79 
80 /**
81  * Used internally by NSAllocateObject() ... you probably don't need this.
82  */
83 GS_EXPORT void		GSDebugAllocationAdd(Class c, id o);
84 
85 /**
86  * Used internally by NSDeallocateObject() ... you probably don't need this.
87  */
88 GS_EXPORT void		GSDebugAllocationRemove(Class c, id o);
89 
90 /**
91  * This function activates or deactivates object allocation debugging.<br />
92  * Returns the previous state.<br />
93  * You should call this function to activate
94  * allocation debugging before using any of the other allocation
95  * debugging functions such as GSDebugAllocationList() or
96  * GSDebugAllocationTotal().<br />
97  * Object allocation debugging
98  * should not affect performance too much, and is very useful
99  * as it allows you to monitor how many objects of each class
100  * your application has allocated.
101  */
102 GS_EXPORT BOOL		GSDebugAllocationActive(BOOL active);
103 
104 /**
105  * This function activates or deactivates byte counting for allocation.<br />
106  * Returns the previous state.<br />
107  * You may call this function to activate additional checks to see how
108  * much memory is allocated to hold each object allocated.  When this is
109  * enabled, listing the allocated objects will also list the number of bytes
110  * of heap memory allocated to hold the objects.<br />
111  */
112 GS_EXPORT BOOL		GSDebugAllocationBytes(BOOL active);
113 
114 /**
115  * <p>
116  *   Returns the number
117  *   of instances of the specified class which are currently
118  *   allocated.  This number is very important to detect memory
119  *   leaks.  If you notice that this number is constantly
120  *   increasing without apparent reason, it is very likely a
121  *   memory leak - you need to check that you are correctly
122  *   releasing objects of this class, otherwise when your
123  *   application runs for a long time, it will eventually
124  *   allocate so many objects as to eat up all your system's
125  *   memory ...
126  * </p>
127  * <p>
128  *   This function, like the ones below, returns the number of
129  *   objects allocated/released from the time when
130  *   GSDebugAllocationActive() was first called.  A negative
131  *   number means that in total, there are less objects of this
132  *   class allocated now than there were when you called
133  *   GSDebugAllocationActive(); a positive one means there are
134  *   more.
135  * </p>
136  */
137 GS_EXPORT int		GSDebugAllocationCount(Class c);
138 
139 /**
140  * Returns the peak
141  * number of instances of the specified class which have been
142  * concurrently allocated.  If this number is very high, it
143  * means at some point in time you had a situation with a
144  * huge number of objects of this class allocated - this is
145  * an indicator that probably at some point in time your
146  * application was using a lot of memory - so you might want
147  * to investigate whether you can prevent this problem by
148  * inserting autorelease pools in your application's
149  * processing loops.
150  */
151 GS_EXPORT int		GSDebugAllocationPeak(Class c);
152 
153 /**
154  * Returns the total
155  * number of instances of the specified class c which have been
156  * allocated - basically the number of times you have
157  * allocated an object of this class.  If this number is very
158  * high, it means you are creating a lot of objects of this
159  * class; even if you are releasing them correctly, you must
160  * not forget that allocating and deallocating objects is
161  * usually one of the slowest things you can do, so you might
162  * want to consider whether you can reduce the number of
163  * allocations and deallocations that you are doing - for
164  * example, by recycling objects of this class, uniquing
165  * them, and/or using some sort of flyweight pattern.  It
166  * might also be possible that you are unnecessarily creating
167  * too many objects of this class.  Well - of course some times
168  * there is nothing you can do about it.
169  */
170 GS_EXPORT int		GSDebugAllocationTotal(Class c);
171 
172 /**
173  * This function returns a NULL
174  * terminated array listing all the classes for which
175  * statistical information has been collected.  Usually, you
176  * call this function, and then loop on all the classes returned,
177  * and for each one you get current, peak and total count by
178  * using GSDebugAllocationCount(), GSDebugAllocationPeak() and
179  * GSDebugAllocationTotal().
180  */
181 GS_EXPORT Class*        GSDebugAllocationClassList(void);
182 
183 /**
184  * This function returns a newline separated list of the classes
185  * which have instances allocated, and the instance counts.
186  * If the 'changeFlag' argument is YES then the list gives the number
187  * of instances allocated/deallocated since the function was
188  * last called with that setting.  This function only returns the
189  * current count of instances (not the peak or total count), but its
190  * output is ready to be displayed or logged.
191  */
192 GS_EXPORT const char*	GSDebugAllocationList(BOOL changeFlag);
193 
194 /**
195  * This function returns a newline
196  * separated list of the classes which have had instances
197  * allocated at any point, and the total count of the number
198  * of instances allocated for each class.  The difference with
199  * GSDebugAllocationList() is that this function returns also
200  * classes which have no objects allocated at the moment, but
201  * which had in the past.
202  */
203 GS_EXPORT const char*	GSDebugAllocationListAll(void);
204 
205 /**
206  * DEPRECATED ... use GSDebugAllocationRecordObjects instead.
207  */
208 GS_EXPORT void     GSDebugAllocationActiveRecordingObjects(Class c);
209 
210 /**
211  * This function activates (or deactivates) tracking all allocated
212  * instances of the specified class c.<br />
213  * Turning on tracking implicitly turns on memory debug (counts)
214  * for all classes (GSAllocationActive()).<br />
215  * Deactivation of tracking releases all currently tracked instances
216  * of the class (but deactivation of general counting does not).<br />
217  * The previous tracking state as reported as the return value of
218  * this function.<br />
219  * This tracking can slow your application down, so you should use it
220  * only when you are into serious debugging.
221  * Usually, you will monitor your application by using the functions
222  * GSDebugAllocationList() and similar, which do not slow things down
223  * much and return * the number of allocated instances; when
224  * (if) by studying the reports generated by these functions
225  * you have found a leak of objects of a certain class, and
226  * if you can't figure out how to fix it by looking at the
227  * code, you can use this function to start tracking
228  * allocated instances of that class, and the following one
229  * can sometime allow you to list the leaked objects directly.
230  */
231 GS_EXPORT BOOL  GSDebugAllocationRecordObjects(Class c, BOOL newState);
232 
233 /**
234  * This function returns an array
235  * containing all the allocated objects of a certain class
236  * which have been recorded ... to start the recording, you need
237  * to invoke GSDebugAllocationRecordObjects().
238  * Presumably, you will immediately call [NSObject-description] on them
239  * to find out the objects you are leaking.  The objects are
240  * returned in an autoreleased array, so until the array is deallocated,
241  * the objects are not released.
242  */
243 GS_EXPORT NSArray *GSDebugAllocationListRecordedObjects(Class c);
244 
245 /**
246  * This function associates the supplied tag with a recorded
247  * object and returns the tag which was previously associated
248  * with it (if any).<br />
249  * If the object was not recorded, the method returns nil<br />
250  * The tag is retained while it is associated with the object.<br />
251  * If the tagged object is deallocated, the tag is released
252  * (so you can track the lifetime of the object by having the tag
253  * perform some operation when it is released).<br />
254  * See also the NSDebugFRLog() and NSDebugMRLog() macros.
255  */
256 GS_EXPORT id GSDebugAllocationTagRecordedObject(id object, id tag);
257 
258 /**
259  * This functions allows to set own function callbacks for debugging allocation
260  * of objects. Useful if you intend to write your own object allocation code.
261  */
262 GS_EXPORT void  GSSetDebugAllocationFunctions(
263   void (*newAddObjectFunc)(Class c, id o),
264   void (*newRemoveObjectFunc)(Class c, id o));
265 
266 #endif
267 
268 /**
269  * Enable/disable zombies.
270  * <p>When an object is deallocated, its isa pointer is normally modified
271  * to the hexadecimal value 0xdeadface, so that any attempt to send a
272  * message to the deallocated object will cause a crash, and examination
273  * of the object within the debugger will show the 0xdeadface value ...
274  * making it obvious why the program crashed.
275  * </p>
276  * <p>Turning on zombies changes this behavior so that the isa pointer
277  * is modified to be that of the NSZombie class.  When messages are
278  * sent to the object, instead of crashing, NSZombie will use NSLog() to
279  * produce an error message.  By default the memory used by the object
280  * will not really be freed, so error messages will continue to
281  * be generated whenever a message is sent to the object, and the object
282  * instance variables will remain available for examination by the debugger.
283  * </p>
284  * The default value of this boolean is NO, but this can be controlled
285  * by the NSZombieEnabled environment variable.
286  */
287 GS_EXPORT BOOL NSZombieEnabled;
288 
289 /**
290  * Enable/disable object deallocation.
291  * <p>If zombies are enabled, objects are by default <em>not</em>
292  * deallocated, and memory leaks.  The NSDeallocateZombies variable
293  * lets you say that the the memory used by zombies should be freed.
294  * </p>
295  * <p>Doing this makes the behavior of zombies similar to that when zombies
296  * are not enabled ... the memory occupied by the zombie may be re-used for
297  * other purposes, at which time the isa pointer may be overwritten and the
298  * zombie behavior will cease.
299  * </p>
300  * The default value of this boolean is NO, but this can be controlled
301  * by the NSDeallocateZombies environment variable.
302  */
303 GS_EXPORT BOOL NSDeallocateZombies;
304 
305 
306 
307 /**
308  *  Retrieve stack information.  Use caution: uses built-in gcc functions
309  *  and currently only works up to 100 frames.
310  */
311 GS_EXPORT void *NSFrameAddress(NSUInteger offset);
312 
313 /**
314  *  Retrieve stack information.  Use caution: uses built-in gcc functions
315  *  and currently only works up to 100 frames.
316  */
317 GS_EXPORT void *NSReturnAddress(NSUInteger offset);
318 
319 /**
320  *  Retrieve stack information.  Use caution: uses built-in gcc functions
321  *  and currently only works up to 100 frames.
322  */
323 GS_EXPORT NSUInteger NSCountFrames(void);
324 
325 #if	defined(__cplusplus)
326 }
327 #endif
328 
329 #endif
330