[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Fwd: Re: Haunting free(): invalid pointer 0x8a11604!]

From: David Sugar
Subject: Re: [Fwd: Re: Haunting free(): invalid pointer 0x8a11604!]
Date: Sun, 13 Feb 2005 14:57:12 -0500
User-agent: Mozilla Thunderbird 1.0 (Macintosh/20041206)

I think you are absolutely correct that the key should be cleared if th->isDetach() is true before calling th->close() and letting it fall through the rest of the code. The threadKey for "self" is also used so that arbitrary code can determine and manipulate the actual Thread "object" that is associated with the current execution context, rather than just the less useful pthread "id". getThread() uses this.

Nick Liebmann wrote:
Well the destructor in the derived class is empty.

Really the problem is ThreadImpl::ThreadDestructor checks th->priv, from an object 'th' which has already been deleted, in the case of a detached thread. Im not really sure of the reasons for the ThreadKey class, but reading the pthread documentation for pthread_key_create:

An optional destructor function may be associated with each key value. At thread exit, if a key value has a non-NULL destructor pointer, and the thread has a non-NULL value associated with that key, the function pointed to is called with the current associated value as its sole argument. The order of destructor calls is unspecified if more than one destructor exists for a thread when it exits.

So I think either ThreadImpl::ThreadDestructor should delete 'th' if it determines its a detached thread, or ThreadImpl::ThreadDestructor should not be called for an already deleted thread.

David Sugar wrote:

Ah, I think I might see...both the exit handling for close is called, as is the destructor, which includes terminate() that does some other stuff? What does the destructor in your derived object look like?

Nick Liebmann wrote:

As a penance for trying to sort out this problem with an old version of the library, I have taken a look with the latest version.

Here are my discoveries:

As previously stated 'delete this' is called from Thread::close(), and there seems to be no reason to assume anything is wrong with this call. All destructors are called appropriately.

The problem valgrind reports is that an access is being made to an already deleted chunk of memory, and it seems to be correct...

After the 'delete this' pthread_exit(NULL) is called, which causes a call to ccxx_thread_destructor, which itself calls ThreadImpl::ThreadDestructor.

ThreadImpl::ThreadDestructor checks th->priv which is illegal, because th (the thread) has been deleted.

This is where my knowledge of pthreads becomes flaky, but I reckon this is being called due to the ThreadKey object still having a reference to the thread

Inserting the line:
before the call to th->close() in ThreadImpl::ThreadExecHandler(Thread*th) sorts out the problem, however I am not actually sure of the side effects of this call. Maybe is should be conditional, depending on the detached state of the thread.

David... its over to you


David Sugar wrote:

In older versions of the library you would use "delete this" for detached threads. In the current (1.3) releases, you should NEVER do this. That final() was appearently leftover from before detach behavior was changed. In 1.?2? and definately 1.3, detach deletes the the thread the object for you after you exit() the thread, and does it through the virtual destructors via the Thread base class.

Nick wrote:

Ok, your problem is that the TCPSession::final calls delete this when
the thread ends.

Your choices are

1) Dont call tcp->detach(), call start()... the thread will be deleted
automaticall by TCPSession::final
2) override virtual void final() in TCPSessionThread, to do nothing.

For the library, TCPSession::final should say if(!isDetached()) delete this;

Rami Saarinen wrote:

--- Nick Liebmann <address@hidden> wrote:

I would also suggest declaring empty virtual destructors for any inherited classes for which you have no specific need for a destructor. I dont really know why this should be necessary, but for some reason (at least in the past)
I have found this necessary, and now do it as a habit.

An isolated test-case is definitly the way to go!

Well I just can't get it any simpler than this. Invalid pointer is still
present exactly like before. Am I missing something? Brains?

I am using cc++ 1.3.1, gcc 3.3.3 20040412, Fedora Core 2 (Linux). cc++ was
compiled on this machine. testlistener is the test program.

TCPListener is the one that will create TCPSessionThread per connection
when there are connections pending.
TCPSessionThread does nothing at all (and the invalid pointer error
appears in destructor).

I linked it with -lccgnu2 -ldl (used also -lpthread, but it is not needed

Valgrind gives this when connecting the test program and sending some text to it:

Bug-commoncpp mailing list

Attachment: dyfet.vcf
Description: Vcard

reply via email to

[Prev in Thread] Current Thread [Next in Thread]