From 293dbdc050e3bd444292641282727a0bd24eef27 Mon Sep 17 00:00:00 2001 From: hobbs Date: Thu, 28 Jun 2001 01:22:21 +0000 Subject: * generic/tclInt.h: * generic/tclObj.c: * unix/Makefile.in: added a -DPURIFY mode that makes Tcl_Obj's allocated and free singularly (instead of in alloc in blocks and never free) to allow checkers like Purify to operate better. --- ChangeLog | 19 +++++++++++++++++++ generic/tclInt.h | 33 ++++++++++++++++++++++++++++++++- generic/tclObj.c | 15 +++++++++++++-- unix/Makefile.in | 4 ++-- 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 148926a..20ab5f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,24 @@ 2001-06-27 Jeff Hobbs + * generic/tclInt.h: + * generic/tclObj.c: + * unix/Makefile.in: added a -DPURIFY mode that makes Tcl_Obj's + allocated and free singularly (instead of in alloc in blocks and + never free) to allow checkers like Purify to operate better. + + * library/encoding/koi8-u.enc: added koi8-u (Ukranian variant) + encoding. + + * tests/subst.test: + * generic/tclUtf.c (Tcl_UtfBackslash): Corrected backslash + handling of multibyte utf-8 chars. [Bug #217987] + + * generic/tclCmdIL.c (InfoProcsCmd): fixed potential mem leak in + info procs that created objects without using them. + + * generic/tclCompCmds.c (TclCompileStringCmd): fixed mem leak when + string command failed to parse the subcommand. + * doc/interp.n: * doc/unknown.n: updated notes about what is in a safe interp. [Bug #218605] diff --git a/generic/tclInt.h b/generic/tclInt.h index 7af3c65..2ee93d0 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclInt.h,v 1.56 2001/06/17 03:48:19 dgp Exp $ + * RCS: @(#) $Id: tclInt.h,v 1.57 2001/06/28 01:22:21 hobbs Exp $ */ #ifndef _TCLINT @@ -2183,6 +2183,37 @@ EXTERN int TclCompileWhileCmd _ANSI_ARGS_((Tcl_Interp *interp, TclIncrObjsFreed(); \ } +#elif defined(PURIFY) + +/* + * The PURIFY mode is like the regular mode, but instead of doing block + * Tcl_Obj allocation and keeping a freed list for efficiency, it always + * allocates and frees a single Tcl_Obj so that tools like Purify can + * better track memory leaks + */ + +# define TclNewObj(objPtr) \ + (objPtr) = (Tcl_Obj *) Tcl_Ckalloc(sizeof(Tcl_Obj)); \ + (objPtr)->refCount = 0; \ + (objPtr)->bytes = tclEmptyStringRep; \ + (objPtr)->length = 0; \ + (objPtr)->typePtr = NULL; \ + TclIncrObjsAllocated(); + +# define TclDecrRefCount(objPtr) \ + if (--(objPtr)->refCount <= 0) { \ + if (((objPtr)->bytes != NULL) \ + && ((objPtr)->bytes != tclEmptyStringRep)) { \ + ckfree((char *) (objPtr)->bytes); \ + } \ + if (((objPtr)->typePtr != NULL) \ + && ((objPtr)->typePtr->freeIntRepProc != NULL)) { \ + (objPtr)->typePtr->freeIntRepProc(objPtr); \ + } \ + ckfree((char *) (objPtr)); \ + TclIncrObjsFreed(); \ + } + #else /* not TCL_MEM_DEBUG */ #ifdef TCL_THREADS diff --git a/generic/tclObj.c b/generic/tclObj.c index 21a4caf..09d9428 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclObj.c,v 1.22 2001/05/26 01:25:59 msofer Exp $ + * RCS: @(#) $Id: tclObj.c,v 1.23 2001/06/28 01:22:21 hobbs Exp $ */ #include "tclInt.h" @@ -435,11 +435,15 @@ Tcl_NewObj() */ Tcl_MutexLock(&tclObjMutex); +#ifdef PURIFY + objPtr = (Tcl_Obj *) Tcl_Ckalloc(sizeof(Tcl_Obj)); +#else if (tclFreeObjList == NULL) { TclAllocateFreeObjects(); } objPtr = tclFreeObjList; tclFreeObjList = (Tcl_Obj *) tclFreeObjList->internalRep.otherValuePtr; +#endif objPtr->refCount = 0; objPtr->bytes = tclEmptyStringRep; objPtr->length = 0; @@ -553,6 +557,13 @@ TclAllocateFreeObjects() register Tcl_Obj *prevPtr, *objPtr; register int i; + /* + * This has been noted by Purify to be a potential leak. The problem is + * that Tcl, when not TCL_MEM_DEBUG compiled, keeps around all allocated + * Tcl_Obj's, pointed to by tclFreeObjList, when freed instead of + * actually freeing the memory. These never do get freed properly. + */ + basePtr = (char *) ckalloc(bytesToAlloc); memset(basePtr, 0, bytesToAlloc); @@ -616,7 +627,7 @@ TclFreeObj(objPtr) */ Tcl_MutexLock(&tclObjMutex); -#ifdef TCL_MEM_DEBUG +#if defined(TCL_MEM_DEBUG) || defined(PURIFY) ckfree((char *) objPtr); #else objPtr->internalRep.otherValuePtr = (VOID *) tclFreeObjList; diff --git a/unix/Makefile.in b/unix/Makefile.in index 794a265..41c5b08 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -5,7 +5,7 @@ # "autoconf" program (constructs like "@foo@" will get replaced in the # actual Makefile. # -# RCS: @(#) $Id: Makefile.in,v 1.78 2001/06/27 01:53:18 mdejong Exp $ +# RCS: @(#) $Id: Makefile.in,v 1.79 2001/06/28 01:22:21 hobbs Exp $ VERSION = @TCL_VERSION@ @@ -230,8 +230,8 @@ DLTEST_DIR = @TCL_SRC_DIR@/unix/dltest # Must be absolute to so the corresponding tcltest's tcl_library is absolute. TCL_BUILDTIME_LIBRARY = @TCL_SRC_DIR@/library -#CC = purify -best-effort @CC@ CC = @CC@ +#CC = purify -best-effort @CC@ -DPURIFY #---------------------------------------------------------------- # The information below should be usable as is. The configure -- cgit v0.12