Bug #93593 | ODBC memory leak | ||
---|---|---|---|
Submitted: | 13 Dec 2018 14:36 | Modified: | 1 Jun 2020 3:58 |
Reporter: | Bhargava Srinarasi | Email Updates: | |
Status: | No Feedback | Impact on me: | |
Category: | Connector / ODBC | Severity: | S2 (Serious) |
Version: | 8.0.13 | OS: | Windows |
Assigned to: | CPU Architecture: | Any | |
Tags: | memory leak |
[13 Dec 2018 14:36]
Bhargava Srinarasi
[1 May 2020 3:58]
MySQL Verification Team
Please try version 8.0.20. Thanks.
[14 May 2020 16:56]
Leigh Anderson
I still have this issue in 8.0.20. If I use 5.3.14 there is no leak.
[2 Jun 2020 1:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".
[6 Jun 2020 10:08]
Leigh Anderson
I still have this issue with the 8.0.20 driver. If I use the 5.3.14 driver there is no leak.
[29 Mar 2022 12:08]
c t
still existing in mysql-connector-odbc-noinstall-8.0.28-win32 this bug is happening during load/unload of the driver dll. when you use debugger in VS2017 you can see relation between load/alloc and unload/NO free. VS2017 code used for verification and analysis: // NOTE: Use Multi-Byte Character Set // tested with latest ODBC driver // see output for unload/load // 'memleak_test.exe' (Win32) : Unloaded 'C:\mysql-connector-odbc-noinstall-8.0.28-win32\lib\myodbc8w.dll' // 'memleak_test.exe' (Win32) : Loaded 'C:\mysql-connector-odbc-noinstall-8.0.28-win32\lib\myodbc8w.dll'.Symbols loaded. // REDUCED_OUTPUT can be used to prevent non error output of results of various odbc functions #define REDUCED_OUTPUT 0 // ODBC_DATASOURCE is the ODBC connection used, configured to MySQL ODBC Unicode driver #define ODBC_DATASOURCE "test_mycustomer" #include <iostream> #include <windows.h> #include <sqltypes.h> #include <sqlext.h> #include <psapi.h> #pragma comment(lib, "odbc32.lib") class MemleakTest { public: MemleakTest(const std::string &ds) : odbcDataSource(ds) {} ~MemleakTest() { disconnect(); } bool connect() { const auto envAllocResult = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv); #if !REDUCED_OUTPUT std::cout << "envAllocResult: " << envAllocResult << std::endl; #endif if (SQL_SUCCEEDED(envAllocResult)) { const auto setEnvAttrResult = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); #if !REDUCED_OUTPUT std::cout << "setEnvAttrResult: " << setEnvAttrResult << std::endl; #endif if (SQL_SUCCEEDED(envAllocResult)) { const auto hdbcAllocResult = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc); #if !REDUCED_OUTPUT std::cout << "hdbcAllocResult: " << hdbcAllocResult << std::endl; #endif if (SQL_SUCCEEDED(hdbcAllocResult)) { const auto setConnAttrResult = SQLSetConnectAttr(hDbc, SQL_LOGIN_TIMEOUT, (void*)5, 0); #if !REDUCED_OUTPUT std::cout << "setConnAttrResult: " << setConnAttrResult << std::endl; #endif if (SQL_SUCCEEDED(setConnAttrResult)) { // Connect to data source // const auto connectResult = SQLConnect(hDbc, (SQLCHAR*)odbcDataSource.c_str(), SQL_NTS, (SQLCHAR*) "", SQL_NTS, (SQLCHAR*) "", SQL_NTS); #if !REDUCED_OUTPUT std::cout << "connectResult: " << connectResult << std::endl; #endif if (SQL_SUCCEEDED(connectResult)) { #if !REDUCED_OUTPUT std::cout << "CONNECTED" << std::endl; #endif return true; } else { std::cerr << "SQLConnect failed: " << connectResult << std::endl; } } else { std::cerr << "SQLSetConnectAttr failed: " << setConnAttrResult << std::endl; } FreeHandle(SQL_HANDLE_DBC, hDbc); } else { std::cerr << "SQLAllocHandle hDbc failed: " << hdbcAllocResult << std::endl; } } else { std::cerr << "SQLSetEnvAttr failed: " << setEnvAttrResult << std::endl; } FreeHandle(SQL_HANDLE_ENV, hEnv); } else { std::cerr << "SQLAllocHandle HENV failed: " << envAllocResult << std::endl; } return false; } void disconnect() { if (hDbc) { const auto disconnectResult = SQLDisconnect(hDbc); #if !REDUCED_OUTPUT std::cout << "disconnectResult: " << disconnectResult << std::endl; #endif if (!SQL_SUCCEEDED(disconnectResult)) { std::cerr << "SQLDisconnect failed: " << disconnectResult << std::endl; } FreeHandle(SQL_HANDLE_DBC, hDbc); } if (hEnv) { FreeHandle(SQL_HANDLE_ENV, hEnv); } #if !REDUCED_OUTPUT std::cout << "DISCONNECTED" << std::endl; #endif } private: std::string odbcDataSource; SQLHANDLE hEnv = nullptr; SQLHANDLE hDbc = nullptr; bool FreeHandle(SQLSMALLINT type, SQLHANDLE &handle) { if (nullptr == handle) { std::cerr << "invalid handle given" << std::endl; return false; } const auto freeHandleResult = SQLFreeHandle(type, handle); if (!SQL_SUCCEEDED(freeHandleResult)) { std::cerr << "SQLFreeHandle(type " << type << ", handle " << handle << ") failed: " << freeHandleResult << std::endl; return false; } handle = nullptr; return true; } }; void printMemory() { const HANDLE hProcess = GetCurrentProcess(); PROCESS_MEMORY_COUNTERS pmc; if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) { printf("\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize); } CloseHandle(hProcess); } int main() { std::cout << "***START "; printMemory(); for (uint32_t counter = 0; counter < 500; ++counter) { MemleakTest memleakTest(ODBC_DATASOURCE); memleakTest.connect(); memleakTest.disconnect(); std::cout << "#" << counter; printMemory(); Sleep(500); // dont let firewall/server think its DDoS attack } std::cout << "***END "; printMemory(); return 0; }
[30 Mar 2022 15:32]
c t
Add.: used system: Edition Windows 10 Enterprise Version 20H2 OS build 19042.1586 Experience Windows Feature Experience Pack 120.2212.4170.0