Control: tags -1 pending
On Mon, 11 May 2026 01:05:19 +0000 Daniel Black wrote:
> Package: libodbcinst2
> Version: 2.3.12-2
> Severity: normal
> Tags: patch
> X-Debbugs-Cc: [email protected]
>
> After a dlclose the libodbcinst2 still has a dynamicly allocated
> ini cache and an allocation for the odbcinst logger.
>
> This causes problems with memory leak detection systems[1].
>
> I reported this upstream[2] with a simple fix.
>
> If you are up for carrying a patch[3] until next upstream release
> MariaDB's CI users, and other unixODBC users investigating memory leaks
> would be grateful.
>
> ref:
> [1] https://jira.mariadb.org/browse/MDEV-38838
> [2] https://github.com/lurcher/unixODBC/pull/234
> [3]
https://github.com/lurcher/unixODBC/commit/e545d3dd29c7290a70992c1b2b1de4f6219e1a6f
Thanks for reporting this bug upstream and for preparing a patch. Nick
has reverted parts of your patch in favour of a more portable solution.
I'm going to upload the delta of both of your patches without the
documentation hunks. See below.
As you are using Debian Stable, this patch will need to go through
proposed-stable-updates before it can land in Trixie.
Hugh
Description: Clear cached allocations on dlclose() in libodbcinst2
* Declare destructors at configure time.
* New libodbcinst2 symbol inst_logClose.
* Add inst_logClose() to close and clear ODBCINSTLog.
* Call inst_logClose() and __clear_ini_cache() on shared library closure.
Patch derived from upstream commits:
* e545d3dd29c7290a70992c1b2b1de4f6219e1a6f
* a2cecd22d0509bf550053e8b7d654936af4c7540
See also: https://github.com/lurcher/unixODBC/pull/234
Author: Daniel Black, Nick Gorham
Bug: https://github.com/lurcher/unixODBC/issues/130
Bug: https://github.com/lurcher/unixODBC/issues/207
Bug-Debian: https://bugs.debian.org/1136221
Last-Updated: 2026-05-14
diff --git a/configure.ac b/configure.ac
index 7f46912..1c73027 100644
--- a/configure.ac
+++ b/configure.ac
@@ -592,6 +592,20 @@ AC_CHECK_HEADERS(msql.h,[msql=true],
done
])
+dnl see if we can declare a destructor
+AC_MSG_CHECKING([if __attribute__((destructor)) works])
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([__attribute__((destructor))], [int x = 0;])],
+ [
+ AC_MSG_RESULT( yes )
+ AC_DEFINE([PORTABLE_DESTRUCTOR],[__attribute__((destructor))],[Declare
function as a destructor])
+ ],
+ [
+ AC_MSG_RESULT( no )
+ AC_DEFINE([PORTABLE_DESTRUCTOR],[],[Declare function as a destructor])
+ ]
+)
+
dnl AC_SUBST(all_includes)
dnl AC_SUBST(all_libraries)
diff --git a/odbcinst/SQLGetPrivateProfileString.c
b/odbcinst/SQLGetPrivateProfileString.c
index 35ebfed..8aa4914 100644
--- a/odbcinst/SQLGetPrivateProfileString.c
+++ b/odbcinst/SQLGetPrivateProfileString.c
@@ -327,6 +327,7 @@ static void save_ini_cache( int ret,
mutex_exit( &mutex_ini );
}
+PORTABLE_DESTRUCTOR
void __clear_ini_cache( void )
{
mutex_entry( &mutex_ini );
diff --git a/odbcinst/_logging.c b/odbcinst/_logging.c
index 6b53820..c63d18f 100644
--- a/odbcinst/_logging.c
+++ b/odbcinst/_logging.c
@@ -201,3 +201,15 @@ int inst_logClear( void )
return ret;
}
+PORTABLE_DESTRUCTOR
+void inst_logClose( void )
+{
+
+ local_mutex_entry();
+
+ if ( hODBCINSTLog ) {
+ logClose( hODBCINSTLog );
+ }
+
+ local_mutex_exit();
+}
diff --git a/odbcinst/odbcinst.exp b/odbcinst/odbcinst.exp
index 09d246a..4405f7e 100644
--- a/odbcinst/odbcinst.exp
+++ b/odbcinst/odbcinst.exp
@@ -84,4 +84,5 @@ iniPropertyNext
iniToUpper
iniValue
inst_logPushMsg
+inst_logClose
__clear_ini_cache