[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#501825: libjson-xs-perl_2.23-1(sparc/unstable): FTBFS on sparc, fails in tests

On Fri, Oct 10, 2008 at 09:00:21PM +0200, Martin Zobel-Helas wrote:
> Package: libjson-xs-perl
> Version: 2.23-1
> Severity: serious
> There was an error while trying to autobuild your package:
> > Automatic build of libjson-xs-perl_2.23-1 on schroeder by sbuild/sparc 99.99
> > Build started at 20081010-1421

> > t/19_incr...............dubious
> > 	Test returned status 0 (wstat 10, 0xa)
> > DIED. FAILED test 697
> > 	Failed 1/697 tests, 99.86% okay

This is reproducible on sperger.d.o.

It's an alignment problem that only shows up with an optimization level
of at least -O2.

Program received signal SIGBUS, Bus error.
0xf7ec1134 in decode_json (string=0x192280, json=0x39f18, offset_return=0xff85b96c) at XS.xs:1443
1443      SvGROW (string, SvCUR (string) + 1); // should basically be a NOP
(gdb) bt
#0  0xf7ec1134 in decode_json (string=0x192280, json=0x39f18, offset_return=0xff85b96c) at XS.xs:1443
#1  0xf7ec2444 in XS_JSON__XS_incr_parse (my_perl=0x22008, cv=0x126d58) at XS.xs:1828
#2  0xf7dfab48 in Perl_pp_entersub () from /usr/lib/libperl.so.5.10
#3  0xf7df8f9c in Perl_runops_standard () from /usr/lib/libperl.so.5.10
#4  0xf7df4298 in perl_run () from /usr/lib/libperl.so.5.10
#5  0x00010b88 in main ()

The instruction that causes the bus error is a double-word load (ldd):

0xf7ec1130 <decode_json+132>:   ld  [ %l1 ], %g1
0xf7ec1134 <decode_json+136>:   ldd  [ %g1 + 8 ], %g2
0xf7ec1138 <decode_json+140>:   inc  %g2
0xf7ec113c <decode_json+144>:   cmp  %g3, %g2

The preprocessor output for the above SvGROW() macro invocation is

  (((XPV*) (string)->sv_any)->xpv_len < (((XPV*) (string)->sv_any)->xpv_cur + 1) ? Perl_sv_grow(((PerlInterpreter *)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))), string,((XPV*) (string)->sv_any)->xpv_cur + 1) : ((string)->sv_u.svu_pv));

and the above assembly is the compiled form of the first comparison
at -O2.  The compiler is using a double-word instruction to load both
xpv_cur and xpv_len in one go.

Now, this apparently requires that ((XPV*) (string)->sv_any)->xpv_cur
is aligned on a double-word (64-bit) boundary, which fails here:

$1 = {sv_any = 0x25714, sv_refcnt = 1, sv_flags = 536888326, sv_u = {svu_iv = 1662248, svu_uv = 1662248, 
    svu_rv = 0x195d28, svu_pv = 0x195d28 "[42]", svu_array = 0x195d28, svu_hash = 0x195d28, 
    svu_gp = 0x195d28}}
(gdb) print &((XPV*) (string)->sv_any)->xpv_cur
$2 = (STRLEN *) 0x2571c
(gdb) print &((XPV*) (string)->sv_any)->xpv_len
$3 = (STRLEN *) 0x25720

(Delving somewhat further, I see the 64-bit alignment of string->sv_any
 is lost in libperl's sv_chop(), invoked from incr_skip() at XS.xs:1855
 or so.)

This suggests to me that gcc is being too aggressive on optimizing here.
I don't see how it can consider the double word instruction safe.

Cc'ing the sparc porters list in the hope that somebody gets interested
in this.

I suppose a workaround is to use -O1 on sparc.
Niko Tyni   ntyni@debian.org

Reply to: