Skip to content

Commit d253b27

Browse files
committed
MDEV-38838 Memory loss in CONNECT from handler::ha_rnd_init
This was a leak in unixODBC 2.3.14 where a cache was allocated but not returned. The LD_PRELOAD is so the resolution will be aware of the resolution for save_ini_cache that caused the leak. Alterates considered: 1. __clear_ini_cache in libodbcinst (2.3.12+) is an interface, for which there is no header define. A CMake would need to do full compile and link to check its existance. Workable, just wanted a simplier solution. It looked like it shoud be a better interface in unixODBC. 2. could skip asan tests on CONNECT/ODBC, but this is skipping coverage we want.
1 parent 8721a00 commit d253b27

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

mysql-test/lsan.supp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ leak:gnutls_x509_trust_list_init
1515
leak:gnutls_subject_alt_names_init
1616
leak:__gmp_default_allocate
1717
leak:__gmp_default_reallocate
18+
19+
# unixODBC leak
20+
leak:save_ini_cache

storage/connect/mysql-test/connect/suite.pm

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,51 @@ return "No CONNECT engine" unless $ENV{HA_CONNECT_SO} or
1010
return "Not run for embedded server" if $::opt_embedded_server and
1111
$ENV{HA_CONNECT_SO};
1212

13-
sub is_default { 1 }
13+
sub is_default { 1 }
14+
15+
# To allow the lsan suppression on unixodbc to work
16+
# the llvm-symbolizer needs to be are of the address
17+
# resolution even after the HA_CONNECT_SO has been dlclosed.
18+
19+
# Check OS and file existence
20+
if ($^O =~ /linux|darwin|unix/i && -x "/usr/bin/readelf")
21+
{
22+
my $asan_symbols = 0;
23+
my $file = $::plugindir . '/' . $ENV{HA_CONNECT_SO};
24+
25+
# Open readelf -s output and scan for __asan symbols
26+
open(my $sh, '-|', "readelf -s '$file'")
27+
or die "Failed to run readelf: $!\n";
28+
while (<$sh>) { $asan_symbols = 1 if /__asan/; }
29+
close($sh);
30+
31+
if ($asan_symbols && -x "/usr/bin/ldd")
32+
{
33+
# To allow the lsan suppression on unixodbc to work
34+
# the llvm-symbolizer needs to be aware of the address
35+
# resolution even after the HA_CONNECT_SO has been dlclosed.
36+
37+
my $lib_path;
38+
open(my $ldd, '-|', "ldd $file") or die "Failed to run ldd: $!";
39+
40+
while (<$ldd>)
41+
{
42+
chomp;
43+
# Example ldd line: libodbc.so.2 => /usr/lib/x86_64-linux-gnu/libodbc.so.2 (0x00007f...)
44+
if (/libodbc\.so(?:\.\d+)*\s+=>\s+(\S+)/)
45+
{
46+
$lib_path = $1;
47+
last; # stop after the first match
48+
}
49+
}
50+
close $ldd;
51+
52+
if ($lib_path)
53+
{
54+
$ENV{LD_PRELOAD} = $ENV{LD_PRELOAD} ? "$ENV{LD_PRELOAD}:$lib_path" : $lib_path;
55+
}
56+
}
57+
}
1458

1559
bless { };
1660

0 commit comments

Comments
 (0)