最近在写一个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_initialize
为sessionsInstance
生成一个对象,sessionsInstance
在yaSSL_CleanUp
函数内释放。
问题在于session_created
标识没有随着sessionsInstance
释放而重置,导致下一次执行到GetSessions
时不会再重新生成Sessions
对象。解决办法是在yaSSL_CleanUp
函数内增加session_created
重置操作。如下代码:1
2
3
4
5
6
7
8
9
10
11
12
13extern "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;
}