Tcl Source Code

View Ticket
Login
Ticket UUID: 3493120
Title: Thread extension, memory leak after thread exit
Type: Bug Version: all
Submitter: sebres Created on: 2012-02-24 13:33:32
Subsystem: 49. Threading Assigned To: sebres
Priority: 7 High Severity: Minor
Status: Closed Last Modified: 2014-04-23 18:26:14
Resolution: Fixed Closed By: dgp
    Closed on: 2014-04-23 18:26:14
Description:
Version: 8.5.11 (original and current core-8-5-branch)
Platform: Windows (linux not yet tested)

After exiting of threads, they leave a memory leak. 
Consequence of that: we cannot use techniques such as 'idletime' (to release some system resources, for example large tcl codes are no more used, etc, etc.).

After run of following script I have lost 100MB of memory. In fact, nothing will be done here, except threads are created and exited.

Test script:

puts [thread::names]
time {
  thread::create {::thread::release}
} 500
puts [thread::names]
User Comments: dgp added on 2014-04-23 18:26:14:
That solved it.  Thanks!

Merging now...

sebres added on 2014-04-23 09:19:41:
*nix segfault cleared: we should reset a thread key after freeing of alloc cache (in tclUnixThrd.c);
Fixed within [1dc6ea5ab2];

@Don: could you please test it on CentOS and OSX.

dgp added on 2014-04-22 20:02:29:
Same troubles on Mavericks OSX.

Just try to run the test suite on a

./configure --disable-shared --enable-threads --enable-symbols

build.

dgp added on 2014-04-22 20:02:23:
Same troubles on Mavericks OSX.

Just try to run the test suite on a

./configure --disable-shared --enable-threads --enable-symbols

build.

sebres added on 2014-04-22 17:44:30:

I can't test CentOS right now, but it work on all my linux systems, for ex.: debian / kernel 3.13.0-23-generic. I think, possible in tclUnixThrd.c TclpFreeAllocCache may miss a something like "pthread_setspecific(key, NULL);" after call of "TclFreeAllocCache(ptr);" (in comparison to tclWinThrd.c). But [c251d61424] alone, without this, works fine on my linux mashines.

void
TclpFreeAllocCache(
    void *ptr)
{
    if (ptr != NULL) {
	/*
	 * Called by the pthread lib when a thread exits
	 */

	TclFreeAllocCache(ptr);
	pthread_setspecific(key, NULL);

    } else if (initialized) {
	/*
	 * Called by us in TclFinalizeThreadAlloc() during the library
	 * finalization initiated from Tcl_Finalize()
	 */

	pthread_key_delete(key);
	initialized = 0;
    }
}
@Don: could you tell me please where exactly you have segfaulting on centos (some tcl-tests? or something else?), because I can't reproduce it on my linux systems.


sebres added on 2014-04-22 13:38:00:
Reviews and tests are welcome

sebres added on 2014-04-22 13:28:58:
Leak found and fixed within [c251d61424]
TclpFreeAllocCache (if called with ptr != NULL) has a comment: "Called by us in TclpFinalizeThreadData when a thread exits ..."
But until now it was really never called.
After fixing, no byte is lost during test.

sebres added on 2012-02-28 17:52:37:
much short variant of leak test :

puts [thread::names]
time {
  thread::create {::thread::release}
} 500
puts [thread::names]

sebres added on 2012-02-28 17:29:55:
It seems to be a problem with tcl core (threaded memory subsystem etc.) - I made a test without thread.dll, where I create threads with WinAPI, call inits and hereafter finalize - leak remains.

Following singlethreaded script runs without leak also:

time {
  try {
    set ntp [interp create]
    $ntp eval "load thread27"
  } finally {
    interp delete $ntp
  }
} 500

sebres added on 2012-02-24 20:40:05:
tested with thread2.6.5, thread2.6.7 and current thread-2-7-branch