I've attached the program I'm referring to below. When I run this
program using valgrind (valgrind --leak-check=full --trace-children=yes
./pt_test2), I receive the following output:
==10338== Memcheck, a memory error detector.
==10338== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==10338== Using LibVEX rev 1658, a library for dynamic binary translation.
==10338== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==10338== Using valgrind-3.2.1-Debian, a dynamic binary instrumentation
framework.
==10338== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==10338== For more details, rerun with: -v
==10338==
+Enter thread 1.1...
+Enter thread 2.1...
_This is thread1.1 - 1 ms have elapsed!
_This is thread1.1 - 1 ms have elapsed!
_This is thread1.1 - 1 ms have elapsed!
_This is thread2.1 - 3 ms have elapsed!
q
==10338== Thread 4:
==10338== Conditional jump or move depends on uninitialised value(s)
==10338== at 0x402B080: pthread_detach (pthread_detach.c:32)
==10338== by 0x8048988: cleanup_thread (pt_test2.c:15)
==10338== by 0x80489CE: thread2_1 (pt_test2.c:55)
==10338== by 0x4029E59: start_thread (pthread_create.c:296)
==10338== by 0x40FA91D: clone (in /usr/lib/debug/libc-2.5.so)
==10338==
==10338== Conditional jump or move depends on uninitialised value(s)
==10338== at 0x402B0A8: pthread_detach (pthread_detach.c:51)
==10338== by 0x8048988: cleanup_thread (pt_test2.c:15)
==10338== by 0x80489CE: thread2_1 (pt_test2.c:55)
==10338== by 0x4029E59: start_thread (pthread_create.c:296)
==10338== by 0x40FA91D: clone (in /usr/lib/debug/libc-2.5.so)
==10338==
==10338== Thread 3:
==10338== Conditional jump or move depends on uninitialised value(s)
==10338== at 0x402B080: pthread_detach (pthread_detach.c:32)
==10338== by 0x8048988: cleanup_thread (pt_test2.c:15)
==10338== by 0x8048A86: thread1_1 (pt_test2.c:27)
==10338== by 0x4029E59: start_thread (pthread_create.c:296)
==10338== by 0x40FA91D: clone (in /usr/lib/debug/libc-2.5.so)
==10338==
==10338== Conditional jump or move depends on uninitialised value(s)
==10338== at 0x402B0A8: pthread_detach (pthread_detach.c:51)
==10338== by 0x8048988: cleanup_thread (pt_test2.c:15)
==10338== by 0x8048A86: thread1_1 (pt_test2.c:27)
==10338== by 0x4029E59: start_thread (pthread_create.c:296)
==10338== by 0x40FA91D: clone (in /usr/lib/debug/libc-2.5.so)
All done!
==10338==
==10338== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 15 from 1)
==10338== malloc/free: in use at exit: 888 bytes in 5 blocks.
==10338== malloc/free: 8 allocs, 3 frees, 1,296 bytes allocated.
==10338== For counts of detected errors, rerun with: -v
==10338== searching for pointers to 5 not-freed blocks.
==10338== checked 81,016 bytes.
==10338==
==10338== LEAK SUMMARY:
==10338== definitely lost: 0 bytes in 0 blocks.
==10338== possibly lost: 0 bytes in 0 blocks.
==10338== still reachable: 888 bytes in 5 blocks.
==10338== suppressed: 0 bytes in 0 blocks.
==10338== Reachable blocks (those to which a pointer was found) are not
shown.
==10338== To see them, rerun with: --show-reachable=yes
The "in use at exit" line indicates that there's a memory leak (plus 8
alloc & 3 frees = bad leak). I'm not doing any sort of allocation
anywhere in the code, so I'm thinking the only place it could be leaking
is in one of the libraries I'm using (mainly pthreads in this instance).
I've read about the possible leak if you have a joinable thread that's
not joined, so I've created all but the main thread as detached, and to
further ensure that they're "cleaned up" afterward, I run the
pthread_detach() as part of the cleanup should the thread be cancelled.
Any suggestions on why I'm seeing this memory leak?
Thanks in advance,
Tim
~~~~~~~~~~~~~~~~~~~~~~~~
~~ Code (pt_test2.c): ~~
~~~~~~~~~~~~~~~~~~~~~~~~
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_attr_t attr;
void cleanup_thread(void *thid)
{
pthread_detach((pthread_t) thid);
}
void *thread1_1(void *in)
{
printf(" +Enter thread 1.1...\n");
clock_t time1, time2;
time1 = clock();
pthread_t myid = pthread_self();
pthread_cleanup_push( cleanup_thread, (void *) &myid );
pthread_detach(myid);
while (1) {
pthread_testcancel();
time2 = clock();
if ((double)(time2-time1)/CLOCKS_PER_SEC >= 1) {
printf(" _This is thread1.1 - %i ms have elapsed!\n",
(int)(time2-time1)/CLOCKS_PER_SEC);
time1 = clock();
}
}
pthread_cleanup_pop(0);
printf(" -Exit thread 1.1...\n");
pthread_exit(NULL);
}
void *thread2_1(void *in)
{
printf(" +Enter thread 2.1...\n");
clock_t time1, time2;
time1 = clock();
pthread_t myid = pthread_self();
pthread_cleanup_push( cleanup_thread, (void *) &myid );
pthread_detach(myid);
while (1) {
pthread_testcancel();
time2 = clock();
if ((double)(time2-time1)/CLOCKS_PER_SEC >= 3) {
printf(" _This is thread2.1 - %i ms have elapsed!\n",
(int)(time2-time1)/CLOCKS_PER_SEC);
time1 = clock();
}
}
pthread_cleanup_pop(0);
printf(" -Exit thread 2.1...\n");
pthread_exit(NULL);
}
void *main_thread(void *in)
{
char buff[20];
pthread_t threads[2];
pthread_attr_t attrib;
pthread_attr_init(&attrib);
pthread_attr_setdetachstate(&attrib, PTHREAD_CREATE_DETACHED);
pthread_create(&threads[0], &attrib, thread1_1, NULL);
pthread_create(&threads[1], &attrib, thread2_1, NULL);
pthread_attr_destroy(&attrib);
// scanf("%s", &buff);
gets(buff);
pthread_cancel(threads[0]);
pthread_cancel(threads[1]);
}
int main(int argc, char *argv[])
{
pthread_t tmain_thread;
/* Initialize and set thread detached attribute */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&tmain_thread, &attr, main_thread, NULL);
pthread_attr_destroy(&attr);
pthread_join(tmain_thread, NULL);
printf("All done!\n");
return EXIT_SUCCESS;
}
> The "in use at exit" line indicates that there's a memory leak (plus 8
> alloc & 3 frees = bad leak).
No, it does not. It just means that there are blocks that have been
allocated and not free()d. These blocks are still reachable (from
some global), so they are *not* leaks.
> Any suggestions on why I'm seeing this memory leak?
Read Valgrind docs, in particular section 3.3.7
http://valgrind.org/docs/manual/mc-manual.html#mc-manual.leaks
Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.