OCCI getColumnListMetaData,terminateEnvironment 踩坑

项目中发现一个问题,用一个简单的例子描述下:

使用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 }
View Code

程序执行完显示如下错误:

 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 没有再报错。

有知道详情的大佬麻烦解释下!

posted on 2019-08-27 18:57  william-zou  阅读(740)  评论(0)    收藏  举报