ABY icon indicating copy to clipboard operation
ABY copied to clipboard

Missing cleanup of threads

Open lenerd opened this issue 8 years ago • 2 comments

While testing my circuits I saw that with each invocation of ABY a few more threads were added to the process.

I traced the creation and joining of threads in the sha1 example:

  • 10 threads created
  • 6 thread joined

Here are the full call stacks:

./bin/sha1.exe -r 0
======================
calling pthread_create (1)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYSetup::Init() 0x111)[0x4f83a1]
./bin/sha1.exe(ABYSetup::ABYSetup(crypto*, unsigned int, e_role, e_mt_gen_alg) 0xdc)[0x4f81cc]
./bin/sha1.exe(ABYParty::Init() 0x74)[0x4e97d4]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x1f7)[0x4e9017]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (2)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYSetup::Init() 0x111)[0x4f83a1]
./bin/sha1.exe(ABYSetup::ABYSetup(crypto*, unsigned int, e_role, e_mt_gen_alg) 0xdc)[0x4f81cc]
./bin/sha1.exe(ABYParty::Init() 0x74)[0x4e97d4]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x1f7)[0x4e9017]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (3)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::Init() 0x11f)[0x4e987f]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x1f7)[0x4e9017]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (4)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::Init() 0x11f)[0x4e987f]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x1f7)[0x4e9017]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (5)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::EstablishConnection() 0x1a9)[0x4ea319]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x4fc)[0x4e931c]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (6)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::EstablishConnection() 0x1c6)[0x4ea336]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x4fc)[0x4e931c]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (7)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::EstablishConnection() 0x1e3)[0x4ea353]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x4fc)[0x4e931c]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (8)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::EstablishConnection() 0x200)[0x4ea370]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x4fc)[0x4e931c]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (9)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(OTExtSnd::start_send(unsigned int) 0x276)[0x483ce6]
./bin/sha1.exe(OTExtSnd::send(unsigned long, unsigned long, unsigned long, CBitVector**, snd_ot_flavor, rec_ot_flavor, unsigned int, MaskingFunction*) 0xee)[0x4839de]
./bin/sha1.exe(ABYSetup::ThreadRunIKNPSnd(unsigned int) 0x10d)[0x4f8e0d]
./bin/sha1.exe(ABYSetup::CWorkerThread::ThreadMain() 0x81)[0x4f9d21]
./bin/sha1.exe(CThread::ThreadMainHandler(void*) 0x1e)[0x481f9e]
/usr/lib/libpthread.so.0( 0x7454)[0x7fdff0732454]
/usr/lib/libc.so.6(clone 0x5f)[0x7fdfef2e07df]
======================
======================
calling pthread_create (10)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(OTExtRec::start_receive(unsigned int) 0x270)[0x47f6b0]
./bin/sha1.exe(OTExtRec::receive(unsigned long, unsigned long, unsigned long, CBitVector*, CBitVector*, snd_ot_flavor, rec_ot_flavor, unsigned int, MaskingFunction*) 0x100)[0x47f3b0]
./bin/sha1.exe(ABYSetup::ThreadRunIKNPRcv(unsigned int) 0x106)[0x4f8f76]
./bin/sha1.exe(ABYSetup::CWorkerThread::ThreadMain() 0x99)[0x4f9d39]
./bin/sha1.exe(CThread::ThreadMainHandler(void*) 0x1e)[0x481f9e]
/usr/lib/libpthread.so.0( 0x7454)[0x7fdff0732454]
/usr/lib/libc.so.6(clone 0x5f)[0x7fdfef2e07df]
======================
======================
calling pthread_join (9)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(OTExtSnd::start_send(unsigned int) 0x2fc)[0x483d6c]
./bin/sha1.exe(OTExtSnd::send(unsigned long, unsigned long, unsigned long, CBitVector**, snd_ot_flavor, rec_ot_flavor, unsigned int, MaskingFunction*) 0xee)[0x4839de]
./bin/sha1.exe(ABYSetup::ThreadRunIKNPSnd(unsigned int) 0x10d)[0x4f8e0d]
./bin/sha1.exe(ABYSetup::CWorkerThread::ThreadMain() 0x81)[0x4f9d21]
./bin/sha1.exe(CThread::ThreadMainHandler(void*) 0x1e)[0x481f9e]
/usr/lib/libpthread.so.0( 0x7454)[0x7fdff0732454]
/usr/lib/libc.so.6(clone 0x5f)[0x7fdfef2e07df]
======================
======================
calling pthread_join (10)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(OTExtRec::start_receive(unsigned int) 0x2f6)[0x47f736]
./bin/sha1.exe(OTExtRec::receive(unsigned long, unsigned long, unsigned long, CBitVector*, CBitVector*, snd_ot_flavor, rec_ot_flavor, unsigned int, MaskingFunction*) 0x100)[0x47f3b0]
./bin/sha1.exe(ABYSetup::ThreadRunIKNPRcv(unsigned int) 0x106)[0x4f8f76]
./bin/sha1.exe(ABYSetup::CWorkerThread::ThreadMain() 0x99)[0x4f9d39]
./bin/sha1.exe(CThread::ThreadMainHandler(void*) 0x1e)[0x481f9e]
/usr/lib/libpthread.so.0( 0x7454)[0x7fdff0732454]
/usr/lib/libc.so.6(clone 0x5f)[0x7fdfef2e07df]
======================
Plaintext output: 
dc2172e79fae05b55178d431cd03262b0b45270
Testing SHA1 hash in Bool sharing: 
(0) Server Input:	fde4fbae4a09e020eff722969f83832b141cb2193eab67101d177fa95249c8ca
(0) Client Input:	de63b7f21d2a67d8b91953b9ea3bc26e78c5ccba10c7bff05dbee6ce8ccff78c
(0) Circ:	dc2172e709fae05b55178d431cd03262b0b45270
(0) Verify:	dc2172e709fae05b55178d431cd03262b0b45270
======================
calling pthread_join (3)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(ABYParty::Cleanup() 0x275)[0x4eaa15]
./bin/sha1.exe(ABYParty::~ABYParty() 0x39)[0x4ea6a9]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xa88)[0x4720f8]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_join (4)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(ABYParty::Cleanup() 0x275)[0x4eaa15]
./bin/sha1.exe(ABYParty::~ABYParty() 0x39)[0x4ea6a9]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xa88)[0x4720f8]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_join (5)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(SndThread::~SndThread() 0x2d)[0x4f16bd]
./bin/sha1.exe(SndThread::~SndThread() 0x19)[0x4f1739]
./bin/sha1.exe(ABYParty::Cleanup() 0x320)[0x4eaac0]
./bin/sha1.exe(ABYParty::~ABYParty() 0x39)[0x4ea6a9]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xa88)[0x4720f8]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_join (6)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(SndThread::~SndThread() 0x2d)[0x4f16bd]
./bin/sha1.exe(SndThread::~SndThread() 0x19)[0x4f1739]
./bin/sha1.exe(ABYParty::Cleanup() 0x34a)[0x4eaaea]
./bin/sha1.exe(ABYParty::~ABYParty() 0x39)[0x4ea6a9]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xa88)[0x4720f8]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================

One problem: While SndThread joins the underlying thread on destruction, RcvThread does not do so.

Destructor of SndThread

	~SndThread() {
		kill_task();
		this->Wait();
	}
	;

Destructor of RcvThread

	~RcvThread() {
		//this->Kill();
		delete rcvlock;
		free(listeners);
	}
	;

lenerd avatar Mar 09 '17 17:03 lenerd

The missing Kill() in RcvThread has been uncommented in 9b4fc258cee5293b9be4f7f09cd1168724563cc3, but this probably needs more careful investigation.

dd23 avatar Apr 18 '17 02:04 dd23

I'm not sure, this does, what is intended. I am assuming, the RcvThread objects were created by some kind of control thread. When these objects are destructed, CTread::Kill() is called, which in turn calls pthread_exit(NULL);

The pthread_exit() function terminates the calling thread and returns a value via retval that (if the thread is joinable) is available to another thread in the same process that calls pthread_join(3).

If I understand it correctly, the control thread is terminated, when it tries to destroy a RcvThread object. The TerminateThread() in the Windows implementation of CThread::Kill() however does terminate a different thread.

My guess is, that in ~RcvThread() the method this->Wait() should be called instead. This does a pthread_join() and waits until the ThreadMain() method exits, which happens after receiving the kill message generated by the sender's kill_task().

lenerd avatar Apr 18 '17 08:04 lenerd