发现了一个ODBC gbase8s内存泄漏问题 确认一下
void testgbase8s()
{
//根据db_type构造gbase连接字符串
SQLHENV hEnv = NULL;
SQLHDBC hDbc = NULL;
SQLRETURN retcode;
// 分配环境句柄
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
// 设置环境属性
SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
// 分配连接句柄
SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);
// 连接字符串
SQLCHAR *connString = (SQLCHAR*)"DRIVER=/opt/GBASE/gbase/lib/cli/iclit09b.so;DLOC=zh_CN.57372;TDLL=/opt/GBASE/gbase/lib/esql/igo4a304.so;SKIPP=1;HOST=10.16.11.8;SERV=9088;SRVR=gbase01;DB=testdb;UID=dbtuser;PWD=GBase123$%;";
retcode = SQLDriverConnect(hDbc, NULL, (SQLCHAR *)(connString), SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
cout << "Connected to the database successfully!" << endl;
}
else {
cout << "Failed to connect to the database!" << endl;
printError11(SQL_HANDLE_DBC, hDbc);
}
nlohmann::json row;
std::string selectsql = "SELECT t1.tabname,t2.* FROM gbasedbt.systables t1 INNER JOIN gbasedbt.syscolumnsext t2 ON t1.tabid = t2.tabid WHERE t1.tabname = 'audit_log'";
SQLHSTMT hstmt;
int rc = SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hstmt);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
{
std::cout << "hstmt error" << std::endl;
}
//selectsql = "SELECT * FROM newtable;";
SQLExecDirect(hstmt, (SQLCHAR*)(selectsql.c_str()), SQL_NTS);
//// 从结果集中获取数据
while (SQLFetch(hstmt) != SQL_NO_DATA)
{
CHAR buffer[1024] = { 0 };
nlohmann::json row;
SQLSMALLINT columnCount;
SQLRETURN cc = SQLNumResultCols(hstmt, &columnCount);
SQLRETURN retcode;
SQLCHAR Sqlstate[6], Message[SQL_MAX_MESSAGE_LENGTH];
SQLINTEGER NativeError;
SQLSMALLINT TextLength;
for (SQLUSMALLINT i = 0; i < columnCount; ++i)
{
CHAR columnName[32] = { 0 };
SQLSMALLINT nameLen = 0;
SQLRETURN sqlret = SQLColAttribute(hstmt, i + 1, SQL_COLUMN_LABEL, columnName, sizeof(columnName), &nameLen, NULL);
if (sqlret == SQL_ERROR)
{
retcode = SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, 1, Sqlstate, &NativeError, Message, sizeof(Message), &TextLength);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
std::cout << "SQLSTATE: " << Sqlstate << std::endl;
std::cout << "Native Error: " << NativeError << std::endl;
std::cout << "Message: " << Message << std::endl;
}
}
if (SQLGetData(hstmt, i + 1, SQL_C_CHAR, buffer, sizeof(buffer), NULL) == SQL_SUCCESS)
{
printf("columnName=%s,buffer=%s", columnName, buffer);
if (strcasecmp(columnName, "colname") == 0)
{
row["field"] = buffer;
}
else if (strcasecmp(columnName, "coltypename") == 0)
{
row["type"] = buffer;
}
else if (strcasecmp(columnName, "collength") == 0)
{
row["size"] = buffer;
}
}
}
}
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
// 5. 关闭连接
SQLDisconnect(hDbc);
// 6. 释放连接句柄
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
// 7. 释放环境句柄
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}
int main()
{
for (int i = 0; i < 1; i++)
{
printf("第%d次连接", i);
testgbase8s();
}
return 0;
}

SQLColAttribute申请的堆内存没有释放 循环调用testgbase8s() 内存会一直增大 /opt/GBASE/gbase/lib/cli/iclit09b.so 是咱们官网提供的clientsdk安装的 请帮忙看看我这么调用是不是有问题 还是你们的模块里有内存泄漏
评论
#include
#include
#include
#ifndef NO_WIN32
#include
#include
#include
#endif /*NO_WIN32*/
#include "infxcli.h"
#include "dbcreate.h"
#define ERRMSG_LEN 200
SQLCHAR defDsn[] = "odbc_demo";
void printError(SQLSMALLINT handleType, SQLHANDLE handle) {
SQLCHAR sqlState[1024];
SQLCHAR message[1024];
SQLINTEGER nativeError;
SQLRETURN ret = SQLGetDiagRec(handleType, handle, 1, sqlState, &nativeError, message, sizeof(message), NULL);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
//cout << "SQLSTATE: " << sqlState << endl;
//cout << "Message: " << message << endl;
printf("SQLSTATE: %d\n", sqlState);
printf("Message: %d\n", message);
}
}
void testgbase8s()
{
//根据db_type构造gbase连接字符串
SQLHENV hEnv = NULL;
SQLHDBC hDbc = NULL;
SQLRETURN retcode;
// 分配环境句柄
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
// 设置环境属性
SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
// 分配连接句柄
SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);
// 连接字符串
//SQLCHAR *connString = (SQLCHAR*)"DRIVER=/gbase8s/3.3.0_2X4_1/ids/lib/cli/iclit09b.so;DLOC=zh_CN.utf8;TDLL=/gbase8s/3.3.0_2X4_1/ids/lib/esql/igo4a304.so;HOST=172.16.5.202;SERV=10224;SRVR=ol_gbasedbt1210_20240718181816;DB=hyqdb;UID=gbasedbt;PWD=Big4ifmx;";
SQLCHAR *connString = (SQLCHAR*)"DRIVER=/gbase8s/3.3.0_2X4_1/ids/lib/cli/iclit09b.so;TDLL=/gbase8s/3.3.0_2X4_1/ids/lib/esql/igo4a304.so;HOST=172.16.5.202;SERV=10224;SRVR=ol_gbasedbt1210_20240718181816;DB=hyqdb;UID=gbasedbt;PWD=Big4ifmx;";
retcode = SQLDriverConnect(hDbc, NULL, (SQLCHAR *)(connString), SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
//cout << retcode << endl;
printf("retcode = %d\n", retcode);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
//cout << "Connected to the database successfully!" << endl;
printf("Connected to the database successfully!\n");
}
else {
//cout << "Failed to connect to the database!" << endl;
printf("Failed to connect to the database!\n");
printError(SQL_HANDLE_DBC, hDbc);
}
// nlohmann::json row;
//std::string selectsql = "SELECT * from tt;";
char *selectsql = "SELECT * from tt;";
SQLHSTMT hstmt;
int rc = SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hstmt);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
{
//std::cout << "hstmt error" << std::endl;
printf("hstmt error\n");
}
//selectsql = "SELECT * FROM newtable;";
SQLExecDirect(hstmt, (SQLCHAR*)(selectsql), SQL_NTS);
//// 从结果集中获取数据
while (SQLFetch(hstmt) != SQL_NO_DATA)
{
CHAR buffer[1024] = { 0 };
// nlohmann::json row;
SQLSMALLINT columnCount;
SQLRETURN cc = SQLNumResultCols(hstmt, &columnCount);
SQLRETURN retcode;
SQLCHAR Sqlstate[6], Message[SQL_MAX_MESSAGE_LENGTH];
SQLINTEGER NativeError;
SQLSMALLINT TextLength;
SQLUSMALLINT i;
for (i = 0; i < columnCount; ++i)
{
CHAR columnName[32] = { 0 };
SQLSMALLINT nameLen = 0;
SQLRETURN sqlret = SQLColAttribute(hstmt, i + 1, SQL_COLUMN_LABEL, columnName, sizeof(columnName), &nameLen, NULL);
if (sqlret == SQL_ERROR)
{
retcode = SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, 1, Sqlstate, &NativeError, Message, sizeof(Message), &TextLength);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
//std::cout << "SQLSTATE: " << Sqlstate << std::endl;
//std::cout << "Native Error: " << NativeError << std::endl;
//std::cout << "Message: " << Message << std::endl;
printf("SQLSTATE: %s\n", Sqlstate);
}
}
if (SQLGetData(hstmt, i + 1, SQL_C_CHAR, buffer, sizeof(buffer), NULL) == SQL_SUCCESS)
{
printf("columnName=%s,buffer=%s", columnName, buffer);
if (strcasecmp(columnName, "colname") == 0)
{
// row["field"] = buffer;
}
else if (strcasecmp(columnName, "coltypename") == 0)
{
// row["type"] = buffer;
}
else if (strcasecmp(columnName, "collength") == 0)
{
// row["size"] = buffer;
}
}
}
}
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
// 5. 关闭连接
SQLDisconnect(hDbc);
// 6. 释放连接句柄
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
// 7. 释放环境句柄
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}
int main()
{
int i = 0;
for (i = 0; i < 1; i++)
{
//printf("第%d次连接", i);
testgbase8s();
}
return 0;
}
编译:
gcc -c -fsigned-char -DNO_WIN32 -O -I/gbase8s/3.3.0_2X4_1/ids/incl/cli -I/gbase8s/3.3.0_2X4_1/ids/incl/esql -I/gbase8s/3.3.0_2X4_1/ids/incl/dmi dbcreate.c
gcc -o dbcreate dbcreate.o -L/gbase8s/3.3.0_2X4_1/ids/lib/cli -L/gbase8s/3.3.0_2X4_1/ids/lib/esql -lifcli -lifdmr -L/gbase8s/3.3.0_2X4_1/ids/lib/esql -lifgls -lifglx -lm -lnsl
运行:
valgrind --tool=memcheck --leak-check=yes ./dbcreate
问题展示:
Connected to the database successfully!
columnName=c1,buffer=1==25799==
==25799== HEAP SUMMARY:
==25799== in use at exit: 18,399,127 bytes in 1,473 blocks
==25799== total heap usage: 2,207 allocs, 734 frees, 19,516,096 bytes allocated
==25799==
==25799== 8 bytes in 1 blocks are definitely lost in loss record 101 of 283
==25799== at 0x4C29BC3: malloc (vg_replace_malloc.c:299)
==25799== by 0x4EFCBD9: __SQLColAttributeW (in /gbase8s/3.3.0_2X4_1/ids/lib/cli/libifcli.so)
==25799== by 0x4EFE896: SQLColAttribute (in /gbase8s/3.3.0_2X4_1/ids/lib/cli/libifcli.so)
==25799== by 0x400C13: testgbase8s (in /gbase8s/3.3.0_2X4_1/ids/demo/cli/dbcreate)
==25799== by 0x400D25: main (in /gbase8s/3.3.0_2X4_1/ids/demo/cli/dbcreate)
==25799==
==25799== LEAK SUMMARY:
==25799== definitely lost: 8 bytes in 1 blocks
==25799== indirectly lost: 0 bytes in 0 blocks
==25799== possibly lost: 0 bytes in 0 blocks
==25799== still reachable: 18,399,119 bytes in 1,472 blocks
==25799== suppressed: 0 bytes in 0 blocks
==25799== Reachable blocks (those to which a pointer was found) are not shown.
==25799== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==25799==
==25799== For counts of detected and suppressed errors, rerun with: -v
==25799== Use --track-origins=yes to see where uninitialised values come from
==25799== ERROR SUMMARY: 514 errors from 58 contexts (suppressed: 0 from 0)
热门帖子
- 12025-12-01浏览数:182763
- 22023-05-09浏览数:25057
- 42023-09-25浏览数:18525
- 52020-05-11浏览数:17528