Skip Menu |

This queue is for tickets about the LMDB_File CPAN distribution.

Report information
The Basics
Id: 99292
Status: resolved
Priority: 0/
Queue: LMDB_File

People
Owner: Nobody in particular
Requestors: KENTNL [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: 0.07



Subject: Anomalous SEGV during destruction

I've had a long running problem I've had a hard time isolating, and I'm triaging the little I have here in the event its useful.

And it only happens Multiple open transactions in multiple namespaces sharing the same ENV
 

If I tease them out into seperate ENVs, or if I create transactions only prior to making any changes ( ie: Opentxn, write, commit, continue .... instead of opentxn, ( do stuff ), closetxn at EXIT ) then the problem goes away, but both have reasonable performance penalties.

Unfortunately, I can't provide a concise test case that emulates this behaviour, only a very complicated stack of confusing parts that conspire to make the problem manifest:

 

https://metacpan.org/source/KENTNL/Dist-Zilla-PluginBundle-Author-KENTNL-2.020005/utils/dep_changes.pl

If I modify that script to have

single_txn => 1,

And return %args unmodified from xnamespace, then the problem occurs every time the script terminates, wether it created new entries or simply ran read-only.

Subject: backtrace.txt
Thread 1 (process 910291): #0 0x00007fffecf0fee9 in mdb_txn_commit (txn=0x91) at mdb.c:2942 rc = <optimized out> i = <optimized out> env = <optimized out> __FUNCTION__ = "mdb_txn_commit" #1 0x00007fffecf0ff00 in mdb_txn_commit (txn=0x7b2fb60) at mdb.c:2946 rc = <optimized out> i = <optimized out> env = <optimized out> __FUNCTION__ = "mdb_txn_commit" #2 0x00007fffecf0ff00 in mdb_txn_commit (txn=0x1c4e530) at mdb.c:2946 rc = <optimized out> i = <optimized out> env = <optimized out> __FUNCTION__ = "mdb_txn_commit" #3 0x00007fffed11d654 in XS_LMDB__Txn__commit (cv=<optimized out>) at LMDB.c:1030 txn = <optimized out> RETVAL = <optimized out> targ = 0x1791308 sp = <optimized out> ax = 1 mark = <optimized out> items = <optimized out> #4 0x00000000004c3827 in Perl_pp_entersub () at pp_hot.c:2784 markix = <optimized out> sp = <optimized out> sv = 0x17d0aa0 gv = 0x17912d8 cv = 0x17d0aa0 cx = <optimized out> gimme = 1 hasargs = <optimized out> #5 0x00000000004bce43 in Perl_runops_standard () at run.c:41 op = <optimized out> #6 0x000000000043c92b in Perl_call_sv (sv=sv@entry=0x1782b28, flags=<optimized out>, flags@entry=45) at perl.c:2727 sp = <optimized out> myop = {op_next = 0x0, op_sibling = 0x0, op_ppaddr = 0x0, op_targ = 0, op_type = 0, op_opt = 0, op_slabbed = 0, op_savefree = 0, op_static = 0, op_folded = 0, op_lastsib = 0, op_spare = 0, op_flags = 65 'A', op_private = 0 '\000', op_first = 0x0, op_other = 0x7fffffffc780} method_unop = {op_next = 0x7fffffffc890, op_sibling = 0x4b4abb <Perl_hv_common_key_len+43>, op_ppaddr = 0x0, op_targ = 0, op_type = 0, op_opt = 0, op_slabbed = 0, op_savefree = 0, op_static = 0, op_folded = 0, op_lastsib = 0, op_spare = 0, op_flags = 0 '\000', op_private = 0 '\000', op_first = 0x446122 <Perl_gv_fetchmeth_pvn+306>} method_svop = {op_next = 0x7d3db8, op_sibling = 0x9, op_ppaddr = 0x58b662, op_targ = 0, op_type = 368, op_opt = 0, op_slabbed = 1, op_savefree = 1, op_static = 0, op_folded = 1, op_lastsib = 0, op_spare = 0, op_flags = 185 '\271', op_private = 1 '\001', op_sv = 0x9} oldmark = 0 retval = 0 oldscope = 6 oldcatch = false ret = <optimized out> oldop = 0x1b23b30 cur_env = {je_prev = 0x7fffffffcac0, je_buf = {{__jmpbuf = {140737488340864, 603917217558303656, 24652584, 0, 15569528, 24652584, 603917217218565032, -603916680868654168}, __mask_was_saved = 0, __saved_mask = {__val = {8209552, 8, 5819933, 137438953504, 4294967296, 8209552, 8281856, 8282064, 0, 12498329130309844224, 8209552, 28681456, 7, 0, 5893883, 25146552}}}}, je_ret = 0, je_mustcatch = false} #7 0x00000000004ce96a in S_curse (sv=sv@entry=0x1a69ba0, check_refcnt=check_refcnt@entry=true) at sv.c:6688 destructor = 0x1782b28 sp = <optimized out> stash = 0x1782408 #8 0x00000000004cf2af in Perl_sv_clear (orig_sv=orig_sv@entry=0x1c205d8) at sv.c:6312 stash = <optimized out> type = 7 sv_type_details = <optimized out> iter_sv = 0x17fb3c8 next_sv = 0x0 sv = 0x1a69ba0 hash_index = 8 #9 0x00000000004cf662 in Perl_sv_free2 (sv=0x1c205d8, rc=<optimized out>) at sv.c:6789 No locals. #10 0x00000000004f2e75 in S_SvREFCNT_dec_NN (sv=<optimized out>) at inline.h:134 rc = <optimized out> #11 Perl_free_tmps () at scope.c:159 sv = <optimized out> myfloor = -1 #12 0x00000000004bd075 in Perl_pp_nextstate () at pp_hot.c:52 No locals. #13 0x00000000004bce43 in Perl_runops_standard () at run.c:41 op = <optimized out> #14 0x000000000043c92b in Perl_call_sv (sv=sv@entry=0x1355f80, flags=<optimized out>, flags@entry=13) at perl.c:2727 sp = <optimized out> myop = {op_next = 0x0, op_sibling = 0x0, op_ppaddr = 0x0, op_targ = 0, op_type = 0, op_opt = 0, op_slabbed = 0, op_savefree = 0, op_static = 0, op_folded = 0, op_lastsib = 0, op_spare = 0, op_flags = 65 'A', op_private = 0 '\000', op_first = 0x0, op_other = 0x7fffffffca80} method_unop = {op_next = 0x7fffffffcb70, op_sibling = 0x446122 <Perl_gv_fetchmeth_pvn+306>, op_ppaddr = 0x0, op_targ = 140733193388032, op_type = 304, op_opt = 0, op_slabbed = 0, op_savefree = 1, op_static = 1, op_folded = 1, op_lastsib = 0, op_spare = 1, op_flags = 208 '\320', op_private = 0 '\000', op_first = 0x40} method_svop = {op_next = 0x1488278, op_sibling = 0xf, op_ppaddr = 0x200000000, op_targ = 11815455031309, op_type = 64, op_opt = 0, op_slabbed = 1, op_savefree = 0, op_static = 1, op_folded = 1, op_lastsib = 1, op_spare = 1, op_flags = 42 '*', op_private = 1 '\001', op_sv = 0x8} oldmark = 0 retval = 0 oldscope = 2 oldcatch = false ret = <optimized out> oldop = 0x0 cur_env = {je_prev = 0x7fffffffcc20, je_buf = {{__jmpbuf = {140737488341632, 603917217593955240, 20275072, 0, 30560752, 0, 603917217520554920, -603916680868654168}, __mask_was_saved = 0, __saved_mask = {__val = {28674712, 23316960, 0, 4925082, 0, 12498329130309844224, 0, 0, 140733193388032, 8235024, 30287872, 30287944, 0, 4944424, 188685160, 0}}}}, je_ret = 0, je_mustcatch = false} #15 0x000000000043e912 in Perl_call_list (oldscope=1, paramList=0xab1ec8) at perl.c:4825 atsv = <optimized out> oldline = 0 cv = 0x1355f80 len = 28443200 ret = <optimized out> cur_env = {je_prev = 0x7fffffffcd40, je_buf = {{__jmpbuf = {11214536, 603917217413600168, 4319508, 140737488342896, 0, 0, 603917217591858088, -603916682310052952}, __mask_was_saved = 0, __saved_mask = {__val = {24390464, 0, 140737488342272, 5196359, 2, 0, 4308823400, 5001422, 0, 28649312, 30560768, 8220592, 30560752, 30560752, 30560752, 140737488342376}}}}, je_ret = 0, je_mustcatch = false} #16 0x000000000043fef1 in perl_destruct (my_perl=<optimized out>) at perl.c:574 cur_env = {je_prev = 0x7d1200 <PL_start_env>, je_buf = {{__jmpbuf = {69, 603917217507972008, 4319508, 140737488342896, 0, 0, 603917217411503016, -603916682534186072}, __mask_was_saved = 0, __saved_mask = {__val = {0, 4830937, 0, 0, 140737488342608, 0, 140737488342608, 4439136, 140737488342896, 4457444, 0, 4469852, 603917217507972008, 8589922168, 8196608, 0}}}}, je_ret = 0, je_mustcatch = false} x = <optimized out> destruct_level = 0 '\000' hv = <optimized out> i = <optimized out> #17 0x000000000041e8d4 in main (argc=2, argv=0x7fffffffcf78, env=0x7fffffffcf90) at perlmain.c:125 exitstatus = <optimized out> i = <optimized out> A debugging session is active. Inferior 1 [process 910291] will be killed. Quit anyway? (y or n)

Ok, managed to whittle the aformentioned test to something slightly smaller and predictable.

 

This for me generates a SEGV every time>

Note: if you change the order of the undefs in the END { } block, the SEGV goes away.

This is peculiar, because nothing in the LMDB CHI driver implies the objects are connected, and there seems to be subsequently an implict requried destruction order.

Also, in single_txn mode, I suspect its trying to create the database itself during destruction, and the order of creating the db's is getting confused.

Will keep on trucking and seeing if I can make an even narrower test case.

Subject: leak.pl
#!/usr/bin/env perl # FILENAME: leak.pl # CREATED: 10/04/14 01:56:56 by Kent Fredric (kentnl) <kentfredric@gmail.com> # ABSTRACT: A leak use strict; use warnings; use utf8; use CHI; use Path::Tiny; use LMDB_File qw( MDB_NOSYNC MDB_NOMETASYNC ); my $root = Path::Tiny->tempdir; my $dba = CHI->new( driver => 'LMDB', namespace => 'a', root_dir => $root->stringify, single_txn => 1, ); my $dbb = CHI->new( driver => 'LMDB', namespace => 'b', root_dir => $root->stringify, single_txn => 1, ); END { undef $dba; undef $dbb; print "XG DONE"; } $dba->compute('y', undef, sub { $dbb->compute('x', undef, sub { 'x' x 2500 }); });
Can you test if LDMB_File 0.07_3 fixes the problem? Thanks. El Vie Oct 03 10:39:13 2014, KENTNL escribió: Show quoted text
> Ok, managed to whittle the aformentioned test to something slightly > smaller and > predictable. > > This for me generates a SEGV every time> > > Note: if you change the order of the undefs in the END { } block, the > SEGV goes > away. > > This is peculiar, because nothing in the LMDB CHI driver implies the > objects > are connected, and there seems to be subsequently an implict requried > destruction order. > > Also, in single_txn mode, I suspect its trying to create the database > itself > during destruction, and the order of creating the db's is getting > confused. > > Will keep on trucking and seeing if I can make an even narrower test > case.