[Bug target/60088] Segfault when using quad precision and -march=native on gfortran

jouko.orava at iki dot fi gcc-bugzilla@gcc.gnu.org
Fri Feb 7 03:35:00 GMT 2014


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60088

--- Comment #18 from Jouko Orava <jouko.orava at iki dot fi> ---
Addendum: the unaligned access causing the segfault seems to occur
because __libc_malloc returns an address aligned to 8 bytes, but
it is used as if it was aligned to 16 bytes. The disassembly is

 80493a0: e8 bb 64 04 00        call   808f860 <__libc_malloc>
 80493a5: 89 45 f0              mov    %eax,-0x10(%ebp)
 80493a8: 8b 5d f4              mov    -0xc(%ebp),%ebx
 80493ab: b8 01 00 00 00        mov    $0x1,%eax
 80493b0: 39 d8                 cmp    %ebx,%eax
 80493b2: 7f 18                 jg     80493cc <test_+0x58>
 80493b4: 8d 48 ff              lea    -0x1(%eax),%ecx
 80493b7: 8b 55 f0              mov    -0x10(%ebp),%edx
 80493ba: c1 e1 04              shl    $0x4,%ecx
 80493bd: 01 ca                 add    %ecx,%edx
 80493bf: 66 0f ef c0           pxor   %xmm0,%xmm0

 80493c3: 66 0f 7f 02           movdqa %xmm0,(%edx)

 80493c7: 83 c0 01              add    $0x1,%eax
 80493ca: eb e4                 jmp    80493b0 <test_+0x3c>
 80493cc: 8b 45 f0              mov    -0x10(%ebp),%eax

but note that this exact binary was compiled statically, and therefore
the addresses differ from the original bug report.

Assuming I read the above disassembly correctly, the pointer returned
to by __libc_malloc is stored in the stack (at %ebp-16), and retrieved
before the access back to %edx. An offset is calculated based on some
values into %ecx, multiplied by 16, and added to %edx. %xmm0 is cleared,
then copied to address pointed to by %edx. In other words, this is
just clearing the array received from malloc() to zeros.

Jacob Abel, if you could run the binary you provided me in gdb using
(gdb) break *0x80493a5
(gdb) run
(gdb) info registers
and verify that the %eax register contains an unaligned value
(not aligned to 16, last nibble nonzero), then we can confirm that
this is the issue -- that GNU Fortran or quadmath library expects
malloc() to return 16-byte aligned pointers, whereas it only provides
8-byte aligned pointers.

For reference, the malloc man page at the Linux man-pages project, at
    http://man7.org/linux/man-pages/man3/malloc.3.html
explicitly states malloc() returns only 8-byte aligned pointers.
(Other references seem to erroneously state that it returns 16-byte
aligned pointers on 64-bit architectures.)



More information about the Gcc-bugs mailing list