Open mjegh opened 5 years ago
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
This is very similar to issue 15 (which was RT 94232) and was causes by the fix to RT91698 but far worse:
Which outputs: