项目中发现一个问题,用一个简单的例子描述下:
使用OCCI 的getColumnListMetaData 获取一张表的内容,执行完报错:
1 int main(int argc, char* argv[]) 2 { 3 string program = argv[0]; 4 glogInit(); 5 Environment *env = NULL; 6 Connection *conn = NULL; 7 Statement *stmt = NULL; 8 ResultSet *rs = NULL; 9 int errNum; 10 string errMsg; 11 12 13 14 string username = "usr1"; 15 string password = "usr1"; 16 string connstring = "192.168.0.1:1521/orcl"; 17 env = Environment::createEnvironment(); 18 19 assert(env != NULL); 20 conn = env->createConnection(username,password,connstring); 21 if(!conn) 22 { 23 return -1; 24 } 25 26 27 Statement *pStmt = NULL; 28 string sqlStmt="select * from USER_TABLES"; 29 pStmt = conn->createStatement(sqlStmt); 30 ResultSet *pRs = pStmt->executeQuery(sqlStmt); 31 32 vector<MetaData> metafield = pRs->getColumnListMetaData(); 33 34 while(pRs->next()) { 35 for(int col =0;col <metafield.size();col++) 36 { 37 string reStr = pRs->getString(col + 1).empty() ? "" : pRs->getString(col + 1).c_str(); 38 cout<<" "<<reStr<<" "; 39 } 40 cout<<endl; 41 } 42 43 pStmt->closeResultSet(pRs); 44 env->terminateConnection(conn); 45 Environment::terminateEnvironment(env); 46 47 return 0; 48 }
程序执行完显示如下错误:
1 E0827 17:32:38.492885 30841 oracleconnector.cpp:40] *** Aborted at 1566898358 (unix time) try "date -d @1566898358" if you are using GNU date *** 2 E0827 17:32:38.494403 30841 oracleconnector.cpp:40] PC: @ 0x0 (unknown) 3 E0827 17:32:38.494635 30841 oracleconnector.cpp:40] *** SIGSEGV (@0x10) received by PID 30841 (TID 0x7feef115ae80) from PID 16; stack trace: *** 4 E0827 17:32:38.495303 30841 oracleconnector.cpp:40] @ 0x7feef0d605d0 (unknown) 5 E0827 17:32:38.504227 30841 oracleconnector.cpp:40] @ 0x7feeefc45cd2 kpuhhfre 6 E0827 17:32:38.511675 30841 oracleconnector.cpp:40] @ 0x7feeeedce5df OCIPHeapFree 7 E0827 17:32:38.512270 30841 oracleconnector.cpp:40] @ 0x7feef05b2974 oracle::occi::HeapAlloc<>::operator delete() 8 E0827 17:32:38.512823 30841 oracleconnector.cpp:40] @ 0x7feef05e024f _ZN6oracle4occi12MetaDataImplD9Ev 9 E0827 17:32:38.513456 30841 oracleconnector.cpp:40] @ 0x7feef05e027a oracle::occi::MetaDataImpl::~MetaDataImpl() 10 E0827 17:32:38.514011 30841 oracleconnector.cpp:40] @ 0x7feef05e011a oracle::occi::RefCounted::onZeroReferences() 11 E0827 17:32:38.514832 30841 oracleconnector.cpp:40] @ 0x7feef05e0137 oracle::occi::RefCounted::deleteRef() 12 E0827 17:32:38.515621 30841 oracleconnector.cpp:40] @ 0x7feef05b8079 _ZN6oracle4occi8ConstPtrINS0_12MetaDataImplEED9Ev 13 E0827 17:32:38.516194 30841 oracleconnector.cpp:40] @ 0x7feef05b8062 oracle::occi::ConstPtr<>::~ConstPtr() 14 E0827 17:32:38.516757 30841 oracleconnector.cpp:40] @ 0x7feef05b804d _ZN6oracle4occi3PtrINS0_12MetaDataImplEED9Ev 15 E0827 17:32:38.517264 30841 oracleconnector.cpp:40] @ 0x7feef05b803e oracle::occi::Ptr<>::~Ptr() 16 E0827 17:32:38.517736 30841 oracleconnector.cpp:40] @ 0x7feef05e06eb _ZN6oracle4occi8MetaDataD9Ev 17 E0827 17:32:38.518162 30841 oracleconnector.cpp:40] @ 0x7feef05e06dc oracle::occi::MetaData::~MetaData() 18 E0827 17:32:38.518338 30841 oracleconnector.cpp:40] @ 0x4128c2 std::_Destroy<>() 19 E0827 17:32:38.518527 30841 oracleconnector.cpp:40] @ 0x4127aa std::_Destroy_aux<>::__destroy<>() 20 E0827 17:32:38.518707 30841 oracleconnector.cpp:40] @ 0x41265d std::_Destroy<>() 21 E0827 17:32:38.518891 30841 oracleconnector.cpp:40] @ 0x4124f1 std::_Destroy<>() 22 E0827 17:32:38.519076 30841 oracleconnector.cpp:40] @ 0x412239 std::vector<>::~vector() 23 E0827 17:32:38.519229 30841 oracleconnector.cpp:40] @ 0x411d99 main 24 E0827 17:32:38.519829 30841 oracleconnector.cpp:40] @ 0x7feeecfe8495 __libc_start_main 25 E0827 17:32:38.520076 30841 oracleconnector.cpp:40] @ 0x40f5b9 (unknown) 26 E0827 17:32:38.520521 30841 oracleconnector.cpp:40] @ 0x0 (unknown)
排查代码发现,只要执行 Environment::terminateEnvironment(env); 该测试程序就出错
根据错误提示,是程序执行完,MetaData在析构时出错。 如果注释掉45行的Environment::terminateEnvironment(env); 该测试程序不会出错。
猜测是因为执行完main函数时,该函数开始释放函数栈,vector<MetaData> metafield 会销毁它所有的实例,此时Oracle 所有链接资源都已经被释放,metafield 应该是使用了Oracle 创建的指针,此时指针已经失效,因此发生段错误。
根据猜测,将31至43行加一对大括号,让其先释放vector 没有再报错。
有知道详情的大佬麻烦解释下!
浙公网安备 33010602011771号