diff --git a/mysql-test/lib/My/Debugger.pm b/mysql-test/lib/My/Debugger.pm index fa40f297b2859..643389ca18b0c 100644 --- a/mysql-test/lib/My/Debugger.pm +++ b/mysql-test/lib/My/Debugger.pm @@ -84,6 +84,7 @@ my %debuggers = ( push @::global_suppressions, qr/InnoDB: native AIO failed/; ::mtr_error('rr requires kernel.perf_event_paranoid <= 1') if ::mtr_grab_file('/proc/sys/kernel/perf_event_paranoid') > 1; + $ENV{LSAN_OPTIONS}= "report_objects=1:" . ($ENV{LSAN_OPTIONS} || '') } }, valgdb => { diff --git a/mysql-test/lsan.supp b/mysql-test/lsan.supp index 3f460d4544edc..9724685325fa5 100644 --- a/mysql-test/lsan.supp +++ b/mysql-test/lsan.supp @@ -15,3 +15,6 @@ leak:gnutls_x509_trust_list_init leak:gnutls_subject_alt_names_init leak:__gmp_default_allocate leak:__gmp_default_reallocate + +# unixODBC leak +leak:save_ini_cache diff --git a/mysql-test/mariadb-test-run.pl b/mysql-test/mariadb-test-run.pl index 279168c4172cb..5166b23bbc8cd 100755 --- a/mysql-test/mariadb-test-run.pl +++ b/mysql-test/mariadb-test-run.pl @@ -1644,7 +1644,8 @@ sub command_line_setup { # $ENV{ASAN_OPTIONS}= "log_path=${opt_vardir}/log/asan:" . $ENV{ASAN_OPTIONS}; # Add leak suppressions - $ENV{LSAN_OPTIONS}= "suppressions=${glob_mysql_test_dir}/lsan.supp:print_suppressions=0" + $ENV{LSAN_OPTIONS}= "suppressions=${glob_mysql_test_dir}/lsan.supp:print_suppressions=0:" + . ($ENV{LSAN_OPTIONS} || '') if -f "$glob_mysql_test_dir/lsan.supp" and not IS_WINDOWS; mtr_verbose("ASAN_OPTIONS=$ENV{ASAN_OPTIONS}"); diff --git a/storage/connect/mysql-test/connect/suite.pm b/storage/connect/mysql-test/connect/suite.pm index 2dabbc82e7d46..e0f715eb1cffc 100644 --- a/storage/connect/mysql-test/connect/suite.pm +++ b/storage/connect/mysql-test/connect/suite.pm @@ -10,7 +10,63 @@ return "No CONNECT engine" unless $ENV{HA_CONNECT_SO} or return "Not run for embedded server" if $::opt_embedded_server and $ENV{HA_CONNECT_SO}; -sub is_default { 1 } +sub is_default { 1 } + +# To allow the lsan suppression on unixodbc to work +# the llvm-symbolizer needs to be are of the address +# resolution even after the HA_CONNECT_SO has been dlclosed. + +# Check OS and file existence +if ($^O =~ /linux|darwin|unix/i && -x "/usr/bin/readelf") +{ + my $asan_symbols = 0; + my $file = $::plugindir . '/' . $ENV{HA_CONNECT_SO}; + + # Open readelf -s output and scan for __asan symbols + open(my $sh, '-|', "readelf -s '$file'") + or die "Failed to run readelf: $!\n"; + while (<$sh>) { $asan_symbols = 1 if /__asan/; } + close($sh); + + if ($asan_symbols && -x "/usr/bin/ldd") + { + # To allow the lsan suppression on unixodbc to work + # the llvm-symbolizer needs to be aware of the address + # resolution even after the HA_CONNECT_SO has been dlclosed. + + my $lib_path; + open(my $ldd, '-|', "ldd $file") or die "Failed to run ldd: $!"; + + while (<$ldd>) + { + chomp; + # Example ldd line: libodbc.so.2 => /usr/lib/x86_64-linux-gnu/libodbc.so.2 (0x00007f...) + if (/libodbc\.so(?:\.\d+)*\s+=>\s+(\S+)/) + { + $lib_path = $1; + last; # stop after the first match + } + } + close $ldd; + + # assuming odbcinst is in the same path so we can check + # if it has fixed version. + my $libodbcinst = $lib_path; + $libodbcinst =~ s/odbc/odbcinst/; + my $leakfixed= 0; + if ( -f $libodbcinst ) + { + open(my $sh, '-|', "readelf -s '$libodbcinst'") + or die "Failed to run readelf: $!\n"; + while (<$sh>) { $leakfixed = 1 if /inst_logClose/; } + close($sh); + } + if (!$leakfixed && $lib_path) + { + $ENV{LD_PRELOAD} = $ENV{LD_PRELOAD} ? "$ENV{LD_PRELOAD}:$lib_path" : $lib_path; + } + } +} bless { };