DBD-Oracle
DBD-Oracle copied to clipboard
panic: memory wrap
This is very similar to issue 15 (which was RT 94232) and was causes by the fix to RT91698 but far worse:
use strict;
use warnings;
use DBI;
use DBD::Oracle qw(:ora_types);
use Data::Dumper;
print "perl=$] DBI=$DBI::VERSION DBD::Oracle=$DBD::Oracle::VERSION\n";
my $dbh = DBI->connect(
"dbi:Oracle:blahblah',
"username",
"password",
{RaiseError => 1}
);
my $sth = $dbh->prepare(qq{
BEGIN
:out := '1';
END;
});
$sth->bind_param_inout(':out', \my $result, 1
, {ora_type => ORA_CHAR}
);
$sth->execute();
print Dumper($result);
$sth->execute();
print Dumper($result);
$dbh->disconnect;
Which outputs:
perl=5.022000 DBI=1.639 DBD::Oracle=1.791
$VAR1 = '1 ';
panic: memory wrap at rt94232_gh_15.pl line 27.
Im guessing this is still an issue?
@djzort asked me to have a look at this, but I've run into limits on my knowledge (and time) on how this is meant to work:
The base issue is this code:
SvGROW(phs->sv,(STRLEN) (unsigned int)phs->maxlen-1);
is called when phs->maxlen is 0, subtracting 1 returns 0xffffffffffffffff:
Breakpoint 1, Perl_croak_memory_wrap () at util.c:1776
1776 Perl_croak_nocontext("%s",PL_memory_wrap);
(gdb) bt
#0 Perl_croak_memory_wrap () at util.c:1776
#1 0x00005555556fbb1c in Perl_sv_grow (my_perl=0x5555559ae260,
sv=0x555555e488b8, newlen=18446744073709551615) at sv.c:1607
#2 0x00007ffff7b90fbb in dbd_rebind_ph_char (imp_sth=0x555555a53cc0,
phs=0x555555f6ee20) at dbdimp.c:2789
#3 0x00007ffff7b92a73 in dbd_rebind_ph (sth=0x555555c95ba8,
imp_sth=0x555555a53cc0, phs=0x555555f6ee20) at dbdimp.c:3204
#4 0x00007ffff7b950e8 in ora_st_execute (sth=0x555555c95ba8,
imp_sth=0x555555a53cc0) at dbdimp.c:3689
#5 0x00007ffff7b7b4f5 in XS_DBD__Oracle__st_execute (my_perl=0x5555559ae260,
cv=0x555555de2ce0) at ./Oracle.xsi:623
#6 0x00007ffff7bd4cda in XS_DBI_dispatch (my_perl=0x5555559ae260,
cv=0x555555d43dd8) at DBI.xs:3783
#7 0x00005555556f5f99 in Perl_pp_entersub (my_perl=0x5555559ae260)
at pp_hot.c:5277
#8 0x00005555556e2fe0 in Perl_runops_standard (my_perl=0x5555559ae260)
at run.c:41
#9 0x00005555555d67eb in S_run_body (my_perl=0x5555559ae260, oldscope=1)
at perl.c:2761
#10 0x00005555555d61ea in perl_run (my_perl=0x5555559ae260) at perl.c:2684
#11 0x000055555559c20a in main (argc=3, argv=0x7fffffffebb8,
env=0x7fffffffebd8) at perlmain.c:127
(gdb) up 2
#2 0x00007ffff7b90fbb in dbd_rebind_ph_char (imp_sth=0x555555a53cc0,
phs=0x555555f6ee20) at dbdimp.c:2789
2789 SvGROW(phs->sv,(STRLEN) (unsigned int)phs->maxlen-1);
(gdb) p phs->maxlen
$1 = 0
How does it get that value? Initially it's set to the maxlen supplied to bind_param_inout:
3507 phs->maxlen = maxlen; /* 0 if not inout */
(gdb) p maxlen
$2 = 1
but later it's modified:
(gdb) watch -l phs->maxlen
Hardware watchpoint 3: -location phs->maxlen
(gdb) c
Continuing.
Hardware watchpoint 3: -location phs->maxlen
Old value = 1
New value = 0
dbd_rebind_ph_char (imp_sth=0x555555a53810, phs=0x555555f6fb10)
at dbdimp.c:2846
2846 if (phs->maxlen < 0) /* can happen with nulls */
(gdb) l 2845
2840 }
2841 phs->maxlen = ((IV)SvLEN(phs->sv)); /* avail buffer space (64bit safe) Logicaly maxlen should never change but it does why I know not - MJE because SvGROW can allocate more than you ask for - anyway - I fixed that and it doesn't grow anymore */
2842
2843 }
Since $result is undef at this point, SvLEN() is 0 and phs->maxlen isn't modified again until the panic.
Hopefully someone with a better knowledge of DBD::Oracle will understand what's going on here.
thanks @tonycoz
@mjegh can we arrange to look at this? maybe chat via irc or something