我用-fsanitize = address编译了我的代码,我收到了这个错误:
==11760==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x6020000050d0 in thread T5:
object passed to delete has wrong type:
size of the allocated type: 8 bytes;
size of the deallocated type: 1 bytes.
#0 0x7f25f2aee938 in operator delete(void*, unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/libasan.so.4+0xe1938)
#1 0x7f25f1c94de6 in sql::mysql::MySQL_ParamBind::clearParameters() (/usr/lib64/libmysqlcppconn.so.7+0x6bde6)
#2 0x7f25f1c8f0f2 in sql::mysql::MySQL_Prepared_Statement::closeIntern() (/usr/lib64/libmysqlcppconn.so.7+0x660f2)
#3 0x7f25f1c91f5c in sql::mysql::MySQL_Prepared_Statement::~MySQL_Prepared_Statement() (/usr/lib64/libmysqlcppconn.so.7+0x68f5c)
#4 0x7f25f1c92198 in sql::mysql::MySQL_Prepared_Statement::~MySQL_Prepared_Statement() (/usr/lib64/libmysqlcppconn.so.7+0x69198)
#5 0x555e98524892 in Job::process_job(sql::mysql::MySQL_Connection*) (/src/build/game_server+0x27c892)
#6 0x555e9842ecd5 in DbWorker::run_jobs_thread(int) /src/DbWorker.cpp:136
#7 0x555e984307d2 in DbWorker::run_thread(int) /src/DbWorker.cpp:115
#8 0x555e98425b94 in void std::__invoke_impl<void, void (DbWorker::*)(int), DbWorker*, int>(std::__invoke_memfun_deref, void (DbWorker::*&&)(int), DbWorker*&&, int&&) /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/include/g++-v7/bits/invoke.h:73
#9 0x555e98425b94 in std::__invoke_result<void (DbWorker::*)(int), DbWorker*, int>::type std::__invoke<void (DbWorker::*)(int), DbWorker*, int>(void (DbWorker::*&&)(int), DbWorker*&&, int&&) /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/include/g++-v7/bits/invoke.h:95
#10 0x555e98425b94 in decltype (__invoke((_S_declval<0ul>)(), (_S_declval<1ul>)(), (_S_declval<2ul>)())) std::thread::_Invoker<std::tuple<void (DbWorker::*)(int), DbWorker*, int> >::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/include/g++-v7/thread:234
#11 0x555e98425b94 in std::thread::_Invoker<std::tuple<void (DbWorker::*)(int), DbWorker*, int> >::operator()() /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/include/g++-v7/thread:243
#12 0x555e98425b94 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (DbWorker::*)(int), DbWorker*, int> > >::_M_run() /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/include/g++-v7/thread:186
#13 0x7f25f16fcf9d (/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/libstdc++.so.6+0xe0f9d)
#14 0x7f25f1edb979 in start_thread (/lib64/libpthread.so.0+0x7979)
#15 0x7f25f0df23ee in clone (/lib64/libc.so.6+0x1013ee)
0x6020000050d0 is located 0 bytes inside of 8-byte region [0x6020000050d0,0x6020000050d8)
allocated by thread T5 here:
#0 0x7f25f2aed3b8 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/libasan.so.4+0xe03b8)
#1 0x7f25f1c94272 in sql::mysql::MySQL_Prepared_Statement::setString(unsigned int, sql::SQLString const&) (/usr/lib64/libmysqlcppconn.so.7+0x6b272)
Thread T5 created by T0 here:
#0 0x7f25f2a44b2f in pthread_create (/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/libasan.so.4+0x37b2f)
#1 0x7f25f16fd2c4 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/libstdc++.so.6+0xe12c4)
#2 0x7ffe077cd9f7 (<unknown module>)
SUMMARY: AddressSanitizer: new-delete-type-mismatch (/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/libasan.so.4+0xe1938) in operator delete(void*, unsigned long)
生成的代码是:
bool Job::process_job(sql::Connection *c) {
try {
std::unique_ptr<sql::PreparedStatement> pstmt;
std::unique_ptr<sql::ResultSet> res;
pstmt.reset(c->prepareStatement(sql_select1));
pstmt->setString(1, player_id);
res.reset(pstmt->executeQuery());
while (res->next()) {
// Processing results...
}
} catch(sql::SQLException &) {
return false;
}
return true;
}
当unique_ptr超出范围并删除pstmt时,似乎会发生这种情况。 但它是什么?我做错了吗?
我用:
x86_64的-PC-Linux的GNU-7.3.0
mysql-connector-c ++ 1.1.6
glibc 2.26-r7
最有趣的事实是,相同的代码在没有问题和内存泄漏的情况下工作正常,系统上有相同的编译选项:
x86_64的-PC-Linux的GNU-7.3.0
mysql-connector-c ++ 1.1.6
glibc 2.23-r4