home *** CD-ROM | disk | FTP | other *** search
- /* NSDebug.h
- Debug utilities - do not depend on this in production code
- Copyright 1994-1996, NeXT Software, Inc. All rights reserved.
- */
-
- #if !defined(STRICT_OPENSTEP)
-
- /**************************************************************************
- WARNING: Unsupported API.
-
- This module contains material that is only partially supported -- if
- at all. Do not depend on the existance of any of these symbols in your
- code in future releases of this software. Certainly, do not depend on
- the symbols in this header in production code. The format of any data
- produced by the functions in this header may also change at any time.
-
- However, it should be noted that the features in this file have been
- found to be generally useful, and in some cases invaluable, and are not
- likely to go away anytime soon. Some of these facilities, unfortunately,
- are oriented towards most convenient use on a UNIX-like platform.
- **************************************************************************/
-
- #import <Foundation/NSObject.h>
- #import <Foundation/NSAutoreleasePool.h>
-
- /* The environment component of this API
-
- The boolean- and integer-valued variables declared in this header,
- plus some values set by methods, read starting values from the
- process's environment at process startup. This is mostly a benefit
- if you need to initialize these variables to some non-default value
- before your program's main() routine gets control, but it also
- allows you to change the value without modifying your program's
- source. (Variables can be set and methods called around specific
- areas within a program, too, of course.)
-
- This opens the door to various possibilites, such as a
- statistics-gathering application which spawns off the process to
- be measured, providing a custom environment. The parent process
- could then read the output of the statistics from the file
- descriptor it had opened, and specified in the environment.
-
- In sh/ksh/zsh or other sh-influenced shell, you can set the value in
- the environment like this:
- % export NSKeepAllocationStatistics=YES
- % myProg
-
- or for just that process:
- % NSKeepAllocationStatistics=YES myProg
-
- In a csh/tcsh or other csh-influenced shell, you do this:
- > setenv NSKeepAllocationStatistics YES
- > myProg
-
-
- The initialization from the environment happens very early, but may
- not have happened yet at the time of a +load method statically linked
- into an application (as opposed to one in a dynamically loaded module).
- But as noted in the "Foundation Release Notes", +load methods that are
- statically linked into an application are tricky to use and are not
- recommended.
-
- Here is a table of the variables/values initialized from the environment
- at startup. Some of these just set variables, others call methods to
- set the values.
-
- NAME OF ENV. VARIABLE DEFAULT SET IT TO...
- NSDebugEnabled NO "YES"
- NSZombieEnabled NO "YES"
- NSDeallocateZombies NO "YES"
- NSHangOnMallocError NO "YES"
-
- NSEnableAutoreleasePool YES "NO"
- NSAutoreleaseFreedObjectCheckEnabled NO "YES"
- NSAutoreleaseHighWaterMark 0 non-negative integer
- NSAutoreleaseHighWaterResolution 0 non-negative integer
-
- NSKeepZoneStatistics NO "YES"
- NSZoneStatisticsFD file in /tmp open file descriptor number
- NSKeepAllocationStatistics NO "YES"
- NSAllocationStatisticsFD file in /tmp open file descriptor number
- NSKeepNotificationStatistics NO "YES"
- NSNotificationStatisticsFD file in /tmp open file descriptor number
-
- */
-
- /**************** General ****************/
-
- FOUNDATION_EXPORT BOOL NSDebugEnabled;
- // Mostly used to turn on the stack-processing and recording facility.
- // The 'oh' command can be used to most easily access this facility.
- // The default is NO. ('oh' is currently available only on MACH.)
-
- FOUNDATION_EXPORT BOOL NSZombieEnabled;
- // Enable object zombies. When an object is deallocated, its isa
- // pointer is modified to be that of a "zombie" class (whether or
- // not the storage is then freed can be controlled by the
- // NSDeallocateZombies variable). Messages sent to the zombie
- // object cause logged messages and can be broken on in a debugger.
- // The default is NO.
-
- FOUNDATION_EXPORT BOOL NSDeallocateZombies;
- // Determines whether the storage of objects that have been
- // "zombified" is then freed or not. The default value (NO)
- // is most suitable for debugging messages sent to zombie
- // objects. And since the memory is never freed, storage
- // allocated to an object will never be reused, either (which
- // is sometimes useful otherwise).
-
- FOUNDATION_EXPORT BOOL NSHangOnMallocError;
- // MACH only: Cause the process to hang after printing out the
- // "Malloc-related error detected with code N" message to stderr.
- // A backtrace can be gotten from the process with the 'sample'
- // utility. The default is NO. Has no effect on non-MACH platforms.
-
-
- /**************** Stack processing/recording ****************/
-
- FOUNDATION_EXPORT void NSDebugRecordObjectAndStack(id self);
- // Used with NSDebugEnabled to record object history. In a
- // method, use like:
- // if (NSDebugEnabled) NSDebugRecordObjectAndStack(self);
- // The 'oh' command can be used to dump the recorded information.
- // ('oh' is currently available only on MACH.)
-
- #if !defined(STRICT_40)
-
- FOUNDATION_EXPORT void *NSFrameAddress(unsigned frame);
- FOUNDATION_EXPORT void *NSReturnAddress(unsigned frame);
- // Returns the value of the frame pointer or return address,
- // respectively, of the specified frame. Frames are numbered
- // sequentially, with the "current" frame being zero, the
- // previous frame being 1, etc. The current frame is the
- // frame in which either of these functions is called. For
- // example, NSReturnAddress(0) returns an address near where
- // this function was called, NSReturnAddress(1) returns the
- // address to which control will return when current frame
- // exits, etc. If the requested frame does not exist, then
- // NULL is returned. The behavior of these functions is
- // undefined in the presence of code which has been compiled
- // without frame pointers. Currently only information about
- // the first 160 frames (0 <= frame <= 160) can be computed.
-
- FOUNDATION_EXPORT unsigned NSCountFrames(void);
- // Returns the number of call frames on the stack. The behavior
- // of this functions is undefined in the presence of code which
- // has been compiled without frame pointers.
-
- #endif
-
- /**************** Autorelease pool debugging ****************/
-
- @interface NSAutoreleasePool (NSAutoreleasePoolDebugging)
-
- // Functions used as interesting breakpoints in a debugger
- FOUNDATION_EXPORT void _NSAutoreleaseNoPool(void *object);
- // Called to log the "Object X of class Y autoreleased with no
- // pool in place - just leaking" message.
-
- FOUNDATION_EXPORT void _NSAutoreleaseFreedObject(void *freedObject);
- // Called when a previously freed object would be released
- // by an autorelease pool. See +enableFreedObjectCheck: below.
-
- FOUNDATION_EXPORT void _NSAutoreleaseHighWaterLog(unsigned int count);
- // Called whenever a high water mark is reached by a pool.
- // See +setPoolCountHighWaterMark: below.
-
- + (void)enableRelease:(BOOL)enable;
- // Enables or disables autorelease pools; that is, whether or
- // not the autorelease pools send the -release message to their
- // objects when each pool is released. This message affects only
- // the pools of the autorelease pool stack of the current thread
- // (and any future pools in that thread). The "default default"
- // value can be set in the initial environment when a program
- // is launched with the NSEnableAutoreleasePool environment
- // variable (see notes at the top of this file) -- as thread
- // pool-stacks are created, they take their initial enabled
- // state from that environment variable.
-
- + (void)showPools;
- // Displays to stderr the state of the current thread's
- // autorelease pool stack.
-
- + (void)resetTotalAutoreleasedObjects;
- + (unsigned)totalAutoreleasedObjects;
- // Returns the number of objects autoreleased (in ALL threads,
- // currently) since the counter was last reset to zero with
- // +resetTotalAutoreleasedObjects.
-
- + (void)enableFreedObjectCheck:(BOOL)enable;
- // Enables or disables freed-object checking for the pool stack
- // of the current thread (and any future pools in that thread).
- // When enabled, an autorelease pool will call the function
- // _NSAutoreleaseFreedObject() when it is about to attempt to
- // release an object that the runtime has marked as freed (and
- // then it doesn't attempt to send -release to the freed storage).
- // The pointer to the freed storage is passed to that function.
- // The "default default" value can be set in the initial
- // environment when a program is launched with the
- // NSAutoreleaseFreedObjectCheckEnabled environment variable
- // (see notes at the top of this file) -- as thread pool-stacks
- // are created, they take their initial freed-object-check state
- // from that environment variable.
-
- + (unsigned int)autoreleasedObjectCount;
- // Returns the total number of autoreleased objects in all pools
- // in the current thread's pool stack.
-
- + (unsigned int)topAutoreleasePoolCount;
- // Returns the number of autoreleased objects in top pool of
- // the current thread's pool stack.
-
- + (unsigned int)poolCountHighWaterMark;
- + (void)setPoolCountHighWaterMark:(unsigned int)count;
- // Sets the pool count high water mark for the pool stack of
- // the current thread (and any future pools in that thread). When
- // 'count' objects have accumulated in the top autorelease pool,
- // the pool will call _NSAutoreleaseHighWaterLog(), which
- // generates a message to stderr. The number of objects in the
- // top pool is passed as the parameter to that function. The
- // default high water mark is 0, which disables pool count
- // monitoring. The "default default" value can be set in the
- // initial environment when a program is launched with the
- // NSAutoreleaseHighWaterMark environment variable (see notes at
- // the top of this file) -- as thread pool-stacks are created,
- // they take their initial high water mark value from that
- // environment variable. See also +setPoolCountHighWaterResolution:.
-
- + (unsigned int)poolCountHighWaterResolution;
- + (void)setPoolCountHighWaterResolution:(unsigned int)res;
- // Sets the pool count high water resolution for the pool stack of
- // the current thread (and any future pools in that thread). A
- // call to _NSAutoreleaseHighWaterLog() is generated every multiple
- // of 'res' objects above the high water mark. If 'res' is zero
- // (the default), only one call to _NSAutoreleaseHighWaterLog() is
- // made, when the high water mark is reached. The "default default"
- // value can be set in the initial environment when a program is
- // launched with the NSAutoreleaseHighWaterResolution environment
- // variable (see notes at the top of this file) -- as thread
- // pool-stacks are created, they take their initial high water
- // resolution value from that environment variable. See also
- // +setPoolCountHighWaterMark:.
-
-
- // Obsolete API. Use the methods above instead.
- + (void)enableDoubleReleaseCheck:(BOOL)enable;
- // Use +enableFreedObjectCheck:
- + (void)showPoolsWithObjectIdenticalTo:(id)object;
- // Use +showPools
- + (void)setPoolCountThreshold:(unsigned)count;
- // Equivalent to:
- // [NSAutoreleasePool setPoolCountHighWaterMark:count];
- // [NSAutoreleasePool setPoolCountHighWaterResolution:count];
-
- @end
-
-
- /**************** Statistics-keeping ****************/
-
- // The statistics-keeping facilities generate output on various
- // types of events. Currently, output logs can be generated for
- // use of the zone allocation functions (NSZoneMalloc(), etc.),
- // allocation and deallocation of objects (and other types of
- // lifetime-related events), and for use of the notification
- // facilities (NSNotificationCenter). Currently, also, the output
- // generated is in a columnar ASCII form, to make it most
- // convenient to use command-line data processing utilities,
- // like 'awk', 'grep', and 'sed'.
-
- // The boolean enabling variables can be set in a program, perhaps
- // "around" a section of code that is of interest, and the values
- // can also be given a non-default initial state by placing special
- // environment variables into a process's initial environment (see
- // notes at the top of this file). The names of those environment
- // variables are the same as the names of the enabling variables.
-
- // The destination of the output can be controlled somewhat by
- // setting the values of the "FD" variables below, either at runtime
- // or in the environment, as described above.
-
- FOUNDATION_EXPORT BOOL NSKeepZoneStatistics;
- // Default is NO.
-
- FOUNDATION_EXPORT int NSZoneStatisticsFD;
- // Number of open file descriptor to which output will be
- // written, currently using write(). By default, a file
- // called "zone_stats_<name>_<pid>" (where <name> is the
- // process name and <pid> is the process id) is created in
- // the platform's temporary directory when first needed.
-
- FOUNDATION_EXPORT int NSZoneStatisticsOutputVersion;
- // Not currently used.
-
-
- FOUNDATION_EXPORT BOOL NSKeepAllocationStatistics;
- // Default is NO.
-
- FOUNDATION_EXPORT int NSAllocationStatisticsFD;
- // Number of open file descriptor to which output will be
- // written, currently using write(). By default, a file
- // called "alloc_stats_<name>_<pid>" (where <name> is the
- // process name and <pid> is the process id) is created in
- // the platform's temporary directory when first needed.
-
- FOUNDATION_EXPORT int NSAllocationStatisticsOutputVersion;
- // Not currently used.
-
-
- FOUNDATION_EXPORT BOOL NSKeepNotificationStatistics;
- // Default is NO.
-
- FOUNDATION_EXPORT int NSNotificationStatisticsFD;
- // Number of open file descriptor to which output will be
- // written, currently using write(). By default, a file
- // called "note_stats_<name>_<pid>" (where <name> is the
- // process name and <pid> is the process id) is created in
- // the platform's temporary directory when first needed.
-
- FOUNDATION_EXPORT int NSNotificationStatisticsOutputVersion;
- // Not currently used.
-
-
-
- /* NOTE: The information below is somewhat incomplete and contains
- * inaccuracies, and has not been updated since the prerelease(s).
- * The OpenStep Conversion Guide contains additional information
- * which may be more accurate. Note, too, that there is no information
- * here on the format of the notification statistics output at this
- * time (but the format is similar to that of the zone and allocation
- * statistics output).
- */
-
- /*********** Zone allocation statistics ***********/
-
- /* All output lines begin with 5 fields:
- TIME FRAME RETURN PTRADDR OP
- where TIME is the time in seconds since the reference date for NSDate,
- FRAME is the value of the frame pointer register for the function/method
- that called one of the instrumented functions, RETURN is the return
- address back to the function that called one of the instrumented functions,
- PTRADDR is the address of the object being manipulated/allocated, and
- finally OP is the event being recorded:
- MALLOC (NSZoneMalloc()),
- CALLOC (NSZoneCalloc()),
- REALLOC (NSZoneRealloc()),
- MFREE (NSZoneFree()),
- VALLOC (NSAllocateMemoryPages()),
- VFREE (NSDeallocateMemoryPages()),
- VCOPY (NSCopyMemoryPages()),
- CREATE (NSCreateZone()),
- RECYCLE (NSRecycleZone()),
- SETNAME (NSSetZoneName()),
- GETNAME (NSZoneName()),
- GETZONE (NSZoneFromPointer()),
- DEFAULT (NSDefaultMallocZone()),
- INVALID (some unknown OP; bug).
-
- For the operations FREE, VMFREE, DEFAULT, RECYCLE, and GETNAME, that's it.
- The other operations have this additional information:
- MALLOC
- CALLOC
- ZONE SIZE
-
- REALLOC
- ZONE SIZE RESPTR
-
- VALLOC
- SIZE
-
- VCOPY
- SIZE DSTPTR
-
- CREATE
- SIZE GRAN CANFREE
-
- SETNAME
- NAME
-
- GETZONE
- ZONE
-
- INVALID
- OP#
-
- where ZONE is the address of the zone from which the object was allocated,
- SIZE is the number of bytes requested, RESPTR is the result pointer from
- reallocation, DSTPTR is the destination pointer for copying, GRAN is the
- granularity of a new zone, CANFREE is YES or NO depending on whether or
- not memory is really freed from the zone, NAME is the name assigned to a
- zone, and OP# is the internal integer used to represent an event.
- */
-
- /*********** Allocation statistics ***********/
-
- /* All output lines begin with 6 fields:
- TIME FRAME RETURN OBJADDR CLASS OP
- where TIME is the time in seconds since the reference date for NSDate,
- FRAME is the value of the frame pointer register for the function/method
- that called one of the instrumented functions, RETURN is the return
- address back to the function that called one of the instrumented functions,
- OBJADDR is the address of the object being manipulated/allocated, CLASS is
- the classname of the object, and finally OP is the event being recorded:
- ALLOC (NSAllocateObject()),
- FREE (NSDeallocateObject()),
- COPY (NSCopyObject()),
- AUTO (-autorelease),
- REF+ (NSIncrementExtraRefCount() after increment),
- REF- (NSDecrementExtraRefCountWasZero() before decrement),
- IREF+ (_NSIncrementInternalRefCount() after increment),
- IREF- (_NSDecrementInternalRefCountWasZero() before decrement),
- INVALID (some unknown OP; bug).
-
- Note that not all classes use _NSIncrementInternalRefCount() and
- _NSDecrementInternalRefCountWasZero() to implement their internal
- reference counting. Note also that IREF+/- do not include value
- of internal reference count -- that has be computed by some post-
- processing program.
-
- For the operations AUTO, FREE, and REF?, that's it. The other
- operations have this additional information:
- ALLOC
- ZONE ISIZE ESIZE ASIZE
- COPY
- COPYADDR COPYCLASS COPYZONE COPYISIZE COPYESIZE COPYASIZE
- REF+
- POSTREFCNT
- REF-
- PREREFCNT
- INVALID
- OP#
-
- where ZONE is the name of the zone from which the object was allocated,
- ISIZE is the instance_size of the object's class, ESIZE is the number
- of extra bytes requested for the object, ASIZE is the actual size of
- the block of memory allocated by the malloc() system, COPY* are the
- corresponding items for the created copy, POSTREFCNT is the external
- retain count of the object after incrementing, PREREFCNT is the external
- retain count of the object before decrementing, and OP# is the internal
- integer used to represent an event.
- */
-
- #endif /* !STRICT_OPENSTEP */
-