Valgrind - "still reachable"

0

Zrobiłem sobie małą nakładkę na pthreads:

//posix_thread.h
#ifndef POSIXTHREAD_H
#define POSIXTHREAD_H

#include <pthread.h>

#define FRIEND_WITH_F friend void *functionOfPosixThread(void *pointerToThreadObject) ;

void *functionOfPosixThread(void *pointerToThreadObject) ;
class PosixThread
{
	FRIEND_WITH_F 
	public:
		PosixThread();
		virtual ~PosixThread();

		void Start();
		void Stop();
		inline void PauseOn()
		{
			paused=1 ;
		}
		inline void PauseOff() 
		{
			paused=0 ;
		}
		
		inline void SetDelay(unsigned int delay) 
		{
			this->delay = delay;
		}
		inline unsigned int GetDelay() const 
		{
			return delay;
		}
	protected:
		virtual void Work()=0 ;
	private:
		unsigned int delay ;
		pthread_t thread ;
		int resultOfThreadOperations ;
		volatile bool working ;
		volatile bool paused ;
};

#endif // POSIXTHREAD_H

//posix_thread.cpp
#include "posix_thread.h"

#include <unistd.h>


PosixThread::PosixThread()
{
	delay = 1000 ;
	resultOfThreadOperations = 0 ;
	working = 0 ;
	paused = 0 ;
}

PosixThread::~PosixThread()
{
}

void PosixThread::Start()
{
	resultOfThreadOperations = pthread_create( &thread, NULL, functionOfPosixThread, (void*)this);
}

void PosixThread::Stop()
{
	if((!working) || (resultOfThreadOperations!=0))
	{
		return;		
	}
	paused=0;
	working=0;
	resultOfThreadOperations = pthread_join(thread, NULL);	
}

void *functionOfPosixThread(void* pointerToThreadObject)
{
	PosixThread* thread = (PosixThread*)pointerToThreadObject ;
	thread->working=1 ;
	thread->paused=0;
	while(thread->working)
	{
		if(thread->paused)
		{
			continue ;
		}
		thread->Work() ;
		usleep(thread->delay) ;
	}
	pthread_exit(0);
}

Tutaj konkretna testowa implementacja:

//main.cpp
#include <iostream>

#include <gtest/gtest.h>
#include "posix_thread_test.h"

int main(int argc, char **argv)
{
	testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}
//posix_thread_test.h"
#ifndef POSIXTHREADTEST_H
#define POSIXTHREADTEST_H

#include <gtest/gtest.h>

#include "../Server/posix_thread.h"

#include <string>

namespace 
{
	class PosixThreadTest : public ::testing::Test 
	{
		protected:
			PosixThreadTest(){};
			virtual ~PosixThreadTest(){};
			virtual void SetUp(){} ;
			virtual void TearDown(){} ;
	};
}


class PosixThread4ITest : public PosixThread
{
	FRIEND_WITH_F
	public:
		PosixThread4ITest(std::string nameOfThread) : PosixThread(), name(nameOfThread)
		{
			counter=0;
			std::cout<<"PosixThread4ITest "<<name<<" Constructor\n" ;
		}
		virtual ~PosixThread4ITest()
		{
			std::cout<<"PosixThread4ITest "<<name<<" Destructor\n" ;
		}
	protected:
		virtual void Work()
		{
			std::cout<<"PosixThread4ITest "<<name<<" working: #"<<counter++<<"\n" ;
		}
	private:
		long long unsigned int counter ;
		const std::string name ;
};

#endif // POSIXTHREADTEST_H
//posix_thread_test.cpp
#include "posix_thread_test.h"

TEST(PosixThreadTest, ThreeThreads)
{
	PosixThread4ITest p1("thread1") ;
	PosixThread4ITest p2("thread2") ;
	p1.SetDelay(500000) ;
	p2.SetDelay(800000) ;
	std::cout<<"Start threads.\n";
	p1.Start() ;
	p2.Start() ;
	std::cout<<"Started.\n";	
	std::cout<<"Waiting for 5 secs.\n" ;
	sleep(5) ;	
	std::cout<<"Stop.\n" ;
	p1.Stop() ;
	p2.Stop() ;
	std::cout<<"Stopped.\n" ;
	std::cout<<"Done.\n" ;
}

Wszystko działa, ale gdy chcę sprawdzić valgrindem czy są wycieki pamięci, zawsze, niezależnie od ilości wątków, wskazuje mi, że 28 bajtów jest "still reachable":

valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./Tests
==4100== Memcheck, a memory error detector
==4100== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==4100== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==4100== Command: ./IntegrationTests
==4100== 
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from PosixThreadTest
[ RUN      ] PosixThreadTest.ThreeThreads
PosixThread4ITest thread1 Constructor
PosixThread4ITest thread2 Constructor
Start threads.
PosixThread4ITest thread1 working: #0
PosixThread4ITest thread2 working: #0
Started.
Waiting for 5 secs.
PosixThread4ITest thread1 working: #1
PosixThread4ITest thread2 working: #1
PosixThread4ITest thread1 working: #2
PosixThread4ITest thread1 working: #3
PosixThread4ITest thread2 working: #2
PosixThread4ITest thread1 working: #4
PosixThread4ITest thread2 working: #3
PosixThread4ITest thread1 working: #5
PosixThread4ITest thread1 working: #6
PosixThread4ITest thread2 working: #4
PosixThread4ITest thread1 working: #7
PosixThread4ITest thread2 working: #5
PosixThread4ITest thread1 working: #8
PosixThread4ITest thread1 working: #9
PosixThread4ITest thread2 working: #6
PosixThread4ITest thread1 working: #10
Stop.
PosixThread4ITest thread2 working: #7
Stopped.
Done.
PosixThread4ITest thread2 Destructor
PosixThread4ITest thread1 Destructor
[       OK ] PosixThreadTest.ThreeThreads (6545 ms)
[----------] 1 test from PosixThreadTest (6580 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (6675 ms total)
[  PASSED  ] 1 test.
==4100== 
==4100== HEAP SUMMARY:
==4100==     in use at exit: 28 bytes in 1 blocks
==4100==   total heap usage: 288 allocs, 287 frees, 56,272 bytes allocated
==4100== 
==4100== 28 bytes in 1 blocks are still reachable in loss record 1 of 1
==4100==    at 0x4024F20: malloc (vg_replace_malloc.c:236)
==4100==    by 0x400C37E: _dl_map_object_deps (dl-deps.c:506)
==4100==    by 0x4011BA0: dl_open_worker (dl-open.c:262)
==4100==    by 0x400D7E5: _dl_catch_error (dl-error.c:178)
==4100==    by 0x40115E5: _dl_open (dl-open.c:554)
==4100==    by 0x429E4A1: do_dlopen (dl-libc.c:86)
==4100==    by 0x400D7E5: _dl_catch_error (dl-error.c:178)
==4100==    by 0x429E5A0: dlerror_run (dl-libc.c:47)
==4100==    by 0x429E6BA: __libc_dlopen_mode (dl-libc.c:160)
==4100==    by 0x4053B46: pthread_cancel_init (unwind-forcedunwind.c:53)
==4100==    by 0x4053CBC: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
==4100==    by 0x4051787: __pthread_unwind (unwind.c:130)
==4100== 
==4100== LEAK SUMMARY:
==4100==    definitely lost: 0 bytes in 0 blocks
==4100==    indirectly lost: 0 bytes in 0 blocks
==4100==      possibly lost: 0 bytes in 0 blocks
==4100==    still reachable: 28 bytes in 1 blocks
==4100==         suppressed: 0 bytes in 0 blocks
==4100== 
==4100== For counts of detected and suppressed errors, rerun with: -v
==4100== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 20 from 7)

Niby nie ma wycieków, tylko to "still reachable", ale chciałbym mieć wszystko na czysto. Czy ktoś jest w stanie powiedzieć w którym miejscu kodu mogę mieć błąd?

Komentowałem kawałkami kod i te "stiil reachable" bajty występują tylko wtedy, gdy się wywoła funkcję Start() - czyli gdzieś tam musi być zły kod.

0

Nie pamiętam czy jest, ale spróbuj w destruktorze wywołać pthread_delete.

1 użytkowników online, w tym zalogowanych: 0, gości: 1