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