Closed iabyn closed 4 years ago
Thanks @iabyn,
I thought I'd already run DB_File through Address Sanatizer without finding anything. May have been an older version.
Could you share the Address Sanatizer settings you were using and I'll see if I can reproduce the issue?
On Fri, Jan 03, 2020 at 05:53:42AM -0800, Paul Marquess wrote:
Thanks @iabyn,
I thought I'd already run DB_File through Address Sanatizer without finding anything. May have been an older version.
Could you share the Address Sanatizer settings you were using and I'll see if I can reproduce the issue?
With my current directory being /home/davem/perl5/git/bleed/, I'm using bleadperl configured as:
config_args='-des -Dusedevel -Dprefix=/home/davem/perl5/git/bleed.out -Uinstallusrbinperl -Duseithreads -Doptimize=-g -Accflags=-DDEBUGGING -ggdb -fsanitize=address -Werror=declaration-after-statement -fno-omit-frame-pointer -fno-common -fsanitize-blacklist=/home/davem/perl5/git/bleed/asan_ignore -Aldflags=-fsanitize=address -Dcc=clang'
Then invoking as:
$ PERL_DESTRUCT_LEVEL=2 ./perl -Ilib t/harness cpan/DB_File/t/*.t
Running one test file gave:
================================================================= ==3659==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 1456 byte(s) in 1 object(s) allocated from:
#1 0x7f33292ee1f4 in __os_malloc (/lib64/libdb-5.3.so+0x15c1f4)
#2 0x61d00005467f (<unknown module>)
Indirect leak of 2088 byte(s) in 1 object(s) allocated from:
#1 0x7f33292ee1f4 in __os_malloc (/lib64/libdb-5.3.so+0x15c1f4)
#2 0x620000000c07 (<unknown module>)
Indirect leak of 1656 byte(s) in 7 object(s) allocated from:
#1 0x7f33292ee1f4 in __os_malloc (/lib64/libdb-5.3.so+0x15c1f4)
#2 0x744b3ec4448fc3ff (<unknown module>)
Indirect leak of 32 byte(s) in 1 object(s) allocated from:
#1 0x7f33292ee1f4 in __os_malloc (/lib64/libdb-5.3.so+0x15c1f4)
SUMMARY: AddressSanitizer: 5232 byte(s) leaked in 10 allocation(s).
With my patch, all the errors went away.
-- Modern art: "That's easy, I could have done that!" "Ah, but you didn't!"
Thanks @iabyn
Issue reproduced.
The leak can be triggered by with this code (taken from t/db-btree.t
use blib;
use DB_File;
# check that attempting to tie an array to a DB_BTREE will fail
my $filename = "xyz" ;
my @x ;
tie @x, 'DB_File', $filename, O_RDWR|O_CREAT, 0640, $DB_BTREE ;
unlink $filename ;
Get this error
=9990==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 1456 byte(s) in 1 object(s) allocated from:
#0 0x7f6146141448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
#1 0x7f614212d774 in __os_malloc (/usr/lib/x86_64-linux-gnu/libdb-5.3.so+0x147774)
#2 0x61d00005e67f (<unknown module>)
Indirect leak of 2120 byte(s) in 2 object(s) allocated from:
#0 0x7f6146141448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
#1 0x7f614212d774 in __os_malloc (/usr/lib/x86_64-linux-gnu/libdb-5.3.so+0x147774)
Indirect leak of 1656 byte(s) in 7 object(s) allocated from:
#0 0x7f6146141448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
#1 0x7f614212d774 in __os_malloc (/usr/lib/x86_64-linux-gnu/libdb-5.3.so+0x147774)
#2 0x80967fb4538a37ff (<unknown module>)
The issue is triggered by code in ParseOpenInfo
that first calls db_create
without any problem. It then checks that the SV that will be tied to is a reference to the correct type. In the sample code above it triggers this croak_and_free
.
if (!isHASH)
croak_and_free("DB_File can only tie an associative array to a DB_HASH database") ;
In croak_and_free
all the malloc'ed memory should be freed. Issue here is a successful call to db_create
needs to then call db_close
to free memory that Berkeley DB has allocated behind the scenes, In this case that isn't happening.
Fix included in DB_File 1.853. Closing issue
In bleadperl under Address Sanitizer, 3 of the test files (db-btree, db-hash, db-recno) report leaks. This appears to be because a croak doesn't close the recently-opened DB handle, thus not freeing its resources. The attached proof-of-concept diff makes the issue apparently go away (tested only on DB 5.3.28)
db_file.txt