Dima Kogan <[email protected]> writes:
> valgrind is reporting some memory corruption, so I'll follow that when I
> have the time.
Compiler bug!
The bit of code the compiler trips up on is in pdl__ensure_trans() in
pdlapi.c. Specifically it's this snippet:
for(j=0; j<trans->vtable->npdls; j++) {
if(trans->pdls[j]->trans == trans)
PDL_ENSURE_ALLOCATED(trans->pdls[j]);
}
When building this with gcc4.8 we go through the loop just once, even if
trans->vtable->npdls > 1
This happens with -O1 and up. I refactored this bit of code into this:
void brokenpiece_48(pdl_trans *trans)
{
int j;
for(j=0; j<trans->vtable->npdls; j++)
{
pdl* thispdl = trans->pdls[j];
if( thispdl->trans == trans &&
!(thispdl->state & PDL_ALLOCATED) )
{
pdl_allocdata(thispdl);
}
}
}
and the generated assembly (with -O2) is this:
void brokenpiece_48(pdl_trans *trans)
{
int j;
for(j=0; j<trans->vtable->npdls; j++)
2e50: 48 8b 47 08 mov 0x8(%rdi),%rax
2e54: 44 8b 40 0c mov 0xc(%rax),%r8d
2e58: 45 85 c0 test %r8d,%r8d
2e5b: 7e 0a jle 2e67 <brokenpiece_48+0x17>
{
pdl* thispdl = trans->pdls[j];
2e5d: 48 8b 47 18 mov 0x18(%rdi),%rax
if( thispdl->trans == trans &&
2e61: 48 39 78 10 cmp %rdi,0x10(%rax)
2e65: 74 09 je 2e70 <brokenpiece_48+0x20>
2e67: f3 c3 repz retq
2e69: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
2e70: f6 40 08 01 testb $0x1,0x8(%rax)
2e74: 75 f1 jne 2e67 <brokenpiece_48+0x17>
!(thispdl->state & PDL_ALLOCATED) )
{
pdl_allocdata(thispdl);
2e76: 48 89 c7 mov %rax,%rdi
2e79: e9 00 00 00 00 jmpq 2e7e <brokenpiece_48+0x2e>
Note the out-of-bounds jump at the end, where we were supposed to go
back. Also I don't see anything keeping track of j here. So yeah. I'll
look more deeply and send a report to the gcc people, if it is still
relevant.
dima
_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl