1997-09-01 21:59:51 +00:00
|
|
|
|
/* Interface to debugging utilities for GNUStep and OpenStep
|
1999-11-07 14:50:30 +00:00
|
|
|
|
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
|
|
|
|
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
|
|
|
|
Date: August 1997
|
2001-04-19 16:10:23 +00:00
|
|
|
|
Extended by: Nicola Pero <n.pero@mi.flashnet.it>
|
|
|
|
|
Date: December 2000, April 2001
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
|
|
|
|
This file is part of the GNUstep Base Library.
|
|
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
2007-09-14 11:36:11 +00:00
|
|
|
|
modify it under the terms of the GNU Lesser General Public
|
1997-09-01 21:59:51 +00:00
|
|
|
|
License as published by the Free Software Foundation; either
|
2008-06-08 10:38:33 +00:00
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
2007-09-14 11:36:11 +00:00
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
1997-09-01 21:59:51 +00:00
|
|
|
|
License along with this library; if not, write to the Free
|
2006-10-31 07:05:46 +00:00
|
|
|
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
|
Boston, MA 02111 USA.
|
1997-09-01 21:59:51 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef __NSDebug_h_GNUSTEP_BASE_INCLUDE
|
|
|
|
|
#define __NSDebug_h_GNUSTEP_BASE_INCLUDE
|
2006-10-31 07:05:46 +00:00
|
|
|
|
#import <GNUstepBase/GSVersionMacros.h>
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
|
|
|
|
#include <errno.h>
|
2006-10-31 07:05:46 +00:00
|
|
|
|
#import <Foundation/NSObject.h>
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
1999-02-15 06:39:59 +00:00
|
|
|
|
|
2006-09-13 10:20:49 +00:00
|
|
|
|
#if defined(__cplusplus)
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
1997-09-01 21:59:51 +00:00
|
|
|
|
/*
|
|
|
|
|
* Functions for debugging object allocation/deallocation
|
|
|
|
|
*
|
|
|
|
|
* Internal functions:
|
|
|
|
|
* GSDebugAllocationAdd() is used by NSAllocateObject()
|
|
|
|
|
* GSDebugAllocationRemove() is used by NSDeallocateObject()
|
|
|
|
|
*
|
|
|
|
|
* Public functions:
|
|
|
|
|
* GSDebugAllocationActive()
|
|
|
|
|
* GSDebugAllocationCount()
|
2000-12-11 23:25:47 +00:00
|
|
|
|
* GSDebugAllocationTotal()
|
|
|
|
|
* GSDebugAllocationPeak()
|
|
|
|
|
* GSDebugAllocationClassList()
|
1997-09-01 21:59:51 +00:00
|
|
|
|
* GSDebugAllocationList()
|
1999-04-19 14:29:52 +00:00
|
|
|
|
* GSDebugAllocationListAll()
|
2003-10-08 16:26:59 +00:00
|
|
|
|
* GSSetDebugAllocationFunctions()
|
2001-04-19 16:10:23 +00:00
|
|
|
|
*
|
|
|
|
|
* When the previous functions have allowed you to find a memory leak,
|
|
|
|
|
* and you know that you are leaking objects of class XXX, but you are
|
|
|
|
|
* hopeless about actually finding out where the leak is, the
|
|
|
|
|
* following functions could come handy as they allow you to find
|
|
|
|
|
* exactly *what* objects you are leaking (warning! these functions
|
|
|
|
|
* could slow down your system appreciably - use them only temporarily
|
|
|
|
|
* and only in debugging systems):
|
|
|
|
|
*
|
2001-04-19 17:27:16 +00:00
|
|
|
|
* GSDebugAllocationActiveRecordingObjects()
|
2001-04-19 16:10:23 +00:00
|
|
|
|
* GSDebugAllocationListRecordedObjects()
|
2002-10-09 06:07:38 +00:00
|
|
|
|
*/
|
1998-08-04 10:45:43 +00:00
|
|
|
|
#ifndef NDEBUG
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Used internally by NSAllocateObject() ... you probably don't need this.
|
|
|
|
|
*/
|
2001-04-19 16:10:23 +00:00
|
|
|
|
GS_EXPORT void GSDebugAllocationAdd(Class c, id o);
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Used internally by NSDeallocateObject() ... you probably don't need this.
|
|
|
|
|
*/
|
2001-04-19 16:10:23 +00:00
|
|
|
|
GS_EXPORT void GSDebugAllocationRemove(Class c, id o);
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
2002-10-09 06:07:38 +00:00
|
|
|
|
/**
|
|
|
|
|
* Activates or deactivates object allocation debugging.
|
|
|
|
|
* Returns previous state.
|
|
|
|
|
*/
|
2000-06-14 04:03:56 +00:00
|
|
|
|
GS_EXPORT BOOL GSDebugAllocationActive(BOOL active);
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the number of instances of the specified class
|
|
|
|
|
* which are currently allocated.
|
|
|
|
|
*/
|
2000-06-14 04:03:56 +00:00
|
|
|
|
GS_EXPORT int GSDebugAllocationCount(Class c);
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the peak number of instances of the specified class
|
|
|
|
|
* which have been concurrently allocated.
|
|
|
|
|
*/
|
2000-12-11 23:25:47 +00:00
|
|
|
|
GS_EXPORT int GSDebugAllocationPeak(Class c);
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the total number of instances of the specified class
|
|
|
|
|
* which have been allocated.
|
|
|
|
|
*/
|
2000-12-11 23:25:47 +00:00
|
|
|
|
GS_EXPORT int GSDebugAllocationTotal(Class c);
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a NULL terminated array listing all the classes
|
|
|
|
|
* for which statistical information has been collected.
|
|
|
|
|
*/
|
2002-11-09 06:45:31 +00:00
|
|
|
|
GS_EXPORT Class* GSDebugAllocationClassList(void);
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a newline separated list of the classes which
|
|
|
|
|
* have instances allocated, and the instance counts.
|
|
|
|
|
* If 'changeFlag' is YES then the list gives the number
|
|
|
|
|
* of instances allocated/deallocated since the function
|
|
|
|
|
* was last called.
|
|
|
|
|
*/
|
2000-06-14 04:03:56 +00:00
|
|
|
|
GS_EXPORT const char* GSDebugAllocationList(BOOL changeFlag);
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a newline separated list of the classes which
|
|
|
|
|
* have had instances allocated at any point, and the total
|
|
|
|
|
* count of the number of instances allocated for each class.
|
|
|
|
|
*/
|
2002-11-09 06:45:31 +00:00
|
|
|
|
GS_EXPORT const char* GSDebugAllocationListAll(void);
|
1999-03-11 11:07:21 +00:00
|
|
|
|
|
2002-10-09 06:07:38 +00:00
|
|
|
|
/**
|
|
|
|
|
* Starts recording all allocated objects of a certain class.<br />
|
2002-10-24 09:21:05 +00:00
|
|
|
|
* Use with extreme care ... this could slow down your application
|
2002-10-09 06:07:38 +00:00
|
|
|
|
* enormously.
|
|
|
|
|
*/
|
2001-04-19 16:10:23 +00:00
|
|
|
|
GS_EXPORT void GSDebugAllocationActiveRecordingObjects(Class c);
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns an array containing all the allocated objects
|
|
|
|
|
* of a certain class which have been recorded.
|
2003-07-22 08:52:37 +00:00
|
|
|
|
* Presumably, you will immediately call [NSObject-description] on
|
2002-10-09 06:07:38 +00:00
|
|
|
|
* them to find out the objects you are leaking.
|
|
|
|
|
* Warning - the objects are put in an array, so until
|
|
|
|
|
* the array is autoreleased, the objects are not released.
|
|
|
|
|
*/
|
2001-04-19 16:10:23 +00:00
|
|
|
|
GS_EXPORT NSArray *GSDebugAllocationListRecordedObjects(Class c);
|
|
|
|
|
|
2003-10-08 15:03:58 +00:00
|
|
|
|
/**
|
|
|
|
|
* This function associates the supplied tag with a recorded
|
|
|
|
|
* object and returns the tag which was previously associated
|
|
|
|
|
* with it (if any).<br />
|
2003-12-23 17:22:06 +00:00
|
|
|
|
* If the object was not recorded, the method returns nil<br />
|
2003-10-08 15:03:58 +00:00
|
|
|
|
* The tag is retained while it is associated with the object.<br />
|
|
|
|
|
* See also the NSDebugFRLog() and NSDebugMRLog() macros.
|
|
|
|
|
*/
|
|
|
|
|
GS_EXPORT id GSDebugAllocationTagRecordedObject(id object, id tag);
|
|
|
|
|
|
2002-10-09 06:07:38 +00:00
|
|
|
|
/**
|
|
|
|
|
* Used to produce a format string for logging a message with function
|
|
|
|
|
* location details.
|
|
|
|
|
*/
|
2000-06-14 04:03:56 +00:00
|
|
|
|
GS_EXPORT NSString* GSDebugFunctionMsg(const char *func, const char *file,
|
1999-03-11 11:07:21 +00:00
|
|
|
|
int line, NSString *fmt);
|
2002-10-09 06:07:38 +00:00
|
|
|
|
/**
|
|
|
|
|
* Used to produce a format string for logging a message with method
|
|
|
|
|
* location details.
|
|
|
|
|
*/
|
2000-06-14 04:03:56 +00:00
|
|
|
|
GS_EXPORT NSString* GSDebugMethodMsg(id obj, SEL sel, const char *file,
|
1999-03-11 11:07:21 +00:00
|
|
|
|
int line, NSString *fmt);
|
2003-10-08 16:26:59 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* This functions allows to set own function callbacks for debugging allocation
|
|
|
|
|
* of objects. Useful if you intend to write your own object allocation code.
|
2003-10-08 16:26:59 +00:00
|
|
|
|
*/
|
2005-11-06 13:53:40 +00:00
|
|
|
|
GS_EXPORT void GSSetDebugAllocationFunctions(
|
|
|
|
|
void (*newAddObjectFunc)(Class c, id o),
|
|
|
|
|
void (*newRemoveObjectFunc)(Class c, id o));
|
2003-10-08 16:26:59 +00:00
|
|
|
|
|
1998-08-04 10:45:43 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2002-03-27 09:55:57 +00:00
|
|
|
|
/**
|
|
|
|
|
* Enable/disable zombies.
|
|
|
|
|
* <p>When an object is deallocated, its isa pointer is normally modified
|
|
|
|
|
* to the hexadecimal value 0xdeadface, so that any attempt to send a
|
|
|
|
|
* message to the deallocated object will cause a crash, and examination
|
|
|
|
|
* of the object within the debugger will show the 0xdeadface value ...
|
|
|
|
|
* making it obvious why the program crashed.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>Turning on zombies changes this behavior so that the isa pointer
|
|
|
|
|
* is modified to be that of the NSZombie class. When messages are
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* sent to the object, instead of crashing, NSZombie will use NSLog() to
|
2002-03-27 09:55:57 +00:00
|
|
|
|
* produce an error message. By default the memory used by the object
|
|
|
|
|
* will not really be freed, so error messages will continue to
|
|
|
|
|
* be generated whenever a message is sent to the object, and the object
|
|
|
|
|
* instance variables will remain available for examination by the debugger.
|
|
|
|
|
* </p>
|
|
|
|
|
* The default value of this boolean is NO, but this can be controlled
|
|
|
|
|
* by the NSZombieEnabled environment variable.
|
|
|
|
|
*/
|
|
|
|
|
GS_EXPORT BOOL NSZombieEnabled;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Enable/disable object deallocation.
|
|
|
|
|
* <p>If zombies are enabled, objects are by default <em>not</em>
|
|
|
|
|
* deallocated, and memory leaks. The NSDeallocateZombies variable
|
|
|
|
|
* lets you say that the the memory used by zombies should be freed.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>Doing this makes the behavior of zombies similar to that when zombies
|
|
|
|
|
* are not enabled ... the memory occupied by the zombie may be re-used for
|
|
|
|
|
* other purposes, at which time the isa pointer may be overwritten and the
|
|
|
|
|
* zombie behavior will cease.
|
|
|
|
|
* </p>
|
|
|
|
|
* The default value of this boolean is NO, but this can be controlled
|
|
|
|
|
* by the NSDeallocateZombies environment variable.
|
|
|
|
|
*/
|
|
|
|
|
GS_EXPORT BOOL NSDeallocateZombies;
|
|
|
|
|
|
1999-11-07 14:50:30 +00:00
|
|
|
|
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
2002-10-09 06:07:38 +00:00
|
|
|
|
#ifdef GSDIAGNOSE
|
2006-10-31 07:05:46 +00:00
|
|
|
|
#import <Foundation/NSObjCRuntime.h>
|
|
|
|
|
#import <Foundation/NSProcessInfo.h>
|
1999-03-10 10:34:56 +00:00
|
|
|
|
|
2002-10-09 06:07:38 +00:00
|
|
|
|
/**
|
|
|
|
|
<p>NSDebugLLog() is the basic debug logging macro used to display
|
|
|
|
|
log messages using NSLog(), if debug logging was enabled at compile
|
|
|
|
|
time and the appropriate logging level was set at runtime.
|
|
|
|
|
</p>
|
|
|
|
|
<p>Debug logging which can be enabled/disabled by defining GSDIAGNOSE
|
|
|
|
|
when compiling and also setting values in the mutable set which
|
|
|
|
|
is set up by NSProcessInfo. GSDIAGNOSE is defined automatically
|
|
|
|
|
unless diagnose=no is specified in the make arguments.
|
|
|
|
|
</p>
|
|
|
|
|
<p>NSProcess initialises a set of strings that are the names of active
|
1999-03-10 10:34:56 +00:00
|
|
|
|
debug levels using the '--GNU-Debug=...' command line argument.
|
2004-06-22 22:27:39 +00:00
|
|
|
|
Each command-line argument of that form is removed from
|
|
|
|
|
<code>NSProcessInfo</code>'s list of arguments and the variable part
|
|
|
|
|
(...) is added to the set.
|
2002-10-09 06:07:38 +00:00
|
|
|
|
This means that as far as the program proper is concerned, it is
|
|
|
|
|
running with the same arguments as if debugging had not been enabled.
|
|
|
|
|
</p>
|
|
|
|
|
<p>For instance, to debug the NSBundle class, run your program with
|
1998-08-04 10:45:43 +00:00
|
|
|
|
'--GNU-Debug=NSBundle'
|
|
|
|
|
You can of course supply multiple '--GNU-Debug=...' arguments to
|
|
|
|
|
output debug information on more than one thing.
|
2002-10-09 06:07:38 +00:00
|
|
|
|
</p>
|
|
|
|
|
<p>NSUserDefaults also adds debug levels from the array given by the
|
|
|
|
|
GNU-Debug key ... but these values will not take effect until the
|
2002-11-04 15:39:43 +00:00
|
|
|
|
+standardUserDefaults method is called ... so they are useless for
|
2004-06-22 22:27:39 +00:00
|
|
|
|
debugging NSUserDefaults itself or for debugging any code executed
|
2002-10-09 06:07:38 +00:00
|
|
|
|
before the defaults system is used.
|
|
|
|
|
</p>
|
|
|
|
|
<p>To embed debug logging in your code you use the NSDebugLLog() or
|
1999-03-10 10:34:56 +00:00
|
|
|
|
NSDebugLog() macro. NSDebugLog() is just NSDebugLLog() with the debug
|
|
|
|
|
level set to 'dflt'. So, to activate debug statements that use
|
|
|
|
|
NSDebugLog(), you supply the '--GNU-Debug=dflt' argument to your program.
|
2002-10-09 06:07:38 +00:00
|
|
|
|
</p>
|
|
|
|
|
<p>You can also change the active debug levels under your programs control -
|
1999-03-10 10:34:56 +00:00
|
|
|
|
NSProcessInfo has a [-debugSet] method that returns the mutable set that
|
|
|
|
|
contains the active debug levels - your program can modify this set.
|
2002-10-09 06:07:38 +00:00
|
|
|
|
</p>
|
|
|
|
|
<p>Two debug levels have a special effect - 'dflt' is the level used for
|
|
|
|
|
debug logs statements where no debug level is specified, and 'NoWarn'
|
|
|
|
|
is used to *disable* warning messages.
|
|
|
|
|
</p>
|
|
|
|
|
<p>As a convenience, there are four more logging macros you can use -
|
1999-03-11 11:07:21 +00:00
|
|
|
|
NSDebugFLog(), NSDebugFLLog(), NSDebugMLog() and NSDebugMLLog().
|
|
|
|
|
These are the same as the other macros, but are specifically for use in
|
|
|
|
|
either functions or methods and prepend information about the file, line
|
|
|
|
|
and either function or class/method in which the message was generated.
|
2002-10-09 06:07:38 +00:00
|
|
|
|
</p>
|
1998-08-04 10:45:43 +00:00
|
|
|
|
*/
|
1998-08-04 12:27:57 +00:00
|
|
|
|
#define NSDebugLLog(level, format, args...) \
|
1999-03-10 10:34:56 +00:00
|
|
|
|
do { if (GSDebugSet(level) == YES) \
|
2000-08-07 22:00:31 +00:00
|
|
|
|
NSLog(format , ## args); } while (0)
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This macro is a shorthand for NSDebugLLog() using then default debug
|
|
|
|
|
* level ... 'dflt'
|
|
|
|
|
*/
|
1998-08-04 12:27:57 +00:00
|
|
|
|
#define NSDebugLog(format, args...) \
|
1999-03-10 10:34:56 +00:00
|
|
|
|
do { if (GSDebugSet(@"dflt") == YES) \
|
2000-08-07 22:00:31 +00:00
|
|
|
|
NSLog(format , ## args); } while (0)
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This macro is like NSDebugLLog() but includes the name and location
|
|
|
|
|
* of the function in which the macro is used as part of the log output.
|
|
|
|
|
*/
|
1999-03-11 11:07:21 +00:00
|
|
|
|
#define NSDebugFLLog(level, format, args...) \
|
|
|
|
|
do { if (GSDebugSet(level) == YES) { \
|
|
|
|
|
NSString *fmt = GSDebugFunctionMsg( \
|
|
|
|
|
__PRETTY_FUNCTION__, __FILE__, __LINE__, format); \
|
2000-08-07 22:00:31 +00:00
|
|
|
|
NSLog(fmt , ## args); }} while (0)
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This macro is a shorthand for NSDebugFLLog() using then default debug
|
|
|
|
|
* level ... 'dflt'
|
|
|
|
|
*/
|
1999-03-11 11:07:21 +00:00
|
|
|
|
#define NSDebugFLog(format, args...) \
|
|
|
|
|
do { if (GSDebugSet(@"dflt") == YES) { \
|
|
|
|
|
NSString *fmt = GSDebugFunctionMsg( \
|
|
|
|
|
__PRETTY_FUNCTION__, __FILE__, __LINE__, format); \
|
2000-08-07 22:00:31 +00:00
|
|
|
|
NSLog(fmt , ## args); }} while (0)
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This macro is like NSDebugLLog() but includes the name and location
|
|
|
|
|
* of the <em>method</em> in which the macro is used as part of the log output.
|
|
|
|
|
*/
|
1999-03-11 11:07:21 +00:00
|
|
|
|
#define NSDebugMLLog(level, format, args...) \
|
|
|
|
|
do { if (GSDebugSet(level) == YES) { \
|
|
|
|
|
NSString *fmt = GSDebugMethodMsg( \
|
|
|
|
|
self, _cmd, __FILE__, __LINE__, format); \
|
2000-08-07 22:00:31 +00:00
|
|
|
|
NSLog(fmt , ## args); }} while (0)
|
2002-10-09 06:07:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This macro is a shorthand for NSDebugMLLog() using then default debug
|
|
|
|
|
* level ... 'dflt'
|
|
|
|
|
*/
|
1999-03-11 11:07:21 +00:00
|
|
|
|
#define NSDebugMLog(format, args...) \
|
|
|
|
|
do { if (GSDebugSet(@"dflt") == YES) { \
|
|
|
|
|
NSString *fmt = GSDebugMethodMsg( \
|
|
|
|
|
self, _cmd, __FILE__, __LINE__, format); \
|
2000-08-07 22:00:31 +00:00
|
|
|
|
NSLog(fmt , ## args); }} while (0)
|
2003-10-08 15:03:58 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This macro saves the name and location of the function in
|
|
|
|
|
* which the macro is used, along with a short string msg as
|
|
|
|
|
* the tag associated with a recorded object.
|
|
|
|
|
*/
|
|
|
|
|
#define NSDebugFRLog(object, msg) \
|
|
|
|
|
do { \
|
|
|
|
|
NSString *tag = GSDebugFunctionMsg( \
|
|
|
|
|
__PRETTY_FUNCTION__, __FILE__, __LINE__, msg); \
|
|
|
|
|
GSDebugAllocationTagRecordedObject(object, tag); } while (0)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This macro saves the name and location of the method in
|
|
|
|
|
* which the macro is used, along with a short string msg as
|
|
|
|
|
* the tag associated with a recorded object.
|
|
|
|
|
*/
|
|
|
|
|
#define NSDebugMRLog(object, msg) \
|
|
|
|
|
do { \
|
|
|
|
|
NSString *tag = GSDebugMethodMsg( \
|
|
|
|
|
self, _cmd, __FILE__, __LINE__, msg); \
|
|
|
|
|
GSDebugAllocationTagRecordedObject(object, tag); } while (0)
|
|
|
|
|
|
1998-08-04 10:45:43 +00:00
|
|
|
|
#else
|
1998-08-04 12:27:57 +00:00
|
|
|
|
#define NSDebugLLog(level, format, args...)
|
|
|
|
|
#define NSDebugLog(format, args...)
|
1999-03-11 11:07:21 +00:00
|
|
|
|
#define NSDebugFLLog(level, format, args...)
|
|
|
|
|
#define NSDebugFLog(format, args...)
|
|
|
|
|
#define NSDebugMLLog(level, format, args...)
|
|
|
|
|
#define NSDebugMLog(format, args...)
|
2003-10-08 15:03:58 +00:00
|
|
|
|
#define NSDebugFRLog(object, msg)
|
|
|
|
|
#define NSDebugMRLog(object, msg)
|
1998-08-04 10:45:43 +00:00
|
|
|
|
#endif
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
2004-05-24 16:08:03 +00:00
|
|
|
|
/**
|
|
|
|
|
* Macro to log a message only the first time it is encountered.<br />
|
|
|
|
|
* Not entirely thread safe ... but that's not really important,
|
|
|
|
|
* it just means that it's possible for the message to be logged
|
|
|
|
|
* more than once if two threads call it simultaneously when it
|
|
|
|
|
* has not already been called.<br />
|
|
|
|
|
* Use this from inside a function. Pass an NSString as a format,
|
|
|
|
|
* followed by zero or more arguments for the format string.
|
|
|
|
|
* Example: GSOnceMLog(@"This function is deprecated, use another");
|
|
|
|
|
*/
|
|
|
|
|
#define GSOnceFLog(format, args...) \
|
|
|
|
|
do { static BOOL beenHere = NO; if (beenHere == NO) {\
|
|
|
|
|
NSString *fmt = GSDebugFunctionMsg( \
|
|
|
|
|
__PRETTY_FUNCTION__, __FILE__, __LINE__, format); \
|
|
|
|
|
beenHere = YES; \
|
|
|
|
|
NSLog(fmt , ## args); }} while (0)
|
|
|
|
|
/**
|
|
|
|
|
* Macro to log a message only the first time it is encountered.<br />
|
|
|
|
|
* Not entirely thread safe ... but that's not really important,
|
|
|
|
|
* it just means that it's possible for the message to be logged
|
|
|
|
|
* more than once if two threads call it simultaneously when it
|
|
|
|
|
* has not already been called.<br />
|
|
|
|
|
* Use this from inside a method. Pass an NSString as a format
|
|
|
|
|
* followed by zero or more arguments for the format string.<br />
|
|
|
|
|
* Example: GSOnceMLog(@"This method is deprecated, use another");
|
|
|
|
|
*/
|
|
|
|
|
#define GSOnceMLog(format, args...) \
|
|
|
|
|
do { static BOOL beenHere = NO; if (beenHere == NO) {\
|
|
|
|
|
NSString *fmt = GSDebugMethodMsg( \
|
|
|
|
|
self, _cmd, __FILE__, __LINE__, format); \
|
|
|
|
|
beenHere = YES; \
|
|
|
|
|
NSLog(fmt , ## args); }} while (0)
|
|
|
|
|
|
1999-11-07 14:50:30 +00:00
|
|
|
|
|
|
|
|
|
|
2002-10-09 06:07:38 +00:00
|
|
|
|
#ifdef GSWARN
|
2006-10-31 07:05:46 +00:00
|
|
|
|
#import <Foundation/NSObjCRuntime.h>
|
1999-11-07 14:50:30 +00:00
|
|
|
|
|
2002-10-09 06:07:38 +00:00
|
|
|
|
/**
|
|
|
|
|
<p>NSWarnLog() is the basic debug logging macro used to display
|
|
|
|
|
warning messages using NSLog(), if warn logging was not disabled at compile
|
|
|
|
|
time and the disabling logging level was not set at runtime.
|
|
|
|
|
</p>
|
|
|
|
|
<p>Warning messages which can be enabled/disabled by defining GSWARN
|
|
|
|
|
when compiling.
|
|
|
|
|
</p>
|
|
|
|
|
<p>You can also disable these messages at runtime by supplying a
|
|
|
|
|
'--GNU-Debug=NoWarn' argument to the program, or by adding 'NoWarn'
|
|
|
|
|
to the user default array named 'GNU-Debug'.
|
|
|
|
|
</p>
|
|
|
|
|
<p>These logging macros are intended to be used when the software detects
|
1999-11-07 14:50:30 +00:00
|
|
|
|
something that it not necessarily fatal or illegal, but looks like it
|
|
|
|
|
might be a programming error. eg. attempting to remove 'nil' from an
|
|
|
|
|
NSArray, which the Spec/documentation does not prohibit, but which a
|
2004-06-22 22:27:39 +00:00
|
|
|
|
well written program should not be attempting (since an NSArray object
|
1999-11-07 14:50:30 +00:00
|
|
|
|
cannot contain a 'nil').
|
2002-10-09 06:07:38 +00:00
|
|
|
|
</p>
|
|
|
|
|
<p>NB. The 'warn=yes' option is understood by the GNUstep make package
|
1999-11-07 14:50:30 +00:00
|
|
|
|
to mean that GSWARN should be defined, and the 'warn=no' means that
|
2002-10-09 06:07:38 +00:00
|
|
|
|
GSWARN should be undefined. Default is to define it.
|
|
|
|
|
</p>
|
|
|
|
|
<p>To embed debug logging in your code you use the NSWarnLog() macro.
|
|
|
|
|
</p>
|
|
|
|
|
<p>As a convenience, there are two more logging macros you can use -
|
2004-06-22 22:27:39 +00:00
|
|
|
|
NSWarnFLog(), and NSWarnMLog().
|
1999-11-07 14:50:30 +00:00
|
|
|
|
These are specifically for use in either functions or methods and
|
|
|
|
|
prepend information about the file, line and either function or
|
|
|
|
|
class/method in which the message was generated.
|
2002-10-09 06:07:38 +00:00
|
|
|
|
</p>
|
1999-11-07 14:50:30 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define NSWarnLog(format, args...) \
|
2002-10-09 06:07:38 +00:00
|
|
|
|
do { if (GSDebugSet(@"NoWarn") == NO) { \
|
|
|
|
|
NSLog(format , ## args); }} while (0)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This macro is like NSWarnLog() but includes the name and location of the
|
|
|
|
|
* <em>function</em> in which the macro is used as part of the log output.
|
|
|
|
|
*/
|
1999-11-07 14:50:30 +00:00
|
|
|
|
#define NSWarnFLog(format, args...) \
|
2002-10-09 06:07:38 +00:00
|
|
|
|
do { if (GSDebugSet(@"NoWarn") == NO) { \
|
1999-11-07 14:50:30 +00:00
|
|
|
|
NSString *fmt = GSDebugFunctionMsg( \
|
|
|
|
|
__PRETTY_FUNCTION__, __FILE__, __LINE__, format); \
|
2002-10-09 06:07:38 +00:00
|
|
|
|
NSLog(fmt , ## args); }} while (0)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This macro is like NSWarnLog() but includes the name and location of the
|
|
|
|
|
* <em>method</em> in which the macro is used as part of the log output.
|
|
|
|
|
*/
|
1999-11-07 14:50:30 +00:00
|
|
|
|
#define NSWarnMLog(format, args...) \
|
2002-10-09 06:07:38 +00:00
|
|
|
|
do { if (GSDebugSet(@"NoWarn") == NO) { \
|
1999-11-07 14:50:30 +00:00
|
|
|
|
NSString *fmt = GSDebugMethodMsg( \
|
|
|
|
|
self, _cmd, __FILE__, __LINE__, format); \
|
2002-10-09 06:07:38 +00:00
|
|
|
|
NSLog(fmt , ## args); }} while (0)
|
1999-11-07 14:50:30 +00:00
|
|
|
|
#else
|
|
|
|
|
#define NSWarnLog(format, args...)
|
|
|
|
|
#define NSWarnFLog(format, args...)
|
|
|
|
|
#define NSWarnMLog(format, args...)
|
|
|
|
|
#endif
|
|
|
|
|
|
2004-07-29 15:30:47 +00:00
|
|
|
|
/**
|
|
|
|
|
* Retrieve stack information. Use caution: uses built-in gcc functions
|
|
|
|
|
* and currently only works up to 100 frames.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
GS_EXPORT void *NSFrameAddress(NSUInteger offset);
|
2004-07-29 15:30:47 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Retrieve stack information. Use caution: uses built-in gcc functions
|
|
|
|
|
* and currently only works up to 100 frames.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
GS_EXPORT void *NSReturnAddress(NSUInteger offset);
|
2004-07-29 15:30:47 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Retrieve stack information. Use caution: uses built-in gcc functions
|
|
|
|
|
* and currently only works up to 100 frames.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
GS_EXPORT NSUInteger NSCountFrames(void);
|
2000-08-23 18:54:22 +00:00
|
|
|
|
|
2006-09-13 10:20:49 +00:00
|
|
|
|
#if defined(__cplusplus)
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1997-09-01 21:59:51 +00:00
|
|
|
|
#endif
|