Program compiled with Clang -pg and -O crashes with SEGFAULT

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Program compiled with Clang -pg and -O crashes with SEGFAULT

Qiao Yang
Hi,

I am trying to compile a simple program with Clang 3.3  on Linux and used -pg and -O2 option. The program would crash with segfault. Interestingly if I compile it with -pg option only it works. Do you have any idea why it crashes? And any workaround?

$ cat myprog.c
int main() {
    return 0;
}

$ clang -v -pg -O2 myprog.c
clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
 "/usr/bin/clang" -cc1 -triple x86_64-pc-linux-gnu -emit-obj -disable-free -disable-llvm-verifier -main-file-name myprog.c -mrelocation-model static -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-linker-version 2.22 -momit-leaf-frame-pointer -v -resource-dir /usr/bin/../lib/clang/3.3 -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.3/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir /home/vagrant/work/c++ -ferror-limit 19 -fmessage-length 204 -pg -mstackrealign -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -o /tmp/myprog-oJBSKs.o -x c myprog.c
clang -cc1 version 3.3 based upon LLVM 3.3 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/bin/../lib/clang/3.3/include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
 "/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/gcrt1.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.. -L/lib -L/usr/lib /tmp/myprog-oJBSKs.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o

Running this program it would give me stack trace:
Program received signal SIGSEGV, Segmentation fault.
mcount () at ../sysdeps/x86_64/_mcount.S:46
46 ../sysdeps/x86_64/_mcount.S: No such file or directory.
(gdb) bt
#0  mcount () at ../sysdeps/x86_64/_mcount.S:46
#1  0x00007ffff7dd6568 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x0000000000000000 in ?? ()

If I compare the assembly code with and without optimization, the only difference seems to be that the optimized version removed some register preservation ops before calling mcount().

-pg version, which works:
----------------------------------------
main:                                   # @main
        .cfi_startproc
# BB#0:
        pushq %rbp
.Ltmp2:
        .cfi_def_cfa_offset 16
.Ltmp3:
        .cfi_offset %rbp, -16
        movq %rsp, %rbp
.Ltmp4:
        .cfi_def_cfa_register %rbp
        subq $16, %rsp
        callq mcount
        movl $0, %eax
        movl $0, -4(%rbp)
        addq $16, %rsp
        popq %rbp
        ret

-pg -O2 version, which crashes:
--------------------------------------------
main:                                   # @main
        .cfi_startproc
# BB#0:
        pushq %rax
.Ltmp1:
        .cfi_def_cfa_offset 16
        callq mcount
        xorl %eax, %eax
        popq %rdx
        ret

For those who are familiar with assembly code, does it ring some bell?

--Qiao



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Program compiled with Clang -pg and -O crashes with SEGFAULT

Duncan Sands
Hi Qiao,

On 24/07/13 08:23, Qiao Yang wrote:

> Hi,
>
> I am trying to compile a simple program with Clang 3.3  on Linux and used -pg and -O2 option. The program would crash with segfault. Interestingly if I compile it with -pg option only it works. Do you have any idea why it crashes? And any workaround?
>
> $ cat myprog.c
> int main() {
>      return 0;
> }
>
> $ clang -v -pg -O2 myprog.c

if you compile with -fno-omit-frame-pointer, the crash goes away, right?

> clang version 3.3 (tags/RELEASE_33/final)
> Target: x86_64-pc-linux-gnu
> Thread model: posix
>   "/usr/bin/clang" -cc1 -triple x86_64-pc-linux-gnu -emit-obj -disable-free -disable-llvm-verifier -main-file-name myprog.c -mrelocation-model static -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-linker-version 2.22 -momit-leaf-frame-pointer -v -resource-dir /usr/bin/../lib/clang/3.3 -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.3/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir /home/vagrant/work/c++ -ferror-limit 19 -fmessage-length 204 -pg -mstackrealign -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -o /tmp/myprog-oJBSKs.o -x c myprog.c
> clang -cc1 version 3.3 based upon LLVM 3.3 default target x86_64-pc-linux-gnu
> ignoring nonexistent directory "/include"
> #include "..." search starts here:
> #include <...> search starts here:
>   /usr/local/include
>   /usr/bin/../lib/clang/3.3/include
>   /usr/include/x86_64-linux-gnu
>   /usr/include
> End of search list.
>   "/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/gcrt1.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.. -L/lib -L/usr/lib /tmp/myprog-oJBSKs.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o
>
> Running this program it would give me stack trace:
> Program received signal SIGSEGV, Segmentation fault.
> mcount () at ../sysdeps/x86_64/_mcount.S:46
> 46 ../sysdeps/x86_64/_mcount.S: No such file or directory.
> (gdb) bt
> #0  mcount () at ../sysdeps/x86_64/_mcount.S:46
> #1  0x00007ffff7dd6568 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
> #2  0x0000000000000000 in ?? ()

Here you see that it crashes inside mcount.  I think mcount walks up the call
stack in order to generate a call graph.  Since it crashes when there is no
frame pointer it seems like this is an mcount bug, and it should really be
updated to one of the more modern methods that doesn't require a frame pointer.

>
> If I compare the assembly code with and without optimization, the only difference seems to be that the optimized version removed some register preservation ops before calling mcount().
>
> -pg version, which works:
> ----------------------------------------
> main:                                   # @main
> .cfi_startproc
> # BB#0:
> pushq %rbp

^ frame pointer

> .Ltmp2:
> .cfi_def_cfa_offset 16
> .Ltmp3:
> .cfi_offset %rbp, -16
> movq %rsp, %rbp
> .Ltmp4:
> .cfi_def_cfa_register %rbp
> subq $16, %rsp
> callq mcount
> movl $0, %eax
> movl $0, -4(%rbp)
> addq $16, %rsp
> popq %rbp
> ret
>
> -pg -O2 version, which crashes:
> --------------------------------------------
> main:                                   # @main
> .cfi_startproc
> # BB#0:
> pushq %rax
> .Ltmp1:
> .cfi_def_cfa_offset 16

^ no frame pointer

Ciao, Duncan.

> callq mcount
> xorl %eax, %eax
> popq %rdx
> ret
>
> For those who are familiar with assembly code, does it ring some bell?
>
> --Qiao
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Program compiled with Clang -pg and -O crashes with SEGFAULT

Qiao Yang
Duncan,

Yes, that is exactly the issue. It no longer crashes with -fno-omit-frame-pointer. Thanks a lot.
--Qiao

On Jul 24, 2013, at 10:51 AM, Duncan Sands <[hidden email]> wrote:

> Hi Qiao,
>
> On 24/07/13 08:23, Qiao Yang wrote:
>> Hi,
>>
>> I am trying to compile a simple program with Clang 3.3  on Linux and used -pg and -O2 option. The program would crash with segfault. Interestingly if I compile it with -pg option only it works. Do you have any idea why it crashes? And any workaround?
>>
>> $ cat myprog.c
>> int main() {
>>     return 0;
>> }
>>
>> $ clang -v -pg -O2 myprog.c
>
> if you compile with -fno-omit-frame-pointer, the crash goes away, right?
>
>> clang version 3.3 (tags/RELEASE_33/final)
>> Target: x86_64-pc-linux-gnu
>> Thread model: posix
>>  "/usr/bin/clang" -cc1 -triple x86_64-pc-linux-gnu -emit-obj -disable-free -disable-llvm-verifier -main-file-name myprog.c -mrelocation-model static -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-linker-version 2.22 -momit-leaf-frame-pointer -v -resource-dir /usr/bin/../lib/clang/3.3 -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.3/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir /home/vagrant/work/c++ -ferror-limit 19 -fmessage-length 204 -pg -mstackrealign -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -o /tmp/myprog-oJBSKs.o -x c myprog.c
>> clang -cc1 version 3.3 based upon LLVM 3.3 default target x86_64-pc-linux-gnu
>> ignoring nonexistent directory "/include"
>> #include "..." search starts here:
>> #include <...> search starts here:
>>  /usr/local/include
>>  /usr/bin/../lib/clang/3.3/include
>>  /usr/include/x86_64-linux-gnu
>>  /usr/include
>> End of search list.
>>  "/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/gcrt1.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.. -L/lib -L/usr/lib /tmp/myprog-oJBSKs.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o
>>
>> Running this program it would give me stack trace:
>> Program received signal SIGSEGV, Segmentation fault.
>> mcount () at ../sysdeps/x86_64/_mcount.S:46
>> 46 ../sysdeps/x86_64/_mcount.S: No such file or directory.
>> (gdb) bt
>> #0  mcount () at ../sysdeps/x86_64/_mcount.S:46
>> #1  0x00007ffff7dd6568 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
>> #2  0x0000000000000000 in ?? ()
>
> Here you see that it crashes inside mcount.  I think mcount walks up the call
> stack in order to generate a call graph.  Since it crashes when there is no
> frame pointer it seems like this is an mcount bug, and it should really be
> updated to one of the more modern methods that doesn't require a frame pointer.
>
>>
>> If I compare the assembly code with and without optimization, the only difference seems to be that the optimized version removed some register preservation ops before calling mcount().
>>
>> -pg version, which works:
>> ----------------------------------------
>> main:                                   # @main
>> .cfi_startproc
>> # BB#0:
>> pushq %rbp
>
> ^ frame pointer
>
>> .Ltmp2:
>> .cfi_def_cfa_offset 16
>> .Ltmp3:
>> .cfi_offset %rbp, -16
>> movq %rsp, %rbp
>> .Ltmp4:
>> .cfi_def_cfa_register %rbp
>> subq $16, %rsp
>> callq mcount
>> movl $0, %eax
>> movl $0, -4(%rbp)
>> addq $16, %rsp
>> popq %rbp
>> ret
>>
>> -pg -O2 version, which crashes:
>> --------------------------------------------
>> main:                                   # @main
>> .cfi_startproc
>> # BB#0:
>> pushq %rax
>> .Ltmp1:
>> .cfi_def_cfa_offset 16
>
> ^ no frame pointer
>
> Ciao, Duncan.
>
>> callq mcount
>> xorl %eax, %eax
>> popq %rdx
>> ret
>>
>> For those who are familiar with assembly code, does it ring some bell?
>>
>> --Qiao
>>
>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> [hidden email]         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev