~ubuntu-branches/ubuntu/karmic/gnustep-base/karmic

« back to all changes in this revision

Viewing changes to Headers/Foundation/NSDebug.h

  • Committer: Bazaar Package Importer
  • Author(s): Eric Heintzmann
  • Date: 2005-04-17 00:14:38 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050417001438-enf0y07c9tku85z1
Tags: 1.10.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 Library 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
   Library General Public License for more details.
 
20
 
 
21
   You should have received a copy of the GNU Library General Public
 
22
   License along with this library; if not, write to the Free
 
23
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
 
24
   */
 
25
 
 
26
#ifndef __NSDebug_h_GNUSTEP_BASE_INCLUDE
 
27
#define __NSDebug_h_GNUSTEP_BASE_INCLUDE
 
28
 
 
29
#include <errno.h>
 
30
#include <Foundation/NSObject.h>
 
31
 
 
32
 
 
33
/*
 
34
 *      Functions for debugging object allocation/deallocation
 
35
 *
 
36
 *      Internal functions:
 
37
 *      GSDebugAllocationAdd()          is used by NSAllocateObject()
 
38
 *      GSDebugAllocationRemove()       is used by NSDeallocateObject()
 
39
 *
 
40
 *      Public functions:
 
41
 *      GSDebugAllocationActive()       
 
42
 *      GSDebugAllocationCount()        
 
43
 *      GSDebugAllocationTotal()
 
44
 *      GSDebugAllocationPeak()
 
45
 *      GSDebugAllocationClassList()
 
46
 *      GSDebugAllocationList()
 
47
 *      GSDebugAllocationListAll()
 
48
 * GSSetDebugAllocationFunctions()
 
49
 *
 
50
 * When the previous functions have allowed you to find a memory leak,
 
51
 * and you know that you are leaking objects of class XXX, but you are
 
52
 * hopeless about actually finding out where the leak is, the
 
53
 * following functions could come handy as they allow you to find
 
54
 * exactly *what* objects you are leaking (warning! these functions
 
55
 * could slow down your system appreciably - use them only temporarily
 
56
 * and only in debugging systems):
 
57
 *
 
58
 *  GSDebugAllocationActiveRecordingObjects()
 
59
 *  GSDebugAllocationListRecordedObjects() 
 
60
 */
 
61
#ifndef NDEBUG
 
62
 
 
63
/**
 
64
 * Used internally by NSAllocateObject() ... you probably don't need this.
 
65
 */
 
66
GS_EXPORT void          GSDebugAllocationAdd(Class c, id o);
 
67
 
 
68
/**
 
69
 * Used internally by NSDeallocateObject() ... you probably don't need this.
 
70
 */
 
71
GS_EXPORT void          GSDebugAllocationRemove(Class c, id o);
 
72
 
 
73
/**
 
74
 * Activates or deactivates object allocation debugging.
 
75
 * Returns previous state.
 
76
 */
 
77
GS_EXPORT BOOL          GSDebugAllocationActive(BOOL active);
 
78
 
 
79
/**
 
80
 * Returns the number of instances of the specified class
 
81
 * which are currently allocated.
 
82
 */
 
83
GS_EXPORT int           GSDebugAllocationCount(Class c);
 
84
 
 
85
/**
 
86
 * Returns the peak number of instances of the specified class
 
87
 * which have been concurrently allocated.
 
88
 */
 
89
GS_EXPORT int           GSDebugAllocationPeak(Class c);
 
90
 
 
91
/**
 
92
 * Returns the total number of instances of the specified class
 
93
 * which have been allocated.
 
94
 */
 
95
GS_EXPORT int           GSDebugAllocationTotal(Class c);
 
96
 
 
97
/**
 
98
 * Returns a NULL terminated array listing all the classes 
 
99
 * for which statistical information has been collected.
 
100
 */
 
101
GS_EXPORT Class*        GSDebugAllocationClassList(void);
 
102
 
 
103
/**
 
104
 * Returns a newline separated list of the classes which
 
105
 * have instances allocated, and the instance counts.
 
106
 * If 'changeFlag' is YES then the list gives the number
 
107
 * of instances allocated/deallocated since the function
 
108
 * was last called.
 
109
 */
 
110
GS_EXPORT const char*   GSDebugAllocationList(BOOL changeFlag);
 
111
 
 
112
/**
 
113
 * Returns a newline separated list of the classes which
 
114
 * have had instances allocated at any point, and the total
 
115
 * count of the number of instances allocated for each class.
 
116
 */
 
117
GS_EXPORT const char*   GSDebugAllocationListAll(void);
 
118
 
 
119
/**
 
120
 * Starts recording all allocated objects of a certain class.<br />
 
121
 * Use with extreme care ... this could slow down your application
 
122
 * enormously.
 
123
 */
 
124
GS_EXPORT void     GSDebugAllocationActiveRecordingObjects(Class c);
 
125
 
 
126
/**
 
127
 * Returns an array containing all the allocated objects
 
128
 * of a certain class which have been recorded.
 
129
 * Presumably, you will immediately call [NSObject-description] on
 
130
 * them to find out the objects you are leaking.
 
131
 * Warning - the objects are put in an array, so until
 
132
 * the array is autoreleased, the objects are not released.
 
133
 */
 
134
GS_EXPORT NSArray *GSDebugAllocationListRecordedObjects(Class c);
 
135
 
 
136
/**
 
137
 * This function associates the supplied tag with a recorded
 
138
 * object and returns the tag which was previously associated
 
139
 * with it (if any).<br />
 
140
 * If the object was not recorded, the method returns nil<br />
 
141
 * The tag is retained while it is associated with the object.<br />
 
142
 * See also the NSDebugFRLog() and NSDebugMRLog() macros.
 
143
 */
 
144
GS_EXPORT id GSDebugAllocationTagRecordedObject(id object, id tag);
 
145
 
 
146
/**
 
147
 * Used to produce a format string for logging a message with function
 
148
 * location details.
 
149
 */
 
150
GS_EXPORT NSString*     GSDebugFunctionMsg(const char *func, const char *file,
 
151
                                int line, NSString *fmt);
 
152
/**
 
153
 * Used to produce a format string for logging a message with method
 
154
 * location details.
 
155
 */
 
156
GS_EXPORT NSString*     GSDebugMethodMsg(id obj, SEL sel, const char *file,
 
157
                                int line, NSString *fmt);
 
158
 
 
159
/**
 
160
 * This functions allows to set own function backcalls for debugging allocation
 
161
 * of objects. Useful if you intend to write your own objectalloc.
 
162
 */
 
163
GS_EXPORT void  GSSetDebugAllocationFunctions(void (*newAddObjectFunc)(Class c, id o),
 
164
                                              void (*newRemoveObjectFunc)(Class c, id o));
 
165
 
 
166
#endif
 
167
 
 
168
/**
 
169
 * Enable/disable zombies.
 
170
 * <p>When an object is deallocated, its isa pointer is normally modified
 
171
 * to the hexadecimal value 0xdeadface, so that any attempt to send a
 
172
 * message to the deallocated object will cause a crash, and examination
 
173
 * of the object within the debugger will show the 0xdeadface value ...
 
174
 * making it obvious why the program crashed.
 
175
 * </p>
 
176
 * <p>Turning on zombies changes this behavior so that the isa pointer
 
177
 * is modified to be that of the NSZombie class.  When messages are
 
178
 * sent to the object, intead of crashing, NSZombie will use NSLog() to
 
179
 * produce an error message.  By default the memory used by the object
 
180
 * will not really be freed, so error messages will continue to
 
181
 * be generated whenever a message is sent to the object, and the object
 
182
 * instance variables will remain available for examination by the debugger.
 
183
 * </p>
 
184
 * The default value of this boolean is NO, but this can be controlled
 
185
 * by the NSZombieEnabled environment variable.
 
186
 */
 
187
GS_EXPORT BOOL NSZombieEnabled;
 
188
 
 
189
/**
 
190
 * Enable/disable object deallocation.
 
191
 * <p>If zombies are enabled, objects are by default <em>not</em>
 
192
 * deallocated, and memory leaks.  The NSDeallocateZombies variable
 
193
 * lets you say that the the memory used by zombies should be freed.
 
194
 * </p>
 
195
 * <p>Doing this makes the behavior of zombies similar to that when zombies
 
196
 * are not enabled ... the memory occupied by the zombie may be re-used for
 
197
 * other purposes, at which time the isa pointer may be overwritten and the
 
198
 * zombie behavior will cease.
 
199
 * </p>
 
200
 * The default value of this boolean is NO, but this can be controlled
 
201
 * by the NSDeallocateZombies environment variable.
 
202
 */
 
203
GS_EXPORT BOOL NSDeallocateZombies;
 
204
 
 
205
 
 
206
 
 
207
#ifdef GSDIAGNOSE
 
208
#include        <Foundation/NSObjCRuntime.h>
 
209
#include        <Foundation/NSProcessInfo.h>
 
210
 
 
211
/**
 
212
   <p>NSDebugLLog() is the basic debug logging macro used to display
 
213
   log messages using NSLog(), if debug logging was enabled at compile
 
214
   time and the appropriate logging level was set at runtime.
 
215
   </p>
 
216
   <p>Debug logging which can be enabled/disabled by defining GSDIAGNOSE
 
217
   when compiling and also setting values in the mutable set which
 
218
   is set up by NSProcessInfo. GSDIAGNOSE is defined automatically
 
219
   unless diagnose=no is specified in the make arguments.
 
220
   </p>
 
221
   <p>NSProcess initialises a set of strings that are the names of active
 
222
   debug levels using the '--GNU-Debug=...' command line argument.
 
223
   Each command-line argument of that form is removed from
 
224
   <code>NSProcessInfo</code>'s list of arguments and the variable part
 
225
   (...) is added to the set.
 
226
   This means that as far as the program proper is concerned, it is
 
227
   running with the same arguments as if debugging had not been enabled.
 
228
   </p>
 
229
   <p>For instance, to debug the NSBundle class, run your program with 
 
230
    '--GNU-Debug=NSBundle'
 
231
   You can of course supply multiple '--GNU-Debug=...' arguments to
 
232
   output debug information on more than one thing.
 
233
   </p>
 
234
   <p>NSUserDefaults also adds debug levels from the array given by the
 
235
   GNU-Debug key ... but these values will not take effect until the
 
236
   +standardUserDefaults method is called ... so they are useless for
 
237
   debugging NSUserDefaults itself or for debugging any code executed
 
238
   before the defaults system is used.
 
239
   </p>
 
240
   <p>To embed debug logging in your code you use the NSDebugLLog() or
 
241
   NSDebugLog() macro.  NSDebugLog() is just NSDebugLLog() with the debug
 
242
   level set to 'dflt'.  So, to activate debug statements that use
 
243
   NSDebugLog(), you supply the '--GNU-Debug=dflt' argument to your program.
 
244
   </p>
 
245
   <p>You can also change the active debug levels under your programs control -
 
246
   NSProcessInfo has a [-debugSet] method that returns the mutable set that
 
247
   contains the active debug levels - your program can modify this set.
 
248
   </p>
 
249
   <p>Two debug levels have a special effect - 'dflt' is the level used for
 
250
   debug logs statements where no debug level is specified, and 'NoWarn'
 
251
   is used to *disable* warning messages.
 
252
   </p>
 
253
   <p>As a convenience, there are four more logging macros you can use -
 
254
   NSDebugFLog(), NSDebugFLLog(), NSDebugMLog() and NSDebugMLLog().
 
255
   These are the same as the other macros, but are specifically for use in
 
256
   either functions or methods and prepend information about the file, line
 
257
   and either function or class/method in which the message was generated.
 
258
   </p>
 
259
 */
 
260
#define NSDebugLLog(level, format, args...) \
 
261
  do { if (GSDebugSet(level) == YES) \
 
262
    NSLog(format , ## args); } while (0)
 
263
 
 
264
/**
 
265
 * This macro is a shorthand for NSDebugLLog() using then default debug
 
266
 * level ... 'dflt'
 
267
 */
 
268
#define NSDebugLog(format, args...) \
 
269
  do { if (GSDebugSet(@"dflt") == YES) \
 
270
    NSLog(format , ## args); } while (0)
 
271
 
 
272
/**
 
273
 * This macro is like NSDebugLLog() but includes the name and location
 
274
 * of the function in which the macro is used as part of the log output.
 
275
 */
 
276
#define NSDebugFLLog(level, format, args...) \
 
277
  do { if (GSDebugSet(level) == YES) { \
 
278
    NSString *fmt = GSDebugFunctionMsg( \
 
279
        __PRETTY_FUNCTION__, __FILE__, __LINE__, format); \
 
280
    NSLog(fmt , ## args); }} while (0)
 
281
 
 
282
/**
 
283
 * This macro is a shorthand for NSDebugFLLog() using then default debug
 
284
 * level ... 'dflt'
 
285
 */
 
286
#define NSDebugFLog(format, args...) \
 
287
  do { if (GSDebugSet(@"dflt") == YES) { \
 
288
    NSString *fmt = GSDebugFunctionMsg( \
 
289
        __PRETTY_FUNCTION__, __FILE__, __LINE__, format); \
 
290
    NSLog(fmt , ## args); }} while (0)
 
291
 
 
292
/**
 
293
 * This macro is like NSDebugLLog() but includes the name and location
 
294
 * of the <em>method</em> in which the macro is used as part of the log output.
 
295
 */
 
296
#define NSDebugMLLog(level, format, args...) \
 
297
  do { if (GSDebugSet(level) == YES) { \
 
298
    NSString *fmt = GSDebugMethodMsg( \
 
299
        self, _cmd, __FILE__, __LINE__, format); \
 
300
    NSLog(fmt , ## args); }} while (0)
 
301
 
 
302
/**
 
303
 * This macro is a shorthand for NSDebugMLLog() using then default debug
 
304
 * level ... 'dflt'
 
305
 */
 
306
#define NSDebugMLog(format, args...) \
 
307
  do { if (GSDebugSet(@"dflt") == YES) { \
 
308
    NSString *fmt = GSDebugMethodMsg( \
 
309
        self, _cmd, __FILE__, __LINE__, format); \
 
310
    NSLog(fmt , ## args); }} while (0)
 
311
 
 
312
/**
 
313
 * This macro saves the name and location of the function in
 
314
 * which the macro is used, along with a short string msg as
 
315
 * the tag associated with a recorded object.
 
316
 */
 
317
#define NSDebugFRLog(object, msg) \
 
318
  do { \
 
319
    NSString *tag = GSDebugFunctionMsg( \
 
320
        __PRETTY_FUNCTION__, __FILE__, __LINE__, msg); \
 
321
    GSDebugAllocationTagRecordedObject(object, tag); } while (0)
 
322
 
 
323
/**
 
324
 * This macro saves the name and location of the method in
 
325
 * which the macro is used, along with a short string msg as
 
326
 * the tag associated with a recorded object.
 
327
 */
 
328
#define NSDebugMRLog(object, msg) \
 
329
  do { \
 
330
    NSString *tag = GSDebugMethodMsg( \
 
331
        self, _cmd, __FILE__, __LINE__, msg); \
 
332
    GSDebugAllocationTagRecordedObject(object, tag); } while (0)
 
333
 
 
334
#else
 
335
#define NSDebugLLog(level, format, args...)
 
336
#define NSDebugLog(format, args...)
 
337
#define NSDebugFLLog(level, format, args...)
 
338
#define NSDebugFLog(format, args...)
 
339
#define NSDebugMLLog(level, format, args...)
 
340
#define NSDebugMLog(format, args...)
 
341
#define NSDebugFRLog(object, msg)
 
342
#define NSDebugMRLog(object, msg)
 
343
#endif
 
344
 
 
345
/**
 
346
 * Macro to log a message only the first time it is encountered.<br />
 
347
 * Not entirely thread safe ... but that's not really important,
 
348
 * it just means that it's possible for the message to be logged
 
349
 * more than once if two threads call it simultaneously when it
 
350
 * has not already been called.<br />
 
351
 * Use this from inside a function.  Pass an NSString as a format,
 
352
 * followed by zero or more arguments for the format string.
 
353
 * Example: GSOnceMLog(@"This function is deprecated, use another");
 
354
 */
 
355
#define GSOnceFLog(format, args...) \
 
356
  do { static BOOL beenHere = NO; if (beenHere == NO) {\
 
357
    NSString *fmt = GSDebugFunctionMsg( \
 
358
        __PRETTY_FUNCTION__, __FILE__, __LINE__, format); \
 
359
    beenHere = YES; \
 
360
    NSLog(fmt , ## args); }} while (0)
 
361
/**
 
362
 * Macro to log a message only the first time it is encountered.<br />
 
363
 * Not entirely thread safe ... but that's not really important,
 
364
 * it just means that it's possible for the message to be logged
 
365
 * more than once if two threads call it simultaneously when it
 
366
 * has not already been called.<br />
 
367
 * Use this from inside a method. Pass an NSString as a format
 
368
 * followed by zero or more arguments for the format string.<br />
 
369
 * Example: GSOnceMLog(@"This method is deprecated, use another");
 
370
 */
 
371
#define GSOnceMLog(format, args...) \
 
372
  do { static BOOL beenHere = NO; if (beenHere == NO) {\
 
373
    NSString *fmt = GSDebugMethodMsg( \
 
374
        self, _cmd, __FILE__, __LINE__, format); \
 
375
    beenHere = YES; \
 
376
    NSLog(fmt , ## args); }} while (0)
 
377
 
 
378
 
 
379
 
 
380
#ifdef GSWARN
 
381
#include        <Foundation/NSObjCRuntime.h>
 
382
 
 
383
/**
 
384
   <p>NSWarnLog() is the basic debug logging macro used to display
 
385
   warning messages using NSLog(), if warn logging was not disabled at compile
 
386
   time and the disabling logging level was not set at runtime.
 
387
   </p>
 
388
   <p>Warning messages which can be enabled/disabled by defining GSWARN
 
389
   when compiling.
 
390
   </p>
 
391
   <p>You can also disable these messages at runtime by supplying a
 
392
   '--GNU-Debug=NoWarn' argument to the program, or by adding 'NoWarn'
 
393
   to the user default array named 'GNU-Debug'.
 
394
   </p>
 
395
   <p>These logging macros are intended to be used when the software detects
 
396
   something that it not necessarily fatal or illegal, but looks like it
 
397
   might be a programming error.  eg. attempting to remove 'nil' from an
 
398
   NSArray, which the Spec/documentation does not prohibit, but which a
 
399
   well written program should not be attempting (since an NSArray object
 
400
   cannot contain a 'nil').
 
401
   </p>
 
402
   <p>NB. The 'warn=yes' option is understood by the GNUstep make package
 
403
   to mean that GSWARN should be defined, and the 'warn=no' means that
 
404
   GSWARN should be undefined.  Default is to define it.
 
405
   </p>
 
406
   <p>To embed debug logging in your code you use the NSWarnLog() macro.
 
407
   </p>
 
408
   <p>As a convenience, there are two more logging macros you can use -
 
409
   NSWarnFLog(), and NSWarnMLog().
 
410
   These are specifically for use in either functions or methods and
 
411
   prepend information about the file, line and either function or
 
412
   class/method in which the message was generated.
 
413
   </p>
 
414
 */
 
415
 
 
416
#define NSWarnLog(format, args...) \
 
417
  do { if (GSDebugSet(@"NoWarn") == NO) { \
 
418
    NSLog(format , ## args); }} while (0)
 
419
 
 
420
/**
 
421
 * This macro is like NSWarnLog() but includes the name and location of the
 
422
 * <em>function</em> in which the macro is used as part of the log output.
 
423
 */
 
424
#define NSWarnFLog(format, args...) \
 
425
  do { if (GSDebugSet(@"NoWarn") == NO) { \
 
426
    NSString *fmt = GSDebugFunctionMsg( \
 
427
        __PRETTY_FUNCTION__, __FILE__, __LINE__, format); \
 
428
    NSLog(fmt , ## args); }} while (0)
 
429
 
 
430
/**
 
431
 * This macro is like NSWarnLog() but includes the name and location of the
 
432
 * <em>method</em> in which the macro is used as part of the log output.
 
433
 */
 
434
#define NSWarnMLog(format, args...) \
 
435
  do { if (GSDebugSet(@"NoWarn") == NO) { \
 
436
    NSString *fmt = GSDebugMethodMsg( \
 
437
        self, _cmd, __FILE__, __LINE__, format); \
 
438
    NSLog(fmt , ## args); }} while (0)
 
439
#else
 
440
#define NSWarnLog(format, args...)
 
441
#define NSWarnFLog(format, args...)
 
442
#define NSWarnMLog(format, args...)
 
443
#endif
 
444
 
 
445
/**
 
446
 *  Retrieve stack information.  Use caution: uses built-in gcc functions
 
447
 *  and currently only works up to 100 frames.
 
448
 */
 
449
GS_EXPORT void *NSFrameAddress(int offset);
 
450
 
 
451
/**
 
452
 *  Retrieve stack information.  Use caution: uses built-in gcc functions
 
453
 *  and currently only works up to 100 frames.
 
454
 */
 
455
GS_EXPORT void *NSReturnAddress(int offset);
 
456
 
 
457
/**
 
458
 *  Retrieve stack information.  Use caution: uses built-in gcc functions
 
459
 *  and currently only works up to 100 frames.
 
460
 */
 
461
GS_EXPORT unsigned NSCountFrames(void);
 
462
 
 
463
#endif