Sid Manning
2012-Jun-30 14:58 UTC
[LLVMdev] gcc bug?..segfault problem with getElfArchType.
I've been debugging a segfault issue with the elfreader and I would like
to point out something that I have noticed.
ELF.h declares an inline function, getElfArchType (MemoryBuffer
*Object). When this function is called from
ObjectFile::createELFObjectFile the pointer to Object was getting
corrupted. The only thing that distinguished this pointer was that it
was declared as a unique_ptr. The flow from when it was created to
getElfArchType is pretty direct.
The segfault only happens only at optimization level -O0.
The segfault doesn't happen if getElfArchType is declared as, "static
inline"
FWIW I'm compiling on x86_64/gcc-4.7.1.
This is the assembly, (widen your email window!)
Broken: Call side
ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
0x00000000004cc864
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE>:
push %rbp
0x00000000004cc865
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+1>:
mov %rsp,%rbp
0x00000000004cc868
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+4>:
push %rbx
0x00000000004cc869
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+5>:
sub $0x38,%rsp
0x00000000004cc86d
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+9>:
mov %rdi,-0x38(%rbp)
std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
0x00000000004cc871
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+13>:
mov -0x38(%rbp),%rax
0x00000000004cc875
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+17>:
mov %rax,%rdi
0x00000000004cc878
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+20>:
callq 0x4a51c5 <_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE>
Callee side: The address of *Object is at -0x18(%rbp) not -0x20(%rbp):
0x00000000004a51c5
<_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE>: push %rbp
0x00000000004a51c6
<_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+1>: mov %rsp,%rbp
0x00000000004a51c9
<_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+4>: sub
$0x20,%rsp
0x00000000004a51cd
<_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+8>: mov
%rdi,-0x18(%rbp)
0x00000000004a51d1
<_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+12>: mov
%rsi,-0x20(%rbp)
0x00000000004a51d5
<_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+16>: mov
-0x20(%rbp),%rax
0x00000000004a51d9
<_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+20>: mov %rax,%rdi
0x00000000004a51dc
<_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+23>: callq 0x4a4a74
<_ZNK4llvm12MemoryBuffer13getBufferSizeEv>
Working version call side, getElfArchType is "static inline"
ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
0x00000000004cc8da
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE>:
push %rbp
0x00000000004cc8db
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+1>:
mov %rsp,%rbp
0x00000000004cc8de
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+4>:
push %rbx
0x00000000004cc8df
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+5>:
sub $0x38,%rsp
0x00000000004cc8e3
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+9>:
mov %rdi,-0x38(%rbp)
std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
0x00000000004cc8e7
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+13>:
mov -0x38(%rbp),%rax
0x00000000004cc8eb
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+17>:
mov %rax,%rdi
0x00000000004cc8ee
<_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+20>:
callq 0x4cc868 <getElfArchType>
Callee side gets the correct address:
0x00000000004cc868 <getElfArchType>: push %rbp
0x00000000004cc869 <getElfArchType+1>: mov %rsp,%rbp
0x00000000004cc86c <getElfArchType+4>: push %rbx
0x00000000004cc86d <getElfArchType+5>: sub $0x18,%rsp
0x00000000004cc871 <getElfArchType+9>: mov %rdi,-0x18(%rbp)
0x00000000004cc875 <getElfArchType+13>: mov -0x18(%rbp),%rax
0x00000000004cc879 <getElfArchType+17>: mov %rax,%rdi
0x00000000004cc87c <getElfArchType+20>: callq 0x4a4b06
<_ZNK4llvm12MemoryBuffer13getBufferSizeEv>
Michael Spencer
2012-Jul-01 00:16 UTC
[LLVMdev] gcc bug?..segfault problem with getElfArchType.
On Sat, Jun 30, 2012 at 7:58 AM, Sid Manning <sidneym at codeaurora.org> wrote:> > I've been debugging a segfault issue with the elfreader and I would like to > point out something that I have noticed. > > ELF.h declares an inline function, getElfArchType (MemoryBuffer *Object). > When this function is called from ObjectFile::createELFObjectFile the > pointer to Object was getting corrupted. The only thing that distinguished > this pointer was that it was declared as a unique_ptr. The flow from when > it was created to getElfArchType is pretty direct. > > The segfault only happens only at optimization level -O0. > The segfault doesn't happen if getElfArchType is declared as, "static > inline"Is this occurring with ELF.h in lld? If so this sounds like your compiling llvm and lld with different standard libraries and because -O0 doesn't inline, the linkonce linkage is picking the wrong one. - Michael Spencer> FWIW I'm compiling on x86_64/gcc-4.7.1. > > > This is the assembly, (widen your email window!) > > Broken: Call side > ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) { > 0x00000000004cc864 > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE>: > push %rbp > 0x00000000004cc865 > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+1>: > mov %rsp,%rbp > 0x00000000004cc868 > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+4>: > push %rbx > 0x00000000004cc869 > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+5>: > sub $0x38,%rsp > 0x00000000004cc86d > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+9>: > mov %rdi,-0x38(%rbp) > std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object); > 0x00000000004cc871 > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+13>: > mov -0x38(%rbp),%rax > 0x00000000004cc875 > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+17>: > mov %rax,%rdi > 0x00000000004cc878 > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+20>: > callq 0x4a51c5 <_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE> > > Callee side: The address of *Object is at -0x18(%rbp) not -0x20(%rbp): > > 0x00000000004a51c5 <_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE>: > push %rbp > 0x00000000004a51c6 <_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+1>: > mov %rsp,%rbp > 0x00000000004a51c9 <_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+4>: > sub $0x20,%rsp > 0x00000000004a51cd <_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+8>: > mov %rdi,-0x18(%rbp) > 0x00000000004a51d1 <_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+12>: > mov %rsi,-0x20(%rbp) > 0x00000000004a51d5 <_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+16>: > mov -0x20(%rbp),%rax > 0x00000000004a51d9 <_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+20>: > mov %rax,%rdi > 0x00000000004a51dc <_ZN4llvm6object14getElfArchTypeEPNS_12MemoryBufferE+23>: > callq 0x4a4a74 <_ZNK4llvm12MemoryBuffer13getBufferSizeEv> > > > > > Working version call side, getElfArchType is "static inline" > > ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) { > 0x00000000004cc8da > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE>: > push %rbp > 0x00000000004cc8db > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+1>: > mov %rsp,%rbp > 0x00000000004cc8de > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+4>: > push %rbx > 0x00000000004cc8df > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+5>: > sub $0x38,%rsp > 0x00000000004cc8e3 > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+9>: > mov %rdi,-0x38(%rbp) > std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object); > 0x00000000004cc8e7 > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+13>: > mov -0x38(%rbp),%rax > 0x00000000004cc8eb > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+17>: > mov %rax,%rdi > 0x00000000004cc8ee > <_ZN4llvm6object10ObjectFile19createELFObjectFileEPNS_12MemoryBufferE+20>: > callq 0x4cc868 <getElfArchType> > > Callee side gets the correct address: > 0x00000000004cc868 <getElfArchType>: push %rbp > 0x00000000004cc869 <getElfArchType+1>: mov %rsp,%rbp > 0x00000000004cc86c <getElfArchType+4>: push %rbx > 0x00000000004cc86d <getElfArchType+5>: sub $0x18,%rsp > 0x00000000004cc871 <getElfArchType+9>: mov %rdi,-0x18(%rbp) > 0x00000000004cc875 <getElfArchType+13>: mov -0x18(%rbp),%rax > 0x00000000004cc879 <getElfArchType+17>: mov %rax,%rdi > 0x00000000004cc87c <getElfArchType+20>: callq 0x4a4b06 > <_ZNK4llvm12MemoryBuffer13getBufferSizeEv> >
Sid Manning
2012-Jul-01 00:40 UTC
[LLVMdev] gcc bug?..segfault problem with getElfArchType.
On 06/30/2012 07:16 PM, Michael Spencer wrote:> On Sat, Jun 30, 2012 at 7:58 AM, Sid Manning<sidneym at codeaurora.org> wrote: >> >> I've been debugging a segfault issue with the elfreader and I would like to >> point out something that I have noticed. >> >> ELF.h declares an inline function, getElfArchType (MemoryBuffer *Object). >> When this function is called from ObjectFile::createELFObjectFile the >> pointer to Object was getting corrupted. The only thing that distinguished >> this pointer was that it was declared as a unique_ptr. The flow from when >> it was created to getElfArchType is pretty direct. >> >> The segfault only happens only at optimization level -O0. >> The segfault doesn't happen if getElfArchType is declared as, "static >> inline" > > Is this occurring with ELF.h in lld? If so this sounds like your > compiling llvm and lld with different standard libraries and because > -O0 doesn't inline, the linkonce linkage is picking the wrong one.Yes, this is happening with ELF.h in lld; so that may be what is happening. I'm testing ReaderELF.h with a version of lld-core that reads objects rather than YAML. What is the fix, build everything with std=c++0x? Thanks,