I have a fairly simple Win32 application (.cpp file source code attached) that uses OpenSSL 1.0.1l to send some GET requests in 2 threads. I am getting reports of Handle Leaks in C++ memory validator (see logs at bottom of email), but I can't find what is wrong with my code (if anything). The app appears to function perfectly and the memory doesn't appear to rise in task manager.. but I'm still worried about the Handle Leak reports. * It should be noted that even if I get rid of the threads all together and just call 2 functions for the GET requests, I still get these same leak reports. So I don't think its a thread related problem. Also, the reason I'm not using CRYPTO_set_locking_callback is because I am already using WaitForSingleObject and ReleaseMutex to make sure its impossible for two threads to be running at the same time. Unless I'm missing something, CRYPTO_set_locking_callback is not needed due to the way I coded this. Can someone please verify if the code is thread safe, and comment regarding what might be causing these handle leaks? Maybe it is nothing to be worried about -- not sure.. Are there any other problems you see in the code? Perhaps missing cleanup functions? Or is everything OK and I'm just over analyzing this? Thanks for any tips! Best Regards, -Avery Address / Handle: 0x0000C001 shmem-win32.c sslleak.exe Atom 0 bytes Thread ID: 6736 1/22 18:48:09 990ms (Lifetime:00:01:45:503ms) Sequence: 11 sslleak.exe ___shmem_grab : [shmem-win32.c Line 0] sslleak.exe _fc_key_init_once : [unwind-sjlj.c Line 0] sslleak.exe _main : [crt0_c.c Line 0] sslleak.exe ___tmainCRTStartup : [crtexe.c Line 0] kernel32.dll BaseThreadInitThunk : [{FUNC}BaseThreadInitThunk Line 0] ntdll.dll RtlInitializeExceptionChain : [{FUNC}RtlInitializeExceptionChain Line 0] Address / Handle: 0x0000C00F shmem-win32.c sslleak.exe Atom 0 bytes Thread ID: 6736 1/22 18:48:09 990ms (Lifetime:00:02:29:683ms) Sequence: 97 sslleak.exe ___shmem_grab : [shmem-win32.c Line 0] sslleak.exe ___shmem_grab : [shmem-win32.c Line 0] Address / Handle: 0x0000C016 shmem.c sslleak.exe Atom 0 bytes Thread ID: 6736 1/22 18:48:09 990ms (Lifetime:00:03:02:693ms) Sequence: 143 sslleak.exe ___shmem_winpthreads_grab : [shmem.c Line 0] sslleak.exe ___shmem_winpthreads_grab : [shmem.c Line 0] sslleak.exe ___shmem_winpthreads_grab : [shmem.c Line 0] sslleak.exe ___shmem_winpthreads_grab : [shmem.c Line 0] sslleak.exe ___shmem_winpthreads_grab : [shmem.c Line 0] sslleak.exe ___shmem_winpthreads_grab : [shmem.c Line 0] Address / Handle: 0x0000C009 shmem.c sslleak.exe Atom 0 bytes Thread ID: 6736 1/22 18:48:09 990ms (Lifetime:00:03:22:364ms) Sequence: 61 sslleak.exe ___shmem_winpthreads_grab : [shmem.c Line 0] sslleak.exe _mutex_static_init : [mutex.c Line 0] sslleak.exe _pop_pthread_mem : [thread.c Line 0] sslleak.exe _pop_pthread_mem : [thread.c Line 0] -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mta.openssl.org/pipermail/openssl-users/attachments/20150122/7ec1188f/attachment.html> -------------- next part -------------- #include <windows.h> #include <stdio.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/engine.h> #include <openssl/conf.h> #include <winsock.h> #include <string> HANDLE sslmutex=0; int checks(X509_STORE_CTX *c, void *v) { return 1; } void SSLGO_111() { SSL_CTX *myct; myct = SSL_CTX_new(TLSv1_2_method()); if(myct==NULL) { ERR_remove_state(0); return; } SSL_CTX_set_verify(myct,SSL_VERIFY_PEER, NULL); SSL_CTX_set_cert_verify_callback(myct, checks, "K"); std::string http_resp; std::string headers="GET /111 HTTP/1.1\r\nHost: removed.com\r\nAccept: */*\r\nUser-Agent: Test\r\n\r\n"; X509 *pcc=0; SSL *thessl=0; BIO *bcc = NULL; char buf[513]; int ret; bcc = BIO_new_connect("removed.com:443"); if (!bcc) { goto sslend; } if (BIO_do_connect(bcc)<=0) { goto sslend; } thessl=SSL_new(myct); if (!thessl ) { goto sslend; } SSL_set_bio(thessl, bcc, bcc); if (SSL_connect(thessl)<=0) { goto sslend; } pcc=SSL_get_peer_certificate(thessl); if(pcc==NULL) { goto sslend; } ret=SSL_write(thessl, headers.c_str(),headers.length()); if(ret<0) { goto sslend; } while(1) { memset(buf,0x0,sizeof(buf)); int r=SSL_read(thessl,buf,512); switch(SSL_get_error(thessl,r)) { case SSL_ERROR_SYSCALL: goto sslend; case SSL_ERROR_ZERO_RETURN: goto sslend; case SSL_ERROR_NONE: http_resp+=buf; break; default: ; } } sslend: if(pcc) { X509_free(pcc); } if (thessl) { SSL_shutdown(thessl); SSL_free(thessl); } else if (bcc) { BIO_free(bcc); } if(myct) { SSL_CTX_free(myct); } ERR_remove_state(0); } void SSLGO_222() { SSL_CTX *myct; myct = SSL_CTX_new(TLSv1_2_method()); if(myct==NULL) { ERR_remove_state(0); return; } SSL_CTX_set_verify(myct,SSL_VERIFY_PEER, NULL); SSL_CTX_set_cert_verify_callback(myct, checks, "K"); std::string http_resp; std::string headers="GET /222 HTTP/1.1\r\nHost: removed.com\r\nAccept: */*\r\nUser-Agent: Test\r\n\r\n"; X509 *pcc=0; SSL *thessl=0; BIO *bcc = NULL; char buf[513]; int ret; bcc = BIO_new_connect("removed.com:443"); if (!bcc) { goto sslend; } if (BIO_do_connect(bcc)<=0) { goto sslend; } thessl=SSL_new(myct); if (!thessl ) { goto sslend; } SSL_set_bio(thessl, bcc, bcc); if (SSL_connect(thessl)<=0) { goto sslend; } pcc=SSL_get_peer_certificate(thessl); if(pcc==NULL) { goto sslend; } ret=SSL_write(thessl, headers.c_str(),headers.length()); if(ret<0) { goto sslend; } while(1) { memset(buf,0x0,sizeof(buf)); int r=SSL_read(thessl,buf,512); switch(SSL_get_error(thessl,r)) { case SSL_ERROR_SYSCALL: goto sslend; case SSL_ERROR_ZERO_RETURN: goto sslend; case SSL_ERROR_NONE: http_resp+=buf; break; default: ; } } sslend: if(pcc) { X509_free(pcc); } if (thessl) { SSL_shutdown(thessl); SSL_free(thessl); } else if (bcc) { BIO_free(bcc); } if(myct) { SSL_CTX_free(myct); } ERR_remove_state(0); } DWORD __stdcall thread1(LPVOID l) { while(1) { WaitForSingleObject(sslmutex,INFINITE); SSLGO_222(); ReleaseMutex(sslmutex); Sleep(100); } } DWORD __stdcall thread2(LPVOID l) { while(1) { WaitForSingleObject(sslmutex,INFINITE); SSLGO_111(); ReleaseMutex(sslmutex); Sleep(100); } } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { DWORD t1; DWORD t2; sslmutex=CreateMutex(NULL,false,NULL); if(sslmutex==NULL) { return 0; } SSL_library_init(); SSL_load_error_strings(); HANDLE h1=0; HANDLE h2=0; h1=CreateThread(0,0,thread1,0,0,&t1); if(h1==0) { return 0; } h2=CreateThread(0,0,thread2,0,0,&t1); if(h2==0) { return 0; } while(1) { Sleep(1000); } // IMPORTANT ****************** // Even if I do this and comment out the 2 CreateThreads above, I still get the same Handle Leak reports... so it doesn't appear to be anything relate to // a thread problem /* while(1) { SSLGO_111(); SSLGO_222(); Sleep(1000); } */ }