Front page | perl.perl5.porters |
Postings from July 2009
Re: [perl #60574] sv_upgrade() loses 64-bit alignment, causing SIGBUS on sparc
Thread Previous
|
Thread Next
From:
Nicholas Clark
Date:
July 17, 2009 12:44
Subject:
Re: [perl #60574] sv_upgrade() loses 64-bit alignment, causing SIGBUS on sparc
Message ID:
20090717194440.GJ60303@plum.flirble.org
On Mon, Nov 17, 2008 at 08:52:28PM +0200, Niko Tyni wrote:
> On Mon, Nov 17, 2008 at 03:44:18PM +0000, Nicholas Clark wrote:
> > On Sun, Nov 16, 2008 at 08:17:17PM +0200, Niko Tyni wrote:
> > > On Sun, Nov 16, 2008 at 05:15:36PM +0000, Nicholas Clark wrote:
> > > > On Sun, Nov 16, 2008 at 04:16:14AM -0800, Niko Tyni wrote:
> > > >
> > > > > As seen in <http://bugs.debian.org/505415>, calling sv_chop() or otherwise
> > > > > upgrading an SV can result in an unaligned 64-bit access on the sparc
> > > > > architecture.
> > >
> > > > What is __alignof__(XPVIV) and sizeof(XPVIV) on the same system?
> > >
> > > 8 and 24.
> >
> > whereas __alignof__(xpv_allocated) and sizeof(xpv_allocated) are 8 and 4,
> > and __alignof__(xpviv_allocated) and sizeof(xpviv_allocated) are 12 and 4?
>
> The other way around, otherwise right.
>
> XPV: alignof: 8 sizeof: 16
> xpv_allocated: alignof: 4 sizeof: 8
> XPVIV: alignof: 8 sizeof: 24
> xpviv_allocated: alignof: 4 sizeof: 12
>
> > If so, that would explain a lot, and it's my fault.
>
> Looking forward to the explanation :)
>
> Thanks for your work,
Sorry for the delay. Does change 69ba284b5e077075f1211a1053a11dae403648fd
fix it? It's currently in blead, but it should be suitable to merge to
maint-5.10. It replaces the *_allocated structs with a construction using
STRUCT_OFFSET().
I don't have access to sparc Debian, but I do have limited acces to sparc
Solaris 9 (with gcc). On that, running the appended script I see
bash-2.05$ ./perl -Ilib align.pl >align.c && gcc -Wall -o align align.c && ./align
XPV 16 8
xpv_allocated 8 4
sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur) 8
XPVIV 24 8
xpviv_allocated 12 4
sizeof(XPVIV) - STRUCT_OFFSET(XPVIV, xpv_cur) 16
XPVAV 32 8
xpvav_allocated 20 4
sizeof(XPVAV) - STRUCT_OFFSET(XPVAV, xav_fill) 24
XPVHV 32 8
xpvhv_allocated 20 4
sizeof(XPVHV) - STRUCT_OFFSET(XPVHV, xhv_fill) 24
XPVCV 64 8
xpvcv_allocated 56 4
sizeof(XPVCV) - STRUCT_OFFSET(XPVCV, xpv_cur) 56
XPVFM 64 8
xpvfm_allocated 56 4
sizeof(XPVFM) - STRUCT_OFFSET(XPVFM, xpv_cur) 56
XPVIO 88 8
xpvio_allocated 76 4
sizeof(XPVIO) - STRUCT_OFFSET(XPVIO, xpv_cur) 80
regexp 96 8
struct regexp_allocated 88 4
sizeof(regexp) - STRUCT_OFFSET(regexp, xpv_cur) 88
bash-2.05$
sizeof() ^ ^ __alignof__()
So I think the new way preserves the alignment constraint.
If I've got this right, I'll explain further if necessary. I'm not committing
to an explanation yet, as I don't know if I'm right.
Nicholas Clark
#!perl -w
use strict;
print <<'EOH';
#include "EXTERN.h"
#include "perl.h"
int main() {
EOH
my %first = (
XPVAV => 'xav_fill',
XPVHV => 'xhv_fill',
);
my @types = qw(XPV XPVIV XPVAV XPVHV XPVCV XPVFM);
push @types, qw(XPVIO regexp) if $] >= 5.011;
foreach my $raw (@types) {
foreach my $struct (map {$_, "\L$_\E_allocated"} $raw) {
$struct = "struct $struct" if $struct eq 'regexp_allocated';
print qq{printf("%-48s\\t%d\t%d\\n", "$struct"};
print ", $_($struct)" foreach qw(sizeof __alignof__);
print ")\n;";
}
my $first = $first{$raw} || 'xpv_cur';
my $new = "sizeof($raw) - STRUCT_OFFSET($raw, $first)";
print qq{printf("%-48s\\t%d\\n\\n", "$new", $new);\n};
}
print <<'EOH';
return 0;
}
EOH
__END__
Thread Previous
|
Thread Next