Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: memory leak in multithreaded c++ program

693 views
Skip to first unread message

Igal Ore

unread,
May 4, 2004, 2:49:52 AM5/4/04
to
Hawk wrote:

>Hi
>I wrote a multithreaded program using openssl
>But with every connection it grows up about 8kb
>I think I freed all SSL* and SSL_CTX* I used
>
>I used this functions to make my program threadsafe:
>Perhaps anyone can give me a hint if there is an error?
>With best regards
>Stephan
>
>void CRYPTO_thread_setup(void)
>{
> debugmsg("[CRYPTO_thread_setup] start");
> int i;
>
> lock_cs = (pthread_mutex_t*)OPENSSL_malloc(CRYPTO_num_locks() *
>sizeof(pthread_mutex_t));
> lock_count = (long *)OPENSSL_malloc(CRYPTO_num_locks() *
>sizeof(long));
> for (i=0; i<CRYPTO_num_locks(); i++)
> {
> lock_count[i]=0;
> pthread_mutex_init(&(lock_cs[i]),NULL);
> }
>
> CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
> CRYPTO_set_locking_callback(pthreads_locking_callback);
> debugmsg("[CRYPTO_thread_setup] end");
>}
>
>void thread_cleanup(void)
>{
> debugmsg("[thread_cleanup] start");
> int i;
>
> CRYPTO_set_locking_callback(NULL);
> for (i=0; i<CRYPTO_num_locks(); i++)
> {
> pthread_mutex_destroy(&(lock_cs[i]));
> }
> OPENSSL_free(lock_cs);
> OPENSSL_free(lock_count);
> debugmsg("[thread_cleanup] end");
>}
>
>void pthreads_locking_callback(int mode, int type, const char *file,
> int line)
>{
> //debugmsg("[pthreads_locking_callback] start");
> #if 0
> fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
> CRYPTO_thread_id(),
> (mode&CRYPTO_LOCK)?"l":"u",
> (type&CRYPTO_READ)?"r":"w",file,line);
> #endif
> #if 0
> if (CRYPTO_LOCK_SSL_CERT == type)
> fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
> CRYPTO_thread_id(),
> mode,file,line);
> #endif
> if (mode & CRYPTO_LOCK)
> {
> pthread_mutex_lock(&(lock_cs[type]));
> lock_count[type]++;
> }
> else
> {
> pthread_mutex_unlock(&(lock_cs[type]));
> }
> //debugmsg("[pthreads_locking_callback] end");
>}
>
>unsigned long pthreads_thread_id(void)
>{
> unsigned long ret;
>
> ret=(unsigned long)pthread_self();
> return(ret);
>}
>
>______________________________________________________________________
>OpenSSL Project http://www.openssl.org
>User Support Mailing List openss...@openssl.org
>Automated List Manager majo...@openssl.org
>
>
>
First , try to activate OpenSSL debug memory procedure:
BIO *pbio - BIO_new(BIO_s_file());
BIO_set_fp(out,stdout,BIO_NOCLOSE);
CRYPTO_malloc_debug_init();
MemCheck_start();
MemCheck_on();

.
.
.
MemCheck_off()
MemCheck_stop()
CRYPTO_mem_leaks(pbio);

This will print out to stdout all memory that has been not deallocated ;

Put starting part before everything ( even before
OpenSSL_add_all_algorithms() call) this you will see everything.

Possible place of leeak , is error reporting since it tied to thread IDs

Just on remark one thread safe code : why do you need lock_count array ?

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org

Frédéric Giudicelli

unread,
May 4, 2004, 3:10:26 AM5/4/04
to
Hawk wrote:
> Hi
> I wrote a multithreaded program using openssl
> But with every connection it grows up about 8kb
> I think I freed all SSL* and SSL_CTX* I used
>

You need to call at the end of your thread:
::ERR_clear_error();
::ERR_remove_state(0);

Regards,
--
Frédéric Giudicelli
http://www.newpki.org

Hawk

unread,
May 4, 2004, 4:02:35 AM5/4/04
to
> First , try to activate OpenSSL debug memory procedure:
> BIO *pbio - BIO_new(BIO_s_file());
> BIO_set_fp(out,stdout,BIO_NOCLOSE);
> CRYPTO_malloc_debug_init();
> MemCheck_start();
> MemCheck_on();
>
> .
> .
> .
> MemCheck_off()
> MemCheck_stop()
> CRYPTO_mem_leaks(pbio);
>
> This will print out to stdout all memory that has been not deallocated ;
>
> Put starting part before everything ( even before
> OpenSSL_add_all_algorithms() call) this you will see everything.
>
> Possible place of leeak , is error reporting since it tied to thread IDs

Ok thanks I will try this

>
> Just on remark one thread safe code : why do you need lock_count array ?

I just copied this code from an example I found in the web
If I won't need all this functions it would be nice ;)
What functions do I have to use?
Thanks,
Stephan

Hawk

unread,
May 4, 2004, 4:05:44 AM5/4/04
to

> You need to call at the end of your thread:
> ::ERR_clear_error();
> ::ERR_remove_state(0);

I used the ERR_remove_state but not the clear_Error
Do I have to call this before freeing SSL* and SSL_CTX* objects?

Frédéric Giudicelli

unread,
May 4, 2004, 4:11:37 AM5/4/04
to
Hawk wrote:

>>You need to call at the end of your thread:
>>::ERR_clear_error();
>>::ERR_remove_state(0);
>
>
> I used the ERR_remove_state but not the clear_Error
> Do I have to call this before freeing SSL* and SSL_CTX* objects?
> Thanks,
> Stephan
>
>

Those are last two lines of my thread execution callback.

If you call any openssl's free function after ERR_remove_state(0), you
will have a memory leak, because it will create another thread context
that will never be freed.

--
Frédéric Giudicelli
http://www.newpki.org

Hawk

unread,
May 4, 2004, 1:05:03 PM5/4/04
to
> Those are last two lines of my thread execution callback.
>
> If you call any openssl's free function after ERR_remove_state(0), you
> will have a memory leak, because it will create another thread context
> that will never be freed.

So i can do
SSL_free(clientssl);
SSL_CTX_free(clientsslctx);
ERR_clear_error();
ERR_remove_state(0);
At the end of my thread?
What kind of locking functions do I _need_?
Thanks,
Stephan

Igal Ore

unread,
May 4, 2004, 3:52:49 PM5/4/04
to
This is a multi-part message in MIME format.
--------------000303090400040203030809
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hawk wrote:

this problem does not concerning thread locking or not
When error is logged OpenSSL remember from witch thread it had been raised .
Simplest thing to do is to remove all error state by ERR_remove_state(0)
from the thread , just before finishing it (ERR_clear_error() will clean
out entire OpenSSL error stack , so may be not that good idea , and it
does not affect memory leaking situation)

More complicate thing to do is remember is some kind of array all
threads numbers that ever raised during run of program , at process
thread (or main thread should be the name ? ) , and then calling
ERR_remove_state(x) for all them.

of cause all those troubles would be saved if somebody would create one
function that will erase entire error stack at once (if i will had some
spare time , i will look at it)


Hawk , did you tried to activate OpenSSL memory leak checks ? What does
it did ? it found something , or you were to busy :)?

--------------000303090400040203030809
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title></title>
</head>
<body>
Hawk wrote:
<blockquote cite="mid20040504170...@master.openssl.org"
type="cite">
<blockquote type="cite">
<pre wrap="">Those are last two lines of my thread execution callback.

If you call any openssl's free function after ERR_remove_state(0), you
will have a memory leak, because it will create another thread context
that will never be freed.

</pre>
</blockquote>
<pre wrap=""><!---->


So i can do
SSL_free(clientssl);
SSL_CTX_free(clientsslctx);
ERR_clear_error();
ERR_remove_state(0);
At the end of my thread?
What kind of locking functions do I _need_?
Thanks,
Stephan

______________________________________________________________________
OpenSSL Project <a class="moz-txt-link-freetext" href="http://www.openssl.org">http://www.openssl.org</a>
User Support Mailing List <a class="moz-txt-link-abbreviated" href="mailto:openss...@openssl.org">openss...@openssl.org</a>
Automated List Manager <a class="moz-txt-link-abbreviated" href="mailto:majo...@openssl.org">majo...@openssl.org</a>

</pre>
</blockquote>
this problem does not concerning thread locking or not<br>
When error is logged OpenSSL remember from witch thread it had been
raised .<br>
Simplest thing to do is to remove all error state by
ERR_remove_state(0) from the thread , just before finishing it
(ERR_clear_error() will clean out entire OpenSSL error stack , so may
be not that good idea , and it does not affect memory leaking situation)<br>
<br>
More complicate thing to do is remember is some kind of array all
threads numbers that ever raised during run of program , at process
thread (or main thread should be the name ? ) , and then calling
ERR_remove_state(x) for all them.<br>
<br>
of cause all those troubles would be saved if somebody would create one
function that will erase entire error stack at once (if i will had some
spare time , i will look at it) <br>
<br>
<br>
Hawk , did you tried to activate OpenSSL memory leak checks ? What does
it did ? it found something , or you were to busy :)?<br>
</body>
</html>

--------------000303090400040203030809--

Hawk

unread,
May 4, 2004, 5:10:56 PM5/4/04
to


>this problem does not concerning thread locking or not

But I dond't understand what the functions from the example I found do
There is one which allocates memory
But this memory is never freed
The function thread_cleanup should be called when program finishes
But I wrote a daemon which never stops (well it should't stop ;) )

>When error is logged OpenSSL remember from witch thread it had been raised
.
>Simplest thing to do is to remove all error state by ERR_remove_state(0)
from the thread , just before finishing it (ERR_clear_error() will clean out
>entire OpenSSL error stack , so may be not that good idea , and it does not
affect memory leaking situation)

>More complicate thing to do is remember is some kind of array all threads
numbers that ever raised during run of program , at process thread (or main
>thread should be the name ? ) , and then calling ERR_remove_state(x) for
all them.

>of cause all those troubles would be saved if somebody would create one
function that will erase entire error stack at once (if i will had some
spare >time , i will look at it)

Would be nice ;)

>Hawk , did you tried to activate OpenSSL memory leak checks ? What does it
did ? it found something , or you were to busy :)?

Yes I'm a little bit busy :/
I write my end exam for the next 7 days

Igal Ore

unread,
May 4, 2004, 6:06:05 PM5/4/04
to
This is a multi-part message in MIME format.
--------------030608050005030806060604

Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hawk wrote:

What allocated in this is what called in OpenSSL jargon are static locks
: at crypto.h there definition for 33 (at openssl 0.9.7d) OpenSSL global
locks.

At lot of places in openSSL you would see calls to macro CRYPTO_w_lock
or CRYPTO_r_lock (and they counter parts CRYPTO_w_unlock and
CRYPTO_r_unlock) witch performs inside openSSL multi-thread protection.

What you had allocated there is static array (lock_cs) who holds
pointers (in you example case) to pthread allocated mutexes. If you
saing that yours program is endless daemon then there no problem ( of
cause if you calling thread setup function only once!!!)

So apply openssl memory leak detection and brace yourself , as far as
you described problem will be not because allocating static array of
mutexes.
What i do suggest to you , is in order to get best , and also more
readable result , is to run your damon for some time and then stop it.
If you will start memory leak detection in main thread then you will see
all memory that has not been deallocated . If you will try to do it on
running daemon than , for example , entire arrays of your allocated
mutexes will be show as one big leak, since OpenSSL saw allocation that
nobody had claimed for themself !!!!
Have fun !!! Good luck at exam (god!!! that good to know that i'm not
learning but somebody else do :)

--------------030608050005030806060604


Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title></title>
</head>
<body>
Hawk wrote:

<blockquote cite="mid20040504210...@master.openssl.org"
type="cite">
<pre wrap="">
</pre>
<blockquote type="cite">
<pre wrap="">this problem does not concerning thread locking or not


</pre>
</blockquote>
<pre wrap=""><!---->

But I dond't understand what the functions from the example I found do
There is one which allocates memory
But this memory is never freed
The function thread_cleanup should be called when program finishes
But I wrote a daemon which never stops (well it should't stop ;) )

</pre>
<blockquote type="cite">
<pre wrap="">When error is logged OpenSSL remember from witch thread it had been raised
</pre>
</blockquote>
<pre wrap=""><!---->.
</pre>
<blockquote type="cite">
<pre wrap="">Simplest thing to do is to remove all error state by ERR_remove_state(0)
</pre>
</blockquote>
<pre wrap=""><!---->from the thread , just before finishing it (ERR_clear_error() will clean out
</pre>
<blockquote type="cite">
<pre wrap="">entire OpenSSL error stack , so may be not that good idea , and it does not
</pre>
</blockquote>
<pre wrap=""><!---->affect memory leaking situation)

</pre>
<blockquote type="cite">
<pre wrap="">More complicate thing to do is remember is some kind of array all threads
</pre>
</blockquote>
<pre wrap=""><!---->numbers that ever raised during run of program , at process thread (or main
</pre>
<blockquote type="cite">
<pre wrap="">thread should be the name ? ) , and then calling ERR_remove_state(x) for
</pre>
</blockquote>
<pre wrap=""><!---->all them.

</pre>
<blockquote type="cite">
<pre wrap="">of cause all those troubles would be saved if somebody would create one
</pre>
</blockquote>
<pre wrap=""><!---->function that will erase entire error stack at once (if i will had some
spare &gt;time , i will look at it)

Would be nice ;)

</pre>
<blockquote type="cite">
<pre wrap="">Hawk , did you tried to activate OpenSSL memory leak checks ? What does it
</pre>
</blockquote>
<pre wrap=""><!---->did ? it found something , or you were to busy :)?

Yes I'm a little bit busy :/
I write my end exam for the next 7 days

Thanks,
Stephan


______________________________________________________________________


OpenSSL Project <a class="moz-txt-link-freetext" href="http://www.openssl.org">http://www.openssl.org</a>
User Support Mailing List <a class="moz-txt-link-abbreviated" href="mailto:openss...@openssl.org">openss...@openssl.org</a>
Automated List Manager <a class="moz-txt-link-abbreviated" href="mailto:majo...@openssl.org">majo...@openssl.org</a>

</pre>
</blockquote>
What allocated in this is what called in OpenSSL jargon are static
locks : at crypto.h there definition for 33 (at openssl 0.9.7d) OpenSSL
global locks. <br>
<br>
At lot of places in openSSL you would see calls to macro CRYPTO_w_lock
or CRYPTO_r_lock (and they counter parts CRYPTO_w_unlock and
CRYPTO_r_unlock) witch performs inside openSSL multi-thread protection.<br>
<br>
What you had allocated there is static array (lock_cs) who holds
pointers (in you example case) to pthread allocated mutexes. If you
saing that yours program is endless daemon then there no problem ( of
cause if you calling thread setup function only once!!!)<br>
<br>
So apply openssl memory leak detection and brace yourself , as far as
you described problem will be not because allocating static array of
mutexes.<br>
What i do suggest to you , is in order to get best , and also more
readable result , is to run your damon for some time and then stop it.
If you will start memory leak detection in main thread then you will
see all memory that has not been deallocated . If you will try to do it
on running daemon than , for example , entire arrays of your allocated
mutexes will be show as one big leak, since OpenSSL saw allocation that
nobody had claimed for themself !!!!<br>
Have fun !!! Good luck at exam (god!!! that good to know that i'm not
learning but somebody else do :)<br>
</body>
</html>

--------------030608050005030806060604--

0 new messages