[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