AddressSanitizer warnings memory leaks occured when repeating connecting/disconnecting to a db with msodbcsql for linux both 17.10 and 18.1.
This may be same issue as this comment https://techcommunity.microsoft.com/t5/sql-server-blog/odbc-driver-17-6-for-sql-server-released/bc-p/1954999/highlight/true#M1658 .
I have a reproduction code.
My program repeats connecting and disconnecting to a db server.
pseud code
AllocHandle(hEnv)
AllocHandle(hDbc)
repeat N
Connect(hDbc)
Disconnect(hDbc)
FreeHandle(hDbc)
FeeHandle(hEnv)
When N > 1, AddressSanitizer outputs memory leak detections.
Also I tried like below and got same warnings.
repeat N
AllocHandle(hEnv)
AllocHandle(hDbc)
Connect(hDbc)
Disconnect(hDbc)
FreeHandle(hDbc)
FeeHandle(hEnv)
I want to know this is a false-positive detection or not.
Or, is there a workaround ?
Thank you.
The details are listed below.
Environment
OracleLinux 8.6
GCC11 with AddressSanitizer
Packages
$ dnf list --installed | grep gcc
gcc-toolset-11-binutils.x86_64 2.36.1-2.0.1.el8 @ol8_appstream
gcc-toolset-11-gcc.x86_64 11.2.1-9.1.0.2.el8 @ol8_appstream
gcc-toolset-11-gcc-c++.x86_64 11.2.1-9.1.0.2.el8 @ol8_appstream
gcc-toolset-11-libasan-devel.x86_64 11.2.1-9.1.0.2.el8 @ol8_appstream
gcc-toolset-11-libstdc++-devel.x86_64 11.2.1-9.1.0.2.el8 @ol8_appstream
gcc-toolset-11-runtime.x86_64 11.1-1.el8 @ol8_appstream
libgcc.x86_64 8.5.0-10.1.0.1.el8_6 @System
$ dnf list --installed | grep unixODBC
unixODBC.x86_64 2.3.7-1.rh @packages-microsoft-com-prod
unixODBC-devel.x86_64 2.3.7-1.rh @packages-microsoft-com-prod
$ dnf list --installed | grep msodbc
msodbcsql17.x86_64 17.10.1.1-1 @packages-microsoft-com-prod
msodbcsql18.x86_64 18.1.2.1-1 @packages-microsoft-com-prod
SourceCode
main.c
rewrite L56 when using.
#include <msodbcsql.h>
#include <sql.h>
#include <sqlext.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void HandleDiagnosticRecord(SQLHANDLE hHandle, SQLSMALLINT hType, RETCODE RetCode) {
SQLSMALLINT iRec = 0;
SQLINTEGER iError;
char wszMessage[1000];
char wszState[SQL_SQLSTATE_SIZE + 1];
if (RetCode == SQL_INVALID_HANDLE) {
fprintf(stderr, "Invalid handle!\n");
return;
}
while (SQLGetDiagRec(hType, hHandle, ++iRec, wszState, &iError, wszMessage,
(SQLSMALLINT)(sizeof(wszMessage) / sizeof(char)), (SQLSMALLINT *)NULL) == SQL_SUCCESS) {
// Hide data truncated..
if (strncmp(wszState, "01004", 5)) {
fprintf(stderr, "[%5.5s] %s (%d)\n", wszState, wszMessage, iError);
}
}
}
#define TRYODBC(h, ht, x) \
{ \
RETCODE rc = x; \
if (rc != SQL_SUCCESS) { \
HandleDiagnosticRecord(h, ht, rc); \
} \
if (rc == SQL_ERROR) { \
fprintf(stderr, "Error in " #x "\n"); \
goto Exit; \
} \
}
int main(void) {
SQLHENV hEnv = NULL;
SQLHDBC hDbc = NULL;
if (SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv) == SQL_ERROR) {
fprintf(stderr, "Unable to allocate an environment handle\n");
exit(-1);
}
TRYODBC(hEnv, SQL_HANDLE_ENV, SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0));
TRYODBC(hEnv, SQL_HANDLE_ENV, SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc));
const int LOOP = 2; // (LOOP - 1) * 24byte direct leak detected
for (int i = 0; i < LOOP; i++) {
const char *connStr = "CONNECTION STRING";
TRYODBC(hDbc, SQL_HANDLE_DBC,
SQLDriverConnect(hDbc, NULL, (SQLCHAR *)connStr, strlen(connStr), NULL, 0, NULL, SQL_DRIVER_NOPROMPT));
printf("Connected!\n");
TRYODBC(hDbc, SQL_HANDLE_DBC, SQLDisconnect(hDbc));
printf("Disconnected\n");
}
Exit:
if (hDbc) {
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
hDbc = NULL;
}
if (hEnv) {
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
hEnv = NULL;
}
return 0;
}
build and run
$ gcc main.c -std=c11 -I/opt/microsoft/msodbcsql18/include -lodbc -g -O0 -fsanitize=address -lasan -o main.o
$ ./main.o
[01000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Changed database context to 'master'. (5701)
[01000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Changed language setting to us_english. (5703)
Connected!
Disconnected
[01000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Changed database context to 'master'. (5701)
[01000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Changed language setting to us_english. (5703)
Connected!
Disconnected
=================================================================
==1103==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 24 byte(s) in 1 object(s) allocated from:
#0 0x7f8f00b21307 in operator new(unsigned long) (/lib64/libasan.so.6+0xb6307)
#1 0x7f8efbb5b2ca (/opt/microsoft/msodbcsql18/lib64/libmsodbcsql-18.1.so.2.1+0x1822ca)
Indirect leak of 88 byte(s) in 1 object(s) allocated from:
#0 0x7f8f00b21307 in operator new(unsigned long) (/lib64/libasan.so.6+0xb6307)
#1 0x7f8efbae3379 (/opt/microsoft/msodbcsql18/lib64/libmsodbcsql-18.1.so.2.1+0x10a379)
SUMMARY: AddressSanitizer: 112 byte(s) leaked in 2 allocation(s).