解决mysql connector重复使用时在SSL内部出现非法的问题

最近在写一个DBEngine,其内部封装了mysql的一些api操作,在写测试用例时发现如果包含多个测试用例组(TestSuite),会在执行第二个测试用例时在Mutex::Lock::Lock(mysql-connector-c-path\extra\yassl\src\lock.cpp, 47)处抛出异常,且this指针为nullptr堆栈如下:

1
2
3
4
5
6
7
8
9
10
11
12
 	ntdll.dll!00007ffd35b7b40d()	Unknown
> libmysql_d.dll!yaSSL::Mutex::Lock::Lock(yaSSL::Mutex & lm) Line 47 C++
libmysql_d.dll!yaSSL::Sessions::lookup(const unsigned char * id, yaSSL::SSL_SESSION * copy) Line 1829 C++
libmysql_d.dll!yaSSL_get_session(yaSSL::SSL * ssl) Line 513 C++
libmysql_d.dll!ssl_do(st_VioSSLFd * ptr, st_vio * vio, long timeout, int(*)(SSL *) func, unsigned long * ssl_errno_holder) Line 402 C
libmysql_d.dll!sslconnect(st_VioSSLFd * ptr, st_vio * vio, long timeout, unsigned long * ssl_errno_holder) Line 502 C
libmysql_d.dll!cli_establish_ssl(st_mysql * mysql) Line 3591 C
libmysql_d.dll!mysql_real_connect(st_mysql * mysql, const char * host, const char * user, const char * passwd, const char * db, unsigned int port, const char * unix_socket, unsigned long client_flag) Line 4774 C
DBEngine.dll!CMysqlConn::Connect() Line 41 C++
DBEngine.dll!CGeneralQueryTask::OnExecute(dbengine::IDBPool * pDBPool) Line 43 C++
DBEngine.dll!CDBThread::OnThreadRun() Line 35 C++
DBEngine.dll!CThreadBase::StartThread::__l2::<lambda>() Line 20 C++

回到yaSSL_get_session这一帧,可以确定是GetSessions()返回了空指针。查看GetSessions代码,以及结合yassl_pthread_once宏定义可以发现,c_session_initialize函数在整个运行时只执行了一次,执行标识由session_created记录,其最终调用Session_initializesessionsInstance生成一个对象,sessionsInstanceyaSSL_CleanUp函数内释放。
问题在于session_created标识没有随着sessionsInstance释放而重置,导致下一次执行到GetSessions时不会再重新生成Sessions对象。解决办法是在yaSSL_CleanUp函数内增加session_created重置操作。如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
extern "C" void yaSSL_CleanUp()
{
TaoCrypt::CleanUp();
yaSSL::ysDelete(yaSSL::sslFactoryInstance);
yaSSL::ysDelete(yaSSL::sessionsInstance);
yaSSL::ysDelete(yaSSL::errorsInstance);

// In case user calls more than once, prevent seg fault
yaSSL::sslFactoryInstance = 0;
yaSSL::sessionsInstance = 0;
yaSSL::errorsInstance = 0;
yaSSL::session_created = YASSL_PTHREAD_ONCE_INIT;
}

文章目录