Further to my recent PAUSE registration request and postings on
comp.lang.perl.modules I am proposing a new module to track perl object life
to help detect memory leaks in perl programs/modules (not perl itself)

Here is the pod documentation which will hopefully explain what it will do -
all comments welcome:

NAME
       Devel::ObjectTracker - Track object life to aid memory
       leak detection

SYNOPSIS
         perl5 -d:ObjectTracker test.pl

DESCRIPTION
       Debug module to find where perl objects (or arrays, hashes
       and globs) are created by checking for objects passed to
       and/or returned from subs, and monitoring when they are
       destroyed via destructor subs.  This can help detect
       memory leaks caused by objects being left behind in your
       programs when they shouldn't be.

       The main output is stored in a file which logs the first
       time a memory reference is seen with datetime, current
       session number (starts at 1), object type, call stack
       etc., and whether the object was first seen returned from
       a sub or passed as an argument.  Details are also logged
       whenever an object is destroyed. This includes the
       datetime, session and call stack when the object was
       created.

       The subroutine Devel::ObjectTracker::output_details
       outputs details on the currently existing objects on
       demand.  These details contain date/time, session, call
       stack, etc. when the object was created.

EXAMPLES
       When started ObjectTracker will output all object
       creation/destruction in the log file ObjectTracker.log
       with a session ID of 1.

       At a suitable point in your prog the sub
       Devel::ObjectTracker::output_details should be called
       which will output a list of all current objects to a file
       ObjectTracker_details_1.txt and then it will increment the
       session ID to 2.

       You should then carry out the operations being studied.
       All object creation/destruction will now be recorded in
       the log file with session ID of 2.

       After the operation you should call
       Devel::ObjectTracker::output_details again.  This will
       output a list of all current objects to a file
       ObjectTracker_details_2.txt and then it will increment the
       session ID to 3.

       A look at the details file ObjectTracker_details_2.txt
       will show any objects that were created during sessions 1
       and 2.  From the date/time, session and call stack you can
       see when and where they were created.  This can highlight
       objects which are still in existence and shouldn't be.

       Multiple sessions can be used to good effect in complex
       programs either with output each time as above or
       separately incremented using the sub
       Devel::ObjectTracker::increment_session

OPTIONS
       ObjectTracker has some variables which can be used during
       your script to affect what gets tracked.

       o   To track hashes, arrays and globs as well as true
           objects set $Devel::ObjectTracker::objects_only to 0.
           The default is 1, i.e. only true objects.

       o   By default it will look for new objects in all subs.
           $Devel::ObjectTracker::sub_pattern can be used to
           defined a subroutine name pattern within which to look
           for new objects. Note it will always check for
           destructors (=~ /DESTROY$/).

       o   The output to STDOUT can be adjusted by changing
           $Devel::ObjectTracker::verbose as follows:

            0 = print nothing
            1 = print file creation, session ID etc.   (default)
            2 = print summary details upon object creation/destruction
            3 = print subroutine calls as well as object details

       o   The log file name can be changed by setting
           $Devel::ObjectTracker::log_file.  The default is
           ObjectTracker.log in the current directory.

       o   The details file name can be changed by setting
           $Devel::ObjectTracker::details_file.  The token <NN>
           will be replaced by the current session number (before
           it is incremented).  The default is
           ObjectTracker_details_<NN>.txt in the current
           directory.

       o   Object monitoring can be switched on and off in your
           programs by $Devel::ObjectTracker::enable.  The
           default is 1 (on).

       o   The whether a file header is printed is controlled by
           $Devel::ObjectTracker::print_header.  The default is 1
           (yes).

       o   The output file beginning of line is set by
           $Devel::ObjectTracker::bol.  The default is nothing.
           Set to "\"" for csv format.

       o   The output file value seperator is set by
           $Devel::ObjectTracker::delim.  The default is tab
           (\t). Set to "\",\"" for csv format.

       o   The output file end of line  is set by
           $Devel::ObjectTracker::eol.  The default is a single
           newline (\n).  Set to "\"\n" for csv format.

       o   The stack format line is set by
           $Devel::ObjectTracker::stack_format.  This can contain
           tokens of <LEVEL>, <PACK>, <FILE>, <LINE>, <CALLSUB>,
           <SUBNAME>, <HASARGS>, <WANTARRAY> which are replaced
           as follows:

              LEVEL     = the call level (starts at 0)
              PACK      = package
              FILE      = file name
              LINE      = line number
              CALLSUB   = the calling sub
              SUBNAME   = the called sub
              HASARGS   = as for caller()
              WANTARRAY = as for caller()

           The default is "<FILE>(<SUBNAME>) l=<LINE>".

       o   The stack seperator is set by
           $Devel::ObjectTracker::stack_delim.  The default is ";
           ".

       These variables can be put in a file called .objecttracker
       in the current directory as in the following example:

           $Devel::ObjectTracker::objects_only = 0;
           $Devel::ObjectTracker::sub_pattern  = "^Mysubs::";
           $Devel::ObjectTracker::log_file     = "mylogfile";
           $Devel::ObjectTracker::details_file = "mydetails_<NN>.txt";

       will set ObjectTracker to track hashes, arrays and globs
       as well as objects but only in subroutines that match
       pattern ^Mysubs::.  The log output will be in mylogfile
       and details will be output to mydetails_1.txt,
       mydetails_2.txt, etc.

NOTES
       o   Memory references/Objects are often seen first in
           unexpected places.  For example as hash arguments to
           subs which are called within the constructor or after
           unpacking by Storable::thaw etc.

           See also Exists as similarly objects are often seen
           seemingly for the first time when called below
           destructors.

       o   A sub UNIVERSAL::DESTROY is defined to catch destroys
           of objects which do not have destructors defined
           themselves.  If the program defines this sub itself
           then this should get overridden however this could
           produce confusing results.

       o   It uses the debug hook DB::sub to look for memory
           references returned from subroutine calls, passed as
           arguments and checks for destructors.

       o   Enabling/disabling monitoring and using subroutine
           patterns only affects checking for new objects.
           Destruction is always monitored.

       o   As every subroutine call is being intercepted and the
           arguments and return values being analysed it
           obviously adds a performance overhead.  Furthermore it
           is using considerable amounts of memory keeping track
           of the object memory details.  Expect performance to
           be at least 3 times as slow depending on your platform
           and size of program.

           Note also that the output files can be huge.

       o   Tied hashes produce confusing results.

       o   ObjectTracker has been tested on perl 5.6.1 and 5.5005
           on SGI Irix and Win32 (using SiePerl)

       See also BUGS below

FUNCTIONS
       output_details()

       This subroutine outputs details on the currently existing
       objects.  It creates files in the current directory named
       (by default) ObjectTracker_details_1.txt,
       ObjectTracker_details_2.txt, etc.  according to the
       current session number.  This function increments the
       session number after each call (via increment_session)

       This should be called at suitable points in your program
       and the resultant files can be checked to see if there are
       any objects which shouldn't still be in existence.  It
       will show the date/time, session ID and the call stack
       when the object was created.

       increment_session()

       This can be used to independently increment the session ID
       which is used to record details in the main log file and
       name the output_details files.

FILE FORMATS
       The output file formats are designed to be used in a
       spreadsheet.  By default they have a single header line
       followed by data with values are separated by tab (\t)
       with a single newline (\n) at the end of each line.

       ObjectTracker.log

       This file logs the details of object creation and
       destruction. The fields are as follows:

       ObjectNo
           The sequence number of the object (starts at 1).  Only
           set for new objects where Source ne DES.

       DateTime
           The local date/time the object is first seen or
           destroyed.

       Session
           current session number (starts at 1)

       Sub The subroutine called.

           Will be set to NO_DESTRUCTOR if the test program has
           no destructor for the object concerned.

       Source
           Where the object is seen as follows:

             Ret = first seen returned from a sub.
             Arg = first seen as an arg.
             DES = the sub is a destructor.

           See also Exists as objects can sometimes be seen when
           called from within destructors

       Position
           The argument or return value position (1=first)

       Class
           Object Class or HASH, ARRAY or GLOB

       Ref The memory address of the object.

       Exists
           Object existance info as follows:

       Y        the object/ref has been seen before. Only applies
                to Source=DES

       N        the object/ref has not been seen before. Only
                applies to Source=DES

       de       the call stack contains a destructor subroutine
                (sub =~  /DESTROY$/)

       Stack
           The current call stack.  See OPTIONS for content.

       CrDateTime
           The local date/time the object was first seen. Only
           output where Source=DES.

       CrDateTime
           The datetime when object first seen. Only output where
           Source=DES.

       CrSession
           The session when object first seen. Only output where
           Source=DES.

       CrStack\n
           The call stack when object first seen. Only output
           where Source=DES.

       ObjectTracker_details_<NN>.txt

       This file is produced on demand by the subroutine
       Devel::ObjectTracker::output_details.  In the file name
       <NN> is replaced by the current session number which
       starts at 1.

       The fields are as follows, see desciptions under
       ObjectTracker.log for full details:

       CrObjectNo
           The creation number of the object.

       CrDateTime
           The local date/time the object was first seen.

       CrSession
           Session number when object first seen.

       CrSub
           Subroutine name called when object first seen.

       CrSource
           The source when object first seen.

       Position
           The argument or return value position when object
           first seen.

       CrClass
           Object Class when object first seen.

       CrRef
           The memory address of the object when first seen.

       CrStack
           Call stack when object first seen.

INSTALLATION
       The usual:

             perl Makefile.PL
             make
             make test
             make install

       Should install fine via the CPAN module.

BUGS
       See also NOTES above

       Probably many. Certainly early versions purported to show
       objects in existence when they did'nt (and vice-versa)
       although I think it is more accurate now. You need to
       validate the results yourself to be sure.

       If the sub matches /DESTROY$/ it assumes the first
       argument is the object being destroyed.

       There is no record kept of whether memory references are
       reused. It is possible that refs/objects are seen again in
       subroutines called from within a destructor. To help
       overcome this the field Exists contains de if a destructor
       is seen in the call stack.

       Occasionally it produces 'Attempt to free unreferenced
       scalar' messages but these seem benign.

COPYRIGHT
       etc. etc.

AUTHOR
       John Clutterbuck, [EMAIL PROTECTED]

SEE ALSO
       perl(1).

       perldoc perldebug.


---
John Clutterbuck
Siemens Business Services, UK

Reply via email to