Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - Memory release issue after pthread_detach and pthread_cancel: (23 Items)
   
Memory release issue after pthread_detach and pthread_cancel  
Hi,

I am trying to create a thread in 'main' process. This thread allocates about 100K memory, sleeps for few seconds and 
then releases the memory. 3 such threads are created by the parent process.
After creating each thread parent process sleeps for some time and calls pthread_detach() and pthread_cancel() on 
particular 'tid'.
When I do 'pidin m' for that process, I could see the memory of parent process goes on increasing. with each thread 
create the parent process starts with new memory offset(actual + allocated). i.e when thread finishes it does not 
liberate the complete memory and parent process does not return to it's original value

The logs says that;
parent process starts with about 36K, and after finishing all the threads it ends up acquiring 456K.

pthread_detach() synopsis says '"When a detached thread terminates, all system resources allocated to that thread are 
immediately reclaimed."

OS should destroy all the thread stack once its function is done and is cancelled(also pidin dosen't show that thread).

from where this memory is getting accumulated in parent process? OR is there any other way to clean up the thread stack?
??

Here is the sample program;

#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/resource.h>

static void* cliente(void *datos)
{
	while(true)
	{
		//Allocating dummy memory of about 100K
		char *buff= new char[100000];
		sleep(20);
		//releasing memory
		delete [] buff;
		buff=NULL;
	}
}

int main()
{
    int ret1;
    ret1=0;
    pthread_t mythread[4];

   while(ret1 < 3)
   {
	   //create thread
	   if(!pthread_create((pthread_t *)&mythread[ret1],NULL,cliente,NULL))
	   {
	   	perror("pthread_create");
	   }
	   //dummy sleep
	   sleep(60);
	    //detach the thread
	   int ret = pthread_detach((pthread_t)mythread[ret1]);
	    if(EOK == ret)
	    {
	    	printf("Thread %d got detached\n",mythread[ret1]);
	    	fflush(stdout);
	    }
	    //cancel the thread
	    int iRet = pthread_cancel((pthread_t)mythread[ret1]);  
	    if(EOK == iRet)
	    {
	    	printf("Thread %d got cancelled\n",mythread[ret1]);
	    	fflush(stdout);
	    }   
	    mythread[ret1] = NULL;
	    ret1++;
   }
   while(true)
   {
   }          
return EXIT_SUCCESS;
}




Attachment: Text Threading.cc 1.16 KB
RE: Memory release issue after pthread_detach and pthread_cancel  
What verion of the OS are you using. With 6.3.2 the heap can only grow it never shrinks.  On 6.4.X the heap can shrink 
and the memory is return to the OS.  Check the documentation.

-----Original Message-----
From: kuldeep paranjpe [mailto:community-noreply@qnx.com] 
Sent: Wednesday, July 15, 2009 8:45 AM
To: ostech-core_os
Subject: Memory release issue after pthread_detach and pthread_cancel

Hi,

I am trying to create a thread in 'main' process. This thread allocates about 100K memory, sleeps for few seconds and 
then releases the memory. 3 such threads are created by the parent process.
After creating each thread parent process sleeps for some time and calls pthread_detach() and pthread_cancel() on 
particular 'tid'.
When I do 'pidin m' for that process, I could see the memory of parent process goes on increasing. with each thread 
create the parent process starts with new memory offset(actual + allocated). i.e when thread finishes it does not 
liberate the complete memory and parent process does not return to it's original value

The logs says that;
parent process starts with about 36K, and after finishing all the threads it ends up acquiring 456K.

pthread_detach() synopsis says '"When a detached thread terminates, all system resources allocated to that thread are 
immediately reclaimed."

OS should destroy all the thread stack once its function is done and is cancelled(also pidin dosen't show that thread).

from where this memory is getting accumulated in parent process? OR is there any other way to clean up the thread stack?
??

Here is the sample program;

#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/resource.h>

static void* cliente(void *datos)
{
	while(true)
	{
		//Allocating dummy memory of about 100K
		char *buff= new char[100000];
		sleep(20);
		//releasing memory
		delete [] buff;
		buff=NULL;
	}
}

int main()
{
    int ret1;
    ret1=0;
    pthread_t mythread[4];

   while(ret1 < 3)
   {
	   //create thread
	   if(!pthread_create((pthread_t *)&mythread[ret1],NULL,cliente,NULL))
	   {
	   	perror("pthread_create");
	   }
	   //dummy sleep
	   sleep(60);
	    //detach the thread
	   int ret = pthread_detach((pthread_t)mythread[ret1]);
	    if(EOK == ret)
	    {
	    	printf("Thread %d got detached\n",mythread[ret1]);
	    	fflush(stdout);
	    }
	    //cancel the thread
	    int iRet = pthread_cancel((pthread_t)mythread[ret1]);  
	    if(EOK == iRet)
	    {
	    	printf("Thread %d got cancelled\n",mythread[ret1]);
	    	fflush(stdout);
	    }   
	    mythread[ret1] = NULL;
	    ret1++;
   }
   while(true)
   {
   }          
return EXIT_SUCCESS;
}






_______________________________________________
OSTech
http://community.qnx.com/sf/go/post33805
Re: Memory release issue after pthread_detach and pthread_cancel  
"System resources" that suppose to be deallocated does not include heap 
memory since memory heap is managed separately.
If objects are properly deleted heap memory can be reclaimed for re-use. 
Total heap may not shrink though especially if it is heavily fragmented 
(and depends on OS version).

kuldeep paranjpe wrote:
> Hi,
>
> I am trying to create a thread in 'main' process. This thread allocates about 100K memory, sleeps for few seconds and 
then releases the memory. 3 such threads are created by the parent process.
> After creating each thread parent process sleeps for some time and calls pthread_detach() and pthread_cancel() on 
particular 'tid'.
> When I do 'pidin m' for that process, I could see the memory of parent process goes on increasing. with each thread 
create the parent process starts with new memory offset(actual + allocated). i.e when thread finishes it does not 
liberate the complete memory and parent process does not return to it's original value
>
> The logs says that;
> parent process starts with about 36K, and after finishing all the threads it ends up acquiring 456K.
>
> pthread_detach() synopsis says '"When a detached thread terminates, all system resources allocated to that thread are 
immediately reclaimed."
>
> OS should destroy all the thread stack once its function is done and is cancelled(also pidin dosen't show that thread)
.
>
> from where this memory is getting accumulated in parent process? OR is there any other way to clean up the thread 
stack???
>
> Here is the sample program;
>
> #include <cstdlib>
> #include <iostream>
> #include <stdio.h>
> #include <pthread.h>
> #include <errno.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <sys/resource.h>
>
> static void* cliente(void *datos)
> {
> 	while(true)
> 	{
> 		//Allocating dummy memory of about 100K
> 		char *buff= new char[100000];
> 		sleep(20);
> 		//releasing memory
> 		delete [] buff;
> 		buff=NULL;
> 	}
> }
>
> int main()
> {
>     int ret1;
>     ret1=0;
>     pthread_t mythread[4];
>
>    while(ret1 < 3)
>    {
> 	   //create thread
> 	   if(!pthread_create((pthread_t *)&mythread[ret1],NULL,cliente,NULL))
> 	   {
> 	   	perror("pthread_create");
> 	   }
> 	   //dummy sleep
> 	   sleep(60);
> 	    //detach the thread
> 	   int ret = pthread_detach((pthread_t)mythread[ret1]);
> 	    if(EOK == ret)
> 	    {
> 	    	printf("Thread %d got detached\n",mythread[ret1]);
> 	    	fflush(stdout);
> 	    }
> 	    //cancel the thread
> 	    int iRet = pthread_cancel((pthread_t)mythread[ret1]);  
> 	    if(EOK == iRet)
> 	    {
> 	    	printf("Thread %d got cancelled\n",mythread[ret1]);
> 	    	fflush(stdout);
> 	    }   
> 	    mythread[ret1] = NULL;
> 	    ret1++;
>    }
>    while(true)
>    {
>    }          
> return EXIT_SUCCESS;
> }
>
>
>
>
>
>
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post33805
>   
Re: Memory release issue after pthread_detach and pthread_cancel  
The memory allocation has changed a little from 6.3.2 to 6.4.x. 

But specifically what you are trying to do, can be achieved, I think,
in 6.3.2 by just using some environment variables. 

specifically you can use 

MALLOC_MEMORY_HOLD=0 
(this doesnt hold on to memory in the heap, when blocks are freed and
"can" be released to the system using an underlying munmap call)

or more individually

MALLOC_ARENA_CACHE_MAXBLK=0
MALLOC_ARENA_CACHE_MAXSZ=0

which reduces the size of cached memory blocks inside the heap when
memory is free-ed.

both 6.3.2 and 6.4.x do shrink the heap, but the settings like these
variables control what is freed and when.

in 6.3.2 by default the MAXBLK = 8, so we will cached "8" arena blocks
(this would be 8 blocks of memory that we went to the system with mmap
for).

the size allows you to configure the total size of the
malloc_arena_cache to the specified total size.

let me know if this works for you.

shiv

On Wed, 2009-07-15 at 08:45 -0400, kuldeep paranjpe wrote:
> Hi,
> 
> I am trying to create a thread in 'main' process. This thread
> allocates about 100K memory, sleeps for few seconds and then releases
> the memory. 3 such threads are created by the parent process.
> After creating each thread parent process sleeps for some time and
> calls pthread_detach() and pthread_cancel() on particular 'tid'.
> When I do 'pidin m' for that process, I could see the memory of parent
> process goes on increasing. with each thread create the parent process
> starts with new memory offset(actual + allocated). i.e when thread
> finishes it does not liberate the complete memory and parent process
> does not return to it's original value
> 
> The logs says that;
> parent process starts with about 36K, and after finishing all the
> threads it ends up acquiring 456K.
> 
> pthread_detach() synopsis says '"When a detached thread terminates,
> all system resources allocated to that thread are immediately
> reclaimed."
> 
> OS should destroy all the thread stack once its function is done and
> is cancelled(also pidin dosen't show that thread).
> 
> from where this memory is getting accumulated in parent process? OR is
> there any other way to clean up the thread stack???
> 
> Here is the sample program;
> 
> #include <cstdlib>
> #include <iostream>
> #include <stdio.h>
> #include <pthread.h>
> #include <errno.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <sys/resource.h>
> 
> static void* cliente(void *datos)
> {
>         while(true)
>         {
>                 //Allocating dummy memory of about 100K
>                 char *buff= new char[100000];
>                 sleep(20);
>                 //releasing memory
>                 delete [] buff;
>                 buff=NULL;
>         }
> }
> 
> int main()
> {
>     int ret1;
>     ret1=0;
>     pthread_t mythread[4];
> 
>    while(ret1 < 3)
>    {
>            //create thread
>            if(!pthread_create((pthread_t
> *)&mythread[ret1],NULL,cliente,NULL))
>            {
>                 perror("pthread_create");
>            }
>            //dummy sleep
>            sleep(60);
>             //detach the thread
>            int ret = pthread_detach((pthread_t)mythread[ret1]);
>             if(EOK == ret)
>             {
>                 printf("Thread %d got detached\n",mythread[ret1]);
>                 fflush(stdout);
>             }
>             //cancel the thread
>             int iRet = pthread_cancel((pthread_t)mythread[ret1]); 
>             if(EOK == iRet)
>             {
>                 printf("Thread %d got cancelled\n",mythread[ret1]);
>     ...
View Full Message
Re: Memory release issue after pthread_detach and pthread_cancel  
Hi,
Thanks for your feedback...

Mario:  unfortunately we are still using QNX 6.3.0...we are planning to upgrade, however we can't in the near future do 
various stability issues.

Elena: The objects are being properly deleted. The code that I presented above is just the sample code and not the 
actual one. In the actual code, nothing is being used on the heap. Everything is on the stack. Still I am facing the 
same problem.

Shiv: In the actual code, I am not using malloc. Everything is on the stack. 

Does it so happen that when I cancel the threads, the memory gets accumulated in the parent process and not released to 
the system? Because this is what seems to be happening. 

Awaiting your insights.

Warm Regards,
Kuldeep
Re: Memory release issue after pthread_detach and pthread_cancel  
calling new.. calls malloc
called delete calls free

there is only one process.. and the threads you are creating are
cancelled.. and the memory they allocate via "new" is allocated on the
heap.

shiv
Wed Jul 15 10:21:38 EDT 2009

 --> According to kuldeep paranjpe <--
	Hi,
	Thanks for your feedback...
	
	Mario:  unfortunately we are still using QNX 6.3.0...we are planning to
	upgrade, however we can't in the near future do various stability
	issues.
	
	Elena: The objects are being properly deleted. The code that I presented
	above is just the sample code and not the actual one. In the actual
	code, nothing is being used on the heap. Everything is on the stack.
	Still I am facing the same problem.
	
	Shiv: In the actual code, I am not using malloc. Everything is on the
	stack. 
	
	Does it so happen that when I cancel the threads, the memory gets
	accumulated in the parent process and not released to the system?
	Because this is what seems to be happening. 
	
	Awaiting your insights.
	
	Warm Regards,
	Kuldeep
	
	
	_______________________________________________
	OSTech
	http://community.qnx.com/sf/go/post33832
	

-- 
****
Shiv Nagarajan,
Kernel Developer, QNX Software Systems,
Ottawa, Canada
****
Re: Memory release issue after pthread_detach and pthread_cancel  
IN fact if the thread is cancelled between calls to new and delete, the
memory will be "leaked"

shiv

 --> According to kuldeep paranjpe <--
	Hi,
	Thanks for your feedback...
	
	Mario:  unfortunately we are still using QNX 6.3.0...we are planning to
	upgrade, however we can't in the near future do various stability
	issues.
	
	Elena: The objects are being properly deleted. The code that I presented
	above is just the sample code and not the actual one. In the actual
	code, nothing is being used on the heap. Everything is on the stack.
	Still I am facing the same problem.
	
	Shiv: In the actual code, I am not using malloc. Everything is on the
	stack. 
	
	Does it so happen that when I cancel the threads, the memory gets
	accumulated in the parent process and not released to the system?
	Because this is what seems to be happening. 
	
	Awaiting your insights.
	
	Warm Regards,
	Kuldeep
	
	
	_______________________________________________
	OSTech
	http://community.qnx.com/sf/go/post33832
	

-- 
****
Shiv Nagarajan,
Kernel Developer, QNX Software Systems,
Ottawa, Canada
****
Re: Memory release issue after pthread_detach and pthread_cancel  
Is there any way to avoid such leak???
Re: Memory release issue after pthread_detach and pthread_cancel  
Either use cancellation handlers or don't use pthread cancel. You can implement a different cleanup mechanism using 
other norification mechanisms. It would mean code change on your end.

Shiv
Shiv Nagarajan
Kernel developer, QNX Software Systems
Canada

----- Original Message -----
From: kuldeep paranjpe <community-noreply@qnx.com>
To: ostech-core_os <post33889@community.qnx.com>
Sent: Thu Jul 16 07:44:50 2009
Subject: Re: Memory release issue after pthread_detach and pthread_cancel

Is there any way to avoid such leak???

_______________________________________________
OSTech
http://community.qnx.com/sf/go/post33889

RE: Memory release issue after pthread_detach and pthread_cancel  
I like this behavior because one can run the software for a few days and then you get the idea of the maximum memory 
usage.  If the memory would return to the OS it becomes much harder to find that one of million scenario when the 
machine runs out of memory.

If you don't like this behavior you could use your own object allocator which would be based on mmap().
 
-----Original Message-----
From: kuldeep paranjpe [mailto:community-noreply@qnx.com] 
Sent: Wednesday, July 15, 2009 10:20 AM
To: ostech-core_os
Subject: Re: Memory release issue after pthread_detach and pthread_cancel


Does it so happen that when I cancel the threads, the memory gets accumulated in the parent process and not released to 
the system? Because this is what seems to be happening. 

Awaiting your insights.

Warm Regards,
Kuldeep


_______________________________________________
OSTech
http://community.qnx.com/sf/go/post33832

Re: Memory release issue after pthread_detach and pthread_cancel  
How is it allocated on stack? You should provide example on how it is 
allocated in real code. As Shiv mentioned if you are using new and 
delete it is heap.
Object is allocated on stack if you have something like

foo(int l) {
A object; // one object of type A
B arr[l]; // l objects of type B (dynamic size)
}

or if you use alloca

In this case you don't actually do anything to deallocate it - it 
happens when functions is out of scope;

kuldeep paranjpe wrote:
> Hi,
> Thanks for your feedback...
>
> Mario:  unfortunately we are still using QNX 6.3.0...we are planning to upgrade, however we can't in the near future 
do various stability issues.
>
> Elena: The objects are being properly deleted. The code that I presented above is just the sample code and not the 
actual one. In the actual code, nothing is being used on the heap. Everything is on the stack. Still I am facing the 
same problem.
>
> Shiv: In the actual code, I am not using malloc. Everything is on the stack. 
>
> Does it so happen that when I cancel the threads, the memory gets accumulated in the parent process and not released 
to the system? Because this is what seems to be happening. 
>
> Awaiting your insights.
>
> Warm Regards,
> Kuldeep
>
>
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post33832
>
>   
Re: Memory release issue after pthread_detach and pthread_cancel  
In actual code some maps and vectors are being created on thread stack which are local to the thread and these are 
timely erased and cleared. also there exists some class objects (e.g. Cfoo o_Cfoo )which are local to those threads. 
There is no chance of dynamic memory allocation as such, as no malloc/new are being used (...I don't have any idea how 
maps and vectors internally allocate the memory)
But as per my understanding if there exists some thread stack when thread is in action..if it is cancelled by it's 
parent process at any instance..the memory should be taken away by system, i.e. its stack should be deleted by OS...or 
whatever

NB: I can't give here actual code due to some security reasons 
RE: Memory release issue after pthread_detach and pthread_cancel  

-----Original Message-----
From: kuldeep paranjpe [mailto:community-noreply@qnx.com] 
Sent: Wednesday, July 15, 2009 11:58 AM
To: ostech-core_os
Subject: Re: Memory release issue after pthread_detach and pthread_cancel

In actual code some maps and vectors are being created on thread stack 

No, the object in the maps/vectors are in the heap. It's not because you declare the object on the stack that objects 
allocated within it are on the stack.

which are local to the thread and these are timely erased and cleared. also there exists some class objects (e.g. Cfoo 
o_Cfoo )which are local to those threads. There is no chance of dynamic memory allocation as such, as no malloc/new are 
being used (...I don't have any idea how maps and vectors internally allocate the memory)

It used new / delete ;-)

But as per my understanding if there exists some thread stack when thread is in action..if it is cancelled by it's 
parent process at any instance..the memory should be taken away by system, i.e. its stack should be deleted by OS...or 
whatever

NB: I can't give here actual code due to some security reasons 

_______________________________________________
OSTech
http://community.qnx.com/sf/go/post33848

Re: Memory release issue after pthread_detach and pthread_cancel  
Run your example with IDE's memory analysis tool - you will see if 
object allocated in heap and what happened to them (are they leaks or not).

kuldeep paranjpe wrote:
> In actual code some maps and vectors are being created on thread stack which are local to the thread and these are 
timely erased and cleared. also there exists some class objects (e.g. Cfoo o_Cfoo )which are local to those threads. 
There is no chance of dynamic memory allocation as such, as no malloc/new are being used (...I don't have any idea how 
maps and vectors internally allocate the memory)
> But as per my understanding if there exists some thread stack when thread is in action..if it is cancelled by it's 
parent process at any instance..the memory should be taken away by system, i.e. its stack should be deleted by OS...or 
whatever
>
> NB: I can't give here actual code due to some security reasons 
>
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post33848
>
>   
Re: Memory release issue after pthread_detach and pthread_cancel  
Ya..I guess what Shiv and you guys told was right...I could really see the memory growing by "new offset" in System 
Malloc information...
But what can someone do if the thread has acquired some memory by malloc/new/map/vector or anything...and an external 
event abruptly triggers pthread_detach() and pthread_cancel()????
The memory will never be released...I guess this is what is happening

Thanks to you guys! :-)
RE: Memory release issue after pthread_detach and pthread_cancel  
pthread_cleanup_push()
pthread_cleanup_pop()

> -----Original Message-----
> From: kuldeep paranjpe [mailto:community-noreply@qnx.com]
> Sent: Wednesday, July 15, 2009 12:56 PM
> To: ostech-core_os
> Subject: Re: Memory release issue after pthread_detach and
> pthread_cancel
> 
> Ya..I guess what Shiv and you guys told was right...I could really see
> the memory growing by "new offset" in System Malloc information...
> But what can someone do if the thread has acquired some memory by
> malloc/new/map/vector or anything...and an external event abruptly
> triggers pthread_detach() and pthread_cancel()????
> The memory will never be released...I guess this is what is happening
> 
> Thanks to you guys! :-)
> 
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post33851
Re: RE: Memory release issue after pthread_detach and pthread_cancel  
The pthread cleanup functions are implemented under the hood using a longjmp()-style solution - it's nigh-impossible to 
make it do proper automatic cleanup of stack-allocated C++ objects.  In a broad sense, using C++ and pthread_cancel() /
will/ get you in to trouble.

The only really practical solution if you're using C++ is to avoid using pthread_cancel().   Ultimately we ended up 
writing a library that uses a signal to request cancellation on a target thread, and liberal usage of a call to check 
whether this signal has arrived (particularly after blocking calls) - if the signal was triggered, we throw an exception
, allowing the exception handling code to clean up the stack [as well as allowing catch() blocks to do special-purpose 
cleanup if necessary].  The down side is that you have to remember to place cancellation points explicitly in your code.


-Will
RE: RE: Memory release issue after pthread_detach and pthread_cancel  
Or you put the thread as a fonction member inside a class that hold all the objects, have the destructor do the 
pthread_cancel and then let the rest of the destructor free the object.

I use the POCO library for that type of stuff which has a Runnable class that you inherit from and deal with some of the
 thread details.

I believe the class Rennie wrote which is avaiblable as a Project under foundry27 also has this stuff in.

________________________________________
From: Will Miles [community-noreply@qnx.com]
Sent: Wednesday, July 15, 2009 2:20 PM
To: ostech-core_os
Subject: Re: RE: Memory release issue after pthread_detach and pthread_cancel

The pthread cleanup functions are implemented under the hood using a longjmp()-style solution - it's nigh-impossible to 
make it do proper automatic cleanup of stack-allocated C++ objects.  In a broad sense, using C++ and pthread_cancel() /
will/ get you in to trouble.

The only really practical solution if you're using C++ is to avoid using pthread_cancel().   Ultimately we ended up 
writing a library that uses a signal to request cancellation on a target thread, and liberal usage of a call to check 
whether this signal has arrived (particularly after blocking calls) - if the signal was triggered, we throw an exception
, allowing the exception handling code to clean up the stack [as well as allowing catch() blocks to do special-purpose 
cleanup if necessary].  The down side is that you have to remember to place cancellation points explicitly in your code.


-Will

_______________________________________________
OSTech
http://community.qnx.com/sf/go/post33859
Re: Memory release issue after pthread_detach and pthread_cancel  
Hi Mario,

Sure, it'd work very well, as long as you're absolutely certain that
when the pthread_cancel goes through you have no C++ objects that
require their own destructors are allocated on the stack in that thread.

Personally, I like to use RAII patterns for managing things like mutexes
by using guard objects.  I find that allocating guards on the stack is
very practical - it makes it vastly simpler to manage lock scoping.
pthread_cancel makes a total hash of the way those work, since if you
get hit with a cancel while holding the lock, the destructor on the
guard object will never run.  Forcing those temporary stack allocations
out to higher-scope objects feels like an encapsulation violation to
me, requiring some aspect of a function's local state to live in the
object it's attached to.  It'd also require serialization at a higher
level - we use an event-driven model for much of our architecture,
which in turn means that having many threads in the same function is
the norm rather than the exception for us; keeping lists of the worker
threads blocked on a condvar that might need to release the mutex if
killed is certainly doable, but seemed like more work than just
implementing a C++-safe cancellation mechanism that ensured that
stack-allocated objects would get appropriately destructed.

The bottom line is that any way you slice it, stack-allocated C++
objects and pthread_cancel don't work together.  This leaves the
programmer with two possible options:

a) avoid using pthread_cancel (potentially by implementing your own
cancellation scheme);

or

b) don't allocate any C++ objects on the stack (potentially by ensuring
that all C++ objects used by code called on the relevant thread are
held by a larger-scope object).

Ultimately it depends on how you use C++. :)

-Will

On Wed, 15 Jul 2009 14:26:02 -0400 (EDT)
Mario Charest <community-noreply@qnx.com> wrote:

> 
> Or you put the thread as a fonction member inside a class that hold all the objects, have the destructor do the 
pthread_cancel and then let the rest of the destructor free the object.
> 
> I use the POCO library for that type of stuff which has a Runnable class that you inherit from and deal with some of 
the thread details.
> 
> I believe the class Rennie wrote which is avaiblable as a Project under foundry27 also has this stuff in.
Re: Memory release issue after pthread_detach and pthread_cancel  
If not pthread_cancel...I think pthread_exit() should do the job!
the thread in action should gracefully exit on it's own... 
Re: Memory release issue after pthread_detach and pthread_cancel  
its not really the thread exit that is the issue. It is the fact that
memory that is allocated is from the heap is not freed back and the
thread that has a reference to this memory is no longer around to clean
this up. Thats what results in the leak

shiv
Thu Jul 16 13:15:50 EDT 2009

 --> According to kuldeep paranjpe <--
	If not pthread_cancel...I think pthread_exit() should do the job!
	the thread in action should gracefully exit on it's own... 
	
	_______________________________________________
	OSTech
	http://community.qnx.com/sf/go/post33963
	

-- 
****
Shiv Nagarajan,
Kernel Developer, QNX Software Systems,
Ottawa, Canada
****
Re: Memory release issue after pthread_detach and pthread_cancel  
One underlying problem here is that the C++ standard does not provide
any guidance on what to do in the presence of threads.  And the POSIX
specification does not require any specific special C++ behaviour for
pthread_cancel().  Our implementation doesn't actually rely on
setjmp/longjmp (it actually effectively hooks in to the atexit()
handling), but the net result is the same: C++ unwinding does not occur.

As a previous poster points out, it is likely to be very tricky indeed
to get POSIX thread cancellation and C++ to work nicely with each other.
One workaround would be to arrange for some other OOB signalling
mechanism to set a thread-visible flag which is periodically checked
and, when set, causes some sort of exception to be raised.  This also
helps to control cancellation state: most library calls (e.g. member
functions of map, multiset, etc.) are not cancellation-safe in any case,
so Bad Things(tm) are likely to happen anyway.  (POSIX cancellation is
really only actually useful in a very limited number of scenarios.)

On Thu, 2009-07-16 at 13:16 -0400, Shiv Nagarajan wrote:
> its not really the thread exit that is the issue. It is the fact that
> memory that is allocated is from the heap is not freed back and the
> thread that has a reference to this memory is no longer around to clean
> this up. Thats what results in the leak
> 
> shiv
> Thu Jul 16 13:15:50 EDT 2009
> 
>  --> According to kuldeep paranjpe <--
> 	If not pthread_cancel...I think pthread_exit() should do the job!
> 	the thread in action should gracefully exit on it's own... 
> 	
> 	_______________________________________________
> 	OSTech
> 	http://community.qnx.com/sf/go/post33963
> 	
> 
Re: Memory release issue after pthread_detach and pthread_cancel  
Hi,

My apologies for necroposting, but I've recently been forced to reconsider the issue and wanted to leave a trackback for
 anyone else facing this problem.

Our original implementation worked more-or-less the way Neil described: we used a signal targeted at a specific thread 
to carry a cancellation request, and then relied on interspersing our own check_cancel() calls at strategic points in 
our code.  If the signal had been tripped, check_cancel() would throw a C++ exception, forcing a stack unwind.   Using a
 signal seemed like a particularly clever choice because it would induce an EINTR unblock if the thread was waiting for 
something.  The resulting code would often look something like:

LockGuard lg(mutex);
while (condition == false) {
    check_cancel();
    pthread_cond_wait(&condvar, &mutex);
    check_cancel();
}

This arrangement seemed to work pretty well for a few years.  Recently, however, we ran in to a test machine where 
threads would seemingly get stuck and miss the cancellation request somehow.  It turned out that what was happening was 
that the thread was getting interrupted AFTER the first check_cancel(), but BEFORE the blocking call - so the signal 
handler would run without causing an EINTR, and the thread would just end up blocked instead of terminating.   The 
obvious fix - just try the cancel a couple times - still didn't work; because of other issues on our test rack the 
subsequent cancel attempts still vanished because the poor target thread was getting CPU starved.

To mitigate this hole, we were forced to reconsider pthread_cancel() - it seems it is the only mechanism that will /
guarantee/ that a thread will terminate in a well-defined way without any race conditions.  Unfortunately, this brought 
us back to the original poster's problem, where C++ objects on the stack would not be properly destructed.

We did ultimately find a mechanism of transforming a POSIX cancellation request into a C++ exception throw, though it 
requires a bit of black magic.  The basic approach is to: 

a) Run threads with POSIX cancellation normally set to PTHREAD_CANCEL_DISABLE.
b) Only enable cancellation at your own explicitly added cancellation test points, or around blocking C library calls 
that you can be confident have no side effects (such as internally allocating memory).  Most places we found that 
threads needed to be cancelable from (sleep()s, pthread_cond_wait()s, MsgSend()s, InterruptWait()s, etc.) seem to be in 
this category at the present time.
c) Before you enable cancellation, capture the CPU state and stack frame pointer and cache this information.  Then, bind
 a pthread_cleanup handler that first restores the CPU state, adjusts its own stack frame so that it will return 
directly to the original calling function where the capture took place (stepping over the library call stack frames), 
then throws the C++ exception.

While this seems to be functional, it is unfortunately a bit fragile - the cleanup handler code will be necessarily 
machine and compiler specific.  Right now I have a working implementation for x86 on QNX 6.3.2 (using GCC 3.3.5).   Ping
 me if you want the source code.

Good luck threaded C++ users!

-Will