From 6061ec2039f13f53e1483b78e8e3e21c9b44df35 Mon Sep 17 00:00:00 2001 From: ericm Date: Thu, 27 Apr 2000 01:46:58 +0000 Subject: * doc/memory.n: Man page for Tcl "memory" command, which is created when TCL_MEM_DEBUG is defined at compile time. * doc/TCL_MEM_DEBUG.3: Man page with overall information about TCL_MEM_DEBUG usage. * doc/DumpActiveMemory.3: Man page for Tcl_DumpActiveMemory, Tcl_InitMemory, and Tcl_ValidateAllMemory [Bug: 1816, 1835]. * generic/tclCkalloc.c: Fixed some function headers. * unix/mkLinks: Regen'd with new mkLinks.tcl. * unix/mkLinks.tcl: Fixed indentation, made link setup more intelligent (only do one existance test per man page, instead of one per function). --- ChangeLog | 24 +++++++++++++++ doc/DumpActiveMemory.3 | 68 +++++++++++++++++++++++++++++++++++++++++ doc/TCL_MEM_DEBUG.3 | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ doc/memory.n | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclCkalloc.c | 77 +++++++++++++++++++++++++++++++++-------------- unix/mkLinks | 8 +++++ 6 files changed, 318 insertions(+), 22 deletions(-) create mode 100644 doc/DumpActiveMemory.3 create mode 100644 doc/TCL_MEM_DEBUG.3 create mode 100644 doc/memory.n diff --git a/ChangeLog b/ChangeLog index 7ee758a..0d1a365 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2000-04-26 Eric Melski + + * doc/memory.n: Man page for Tcl "memory" command, which is + created when TCL_MEM_DEBUG is defined at compile time. + + * doc/TCL_MEM_DEBUG.3: Man page with overall information about + TCL_MEM_DEBUG usage. + + * doc/DumpActiveMemory.3: Man page for Tcl_DumpActiveMemory, + Tcl_InitMemory, and Tcl_ValidateAllMemory [Bug: 1816, 1835]. + + * generic/tclCkalloc.c: Fixed some function headers. + + * unix/mkLinks: Regen'd with new mkLinks.tcl. + + * unix/mkLinks.tcl: Fixed indentation, made link setup more + intelligent (only do one existance test per man page, instead of + one per function). + + * doc/library.n: Fixed .SH NAME macro to include each function + documented on the page, so that mkLinks will know about the + functions listed there, and so that the Windows help file index + will get set up correctly [Bug: 1898, 5273]. + 2000-04-26 Jeff Hobbs 8.3.1 RELEASE diff --git a/doc/DumpActiveMemory.3 b/doc/DumpActiveMemory.3 new file mode 100644 index 0000000..ab2a766 --- /dev/null +++ b/doc/DumpActiveMemory.3 @@ -0,0 +1,68 @@ +'\" +'\" Copyright (c) 1992-1999 Karl Lehenbauer and Mark Diekhans. +'\" Copyright (c) 2000 by Scriptics Corporation. +'\" All rights reserved. +'\" +'\" RCS: @(#) $Id: DumpActiveMemory.3,v 1.1 2000/04/27 01:46:59 ericm Exp $ +'\" +.so man.macros +.TH "Tcl_DumpActiveMemory" 3 8.1 Tcl "Tcl Library Procedures" +.BS +.SH NAME +Tcl_DumpActiveMemory, Tcl_InitMemory, Tcl_ValidateAllMemory \- Validated memory allocation interface. +.SH SYNOPSIS +.nf +\fB#include \fR +.sp +int +\fBTcl_DumpActiveMemory\fR(\fIfileName\fR) +.sp +void +\fBTcl_InitMemory\fR(\fIinterp\fR) +.sp +void +\fBTcl_ValidateAllMemory\fR(\fIfileName, line\fR) + +.SH ARGUMENTS +.AP Tcl_Interp *interp in +Tcl interpreter in which to add commands. +.AP char *fileName in +For \fBTcl_DumpActiveMemory\fR, name of the file to which memory +information will be written. For \fBTcl_ValidateAllMemory\fR, name of +the file from which the call is being made (normally \fB__FILE__\fR). +.AP int line in +Line number at which the call to \fBTcl_ValidateAllMemory\fR is made +(normally \fB__LINE__\fR). +.BE + +.SH DESCRIPTION +These functions provide access to Tcl memory debugging information. +They are only available when Tcl has been compiled with +\fBTCL_MEM_DEBUG\fR defined at compile-time. +.PP +\fBTcl_DumpActiveMemory\fR will output a list of all currently +allocated memory to the specified file. The information output for +each allocated block of memory is: starting and ending addresses +(excluding guard zone), size, source file where \fBckalloc\fR was +called to allocate the block and line number in that file. It is +especially useful to call \fBTcl_DumpActiveMemory\fR after the Tcl +interpreter has been deleted. +.PP +\fBTcl_InitMemory\fR adds the Tcl \fBmemory\fR command to the +interpreter given by \fIinterp\fR. It is called by \fBTcl_Main\fR +when Tcl has been compiled with \fBTCL_MEM_DEBUG\fR defined. +.PP +\fBTcl_ValidateAllMemory\fR forces a validation of the guard zones of +all currently allocated blocks of memory. Normally validation of a +block occurs when its freed, unless full validation is enabled, in +which case validation of all blocks occurs when \fBckalloc\fR and +\fBckfree\fR are called. This function forces the validation to occur +at any point. + +.SH SEE ALSO +TCL_MEM_DEBUG, memory + +.SH KEYWORDS +memory, debug + + diff --git a/doc/TCL_MEM_DEBUG.3 b/doc/TCL_MEM_DEBUG.3 new file mode 100644 index 0000000..bf6e2fe --- /dev/null +++ b/doc/TCL_MEM_DEBUG.3 @@ -0,0 +1,81 @@ +'\" +'\" Copyright (c) 1992-1999 Karl Lehenbauer and Mark Diekhans. +'\" Copyright (c) 2000 by Scriptics Corporation. +'\" All rights reserved. +'\" +'\" RCS: @(#) $Id: TCL_MEM_DEBUG.3,v 1.1 2000/04/27 01:46:59 ericm Exp $ +'\" +.so man.macros +.TH TCL_MEM_DEBUG 3 8.1 Tcl "Tcl Library Procedures" +.BS +.SH NAME +TCL_MEM_DEBUG \- Compile-time flag to enable Tcl memory debugging. + +.SH DESCRIPTION +When Tcl is compiled with \fBTCL_MEM_DEBUG\fR defined, a powerful set +of memory debugging aids are included in the compiled binary. This +includes C and Tcl functions which can aid with debugging +memory leaks, memory allocation overruns, and other memory related +errors. + +.SH ENABLING MEMORY DEBUGGING +.PP +To enable memory debugging, Tcl should be recompiled from scratch with +\fBTCL_MEM_DEBUG\fR defined. This will also compile in a non-stub +version of \fBTcl_InitMemory\fR to add the \fBmemory\fR command to Tcl. +.PP +\fBTCL_MEM_DEBUG\fR must be either left defined for all modules or undefined +for all modules that are going to be linked together. If they are not, link +errors will occur, with either \fBTclDbCkfree\fR and \fBTcl_DbCkalloc\fR or +\fBTcl_Ckalloc\fR and \fBTcl_Ckfree\fR being undefined. +.PP +Once memory debugging support has been compiled into Tcl, the C +functions \fBTcl_ValidateAllMemory\fR, and \fBTcl_DumpActiveMemory\fR, +and the Tcl \fBmemory\fR command can be used to validate and examine +memory usage. + +.SH GUARD ZONES +.PP +When memory debugging is enabled, whenever a call to \fBckalloc\fR is +made, slightly more memory than requested is allocated so the memory debugging +code can keep track of the allocated memory, and eight-byte ``guard +zones'' are placed in front of and behind the space that will be +returned to the caller. (The size of the guard zone is defined by the +C #define \fBGUARD_SIZE\fR in \fIbaseline/src/ckalloc.c\fR -- it can +be extended if you suspect large overwrite problems, at some cost in +performance.) A known pattern is written into the guard zones and, on +a call to \fBckfree\fR, the guard zones of the space being freed are +checked to see if either zone has been modified in any way. If one +has been, the guard bytes and their new contents are identified, and a +``low guard failed'' or ``high guard failed'' message is issued. The +``guard failed'' message includes the address of the memory packet and +the file name and line number of the code that called \fBckfree\fR. +This allows you to detect the common sorts of one-off problems, where +not enough space was allocated to contain the data written, for +example. + +.SH DEBUGGING DIFFICULT MEMORY CORRUPTION PROBLEMS +.PP +Normally, Tcl compiled with memory debugging enabled will make it easy +to isolate a corruption problem. Turning on memory validation with +the memory command can help isolate difficult problems. If you +suspect (or know) that corruption is occurring before the Tcl +interpreter comes up far enough for you to issue commands, you can set +\fBMEM_VALIDATE\fR define, recompile tclCkalloc.c and rebuild Tcl. +This will enable memory validation from the first call to +\fBckalloc\fR, again, at a large performance impact. +.PP +If you are desperate and validating memory on every call to +\fBckalloc\fR and \fBckfree\fR isn't enough, you can explicitly call +\fBTcl_ValidateAllMemory\fR directly at any point. It takes a \fIchar +*\fR and an \fIint\fR which are normally the filename and line number +of the caller, but they can actually be anything you want. Remember +to remove the calls after you find the problem. + +.SH SEE ALSO +memory, Tcl_ValidateAllMemory, Tcl_DumpActiveMemory + +.SH KEYWORDS +memory, debug + + diff --git a/doc/memory.n b/doc/memory.n new file mode 100644 index 0000000..4815ec4 --- /dev/null +++ b/doc/memory.n @@ -0,0 +1,82 @@ +'\" +'\" Copyright (c) 1992-1999 by Karl Lehenbauer and Mark Diekhans +'\" Copyright (c) 2000 by Scriptics Corporation. +'\" All rights reserved. +'\" +'\" RCS: @(#) $Id: memory.n,v 1.1 2000/04/27 01:47:00 ericm Exp $ +'\" +.so man.macros +.TH memory n 8.1 Tcl "Tcl Built-In Commands" +.BS +.SH NAME +memory \- Control Tcl memory debugging capabilities. +.SH SYNOPSIS +\fBmemory \fIoption \fR?\fIarg arg ...\fR? + +.SH DESCRIPTION +.PP +The \fBmemory\fR command gives the Tcl developer control of Tcl's memory +debugging capabilities. The memory command has several suboptions, which are +described below. It is only available when Tcl has been compiled with +memory debugging enabled (when \fBTCL_MEM_DEBUG\fR is defined at +compile time). +.TP +\fBmemory info\fR +Produces a report containing the total allocations and frees since +Tcl began, the current packets allocated (the current +number of calls to \fBckalloc\fR not met by a corresponding call +to \fBckfree\fR), the current bytes allocated, and the maximum number +of packets and bytes allocated. +.TP +\fBmemory trace [on|off]\fR +.br +Turns memory tracing on or off. When memory tracing is on, every call +to \fBckalloc\fR causes a line of trace information to be written to +\fIstderr\fR, consisting of the word \fIckalloc\fR, followed by the +address returned, the amount of memory allocated, and the C filename +and line number of the code performing the allocation. For example: +.CS +ckalloc 40e478 98 tclProc.c 1406 +.CE +Calls to \fBckfree\fR are traced in the same manner. +.TP +\fBmemory validate [on|off]\fR +Turns memory validation on or off. When memory validation is enabled, +on every call to \fBckalloc\fR or \fBckfree\fR, the guard zones are +checked for every piece of memory currently in existence that was +allocated by \fBckalloc\fR. This has a large performance impact and +should only be used when overwrite problems are strongly suspected. +The advantage of enabling memory validation is that a guard zone +overwrite can be detected on the first call to \fBckalloc\fR or +\fBckfree\fR after the overwrite occurred, rather than when the +specific memory with the overwritten guard zone(s) is freed, which may +occur long after the overwrite occurred. +.TP +\fBmemory trace_on_at_malloc\fR \fIcount\fR +Enable memory tracing after \fIcount\fR \fBckalloc\fR's have been performed. +For example, if you enter \fBmemory trace_on_at_malloc 100\fR, +after the 100th call to \fBckalloc\fR, memory trace information will begin +being displayed for all allocations and frees. Since there can be a lot +of memory activity before a problem occurs, judicious use of this option +can reduce the slowdown caused by tracing (and the amount of trace information +produced), if you can identify a number of allocations that occur before +the problem sets in. The current number of memory allocations that have +occurred since Tcl started is printed on a guard zone failure. +.TP +\fBmemory break_on_malloc\fR \fIcount\fR +After the \fBcount\fR allocations have been performed, \fBckalloc\fR's +output a message to this effect and that it is now attempting to enter +the C debugger. Tcl will then issue a \fISIGINT\fR signal against itself. +If you are running Tcl under a C debugger, it should then enter the debugger +command mode. +.TP +\fB memory display\fR \fIfile\fR +Write a list of all currently allocated memory to the specified file. + +.SH SEE ALSO +ckalloc, ckfree, Tcl_ValidateAllMemory, Tcl_DumpActiveMemory, TCL_MEM_DEBUG + +.SH KEYWORDS +memory, debug + + diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c index a12f0cd..a85a0fd 100644 --- a/generic/tclCkalloc.c +++ b/generic/tclCkalloc.c @@ -13,7 +13,7 @@ * * This code contributed by Karl Lehenbauer and Mark Diekhans * - * RCS: @(#) $Id: tclCkalloc.c,v 1.7 1999/11/19 06:34:23 hobbs Exp $ + * RCS: @(#) $Id: tclCkalloc.c,v 1.8 2000/04/27 01:47:01 ericm Exp $ */ #include "tclInt.h" @@ -179,20 +179,34 @@ TclDumpMemoryInfo(outFile) maximum_bytes_malloced); } + /* *---------------------------------------------------------------------- * * ValidateMemory -- - * Procedure to validate allocted memory guard zones. + * + * Validate memory guard zones for a particular chunk of allocated + * memory. + * + * Results: + * None. + * + * Side effects: + * Prints validation information about the allocated memory to stderr. * *---------------------------------------------------------------------- */ + static void ValidateMemory(memHeaderP, file, line, nukeGuards) - struct mem_header *memHeaderP; - char *file; - int line; - int nukeGuards; + struct mem_header *memHeaderP; /* Memory chunk to validate */ + char *file; /* File containing the call to + * Tcl_ValidateAllMemory */ + int line; /* Line number of call to + * Tcl_ValidateAllMemory */ + int nukeGuards; /* If non-zero, indicates that the + * memory guards are to be reset to 0 + * after they have been printed */ { unsigned char *hiPtr; int idx; @@ -253,14 +267,21 @@ ValidateMemory(memHeaderP, file, line, nukeGuards) *---------------------------------------------------------------------- * * Tcl_ValidateAllMemory -- - * Validates guard regions for all allocated memory. + * + * Validate memory guard regions for all allocated memory. + * + * Results: + * None. + * + * Side effects: + * Displays memory validation information to stderr. * *---------------------------------------------------------------------- */ void Tcl_ValidateAllMemory (file, line) - char *file; - int line; + char *file; /* File from which Tcl_ValidateAllMemory was called */ + int line; /* Line number of call to Tcl_ValidateAllMemory */ { struct mem_header *memScanP; @@ -278,16 +299,18 @@ Tcl_ValidateAllMemory (file, line) *---------------------------------------------------------------------- * * Tcl_DumpActiveMemory -- - * Displays all allocated memory to stderr. + * + * Displays all allocated memory to a file; if no filename is given, + * information will be written to stderr. * * Results: - * Return TCL_ERROR if an error accessing the file occures, `errno' - * will have the file error number left in it. + * Return TCL_ERROR if an error accessing the file occures, `errno' + * will have the file error number left in it. *---------------------------------------------------------------------- */ int Tcl_DumpActiveMemory (fileName) - char *fileName; + char *fileName; /* Name of the file to write info to */ { FILE *fileP; struct mem_header *memScanP; @@ -597,13 +620,14 @@ Tcl_Realloc(ptr, size) *---------------------------------------------------------------------- * * MemoryCmd -- - * Implements the TCL memory command: - * memory info - * memory display - * break_on_malloc count - * trace_on_at_malloc count - * trace on|off - * validate on|off + * Implements the Tcl "memory" command, which provides Tcl-level + * control of Tcl memory debugging information. + * memory info + * memory display + * memory break_on_malloc count + * memory trace_on_at_malloc count + * memory trace on|off + * memory validate on|off * * Results: * Standard TCL results. @@ -769,13 +793,22 @@ CheckmemCmd(clientData, interp, argc, argv) *---------------------------------------------------------------------- * * Tcl_InitMemory -- - * Initialize the memory command. + * + * Create the "memory" and "checkmem" commands in the given + * interpreter. + * + * Results: + * None. + * + * Side effects: + * New commands are added to the interpreter. * *---------------------------------------------------------------------- */ + void Tcl_InitMemory(interp) - Tcl_Interp *interp; + Tcl_Interp *interp; /* Interpreter in which commands should be added */ { TclInitDbCkalloc(); Tcl_CreateCommand (interp, "memory", MemoryCmd, (ClientData) NULL, diff --git a/unix/mkLinks b/unix/mkLinks index 050851e..86e9609 100644 --- a/unix/mkLinks +++ b/unix/mkLinks @@ -286,6 +286,14 @@ if test -r DoubleObj.3; then ln DoubleObj.3 Tcl_SetDoubleObj.3 ln DoubleObj.3 Tcl_GetDoubleFromObj.3 fi +if test -r DumpActiveMemory.3; then + rm -f Tcl_DumpActiveMemory.3 + rm -f Tcl_InitMemory.3 + rm -f Tcl_ValidateAllMemory.3 + ln DumpActiveMemory.3 Tcl_DumpActiveMemory.3 + ln DumpActiveMemory.3 Tcl_InitMemory.3 + ln DumpActiveMemory.3 Tcl_ValidateAllMemory.3 +fi if test -r Encoding.3; then rm -f Tcl_GetEncoding.3 rm -f Tcl_FreeEncoding.3 -- cgit v0.12