[Gc] Gc segfault with gcc-3.4 and Gc segfault under valgrind

Eric Deplagne Eric.Deplagne at wanadoo.fr
Thu Nov 16 00:44:55 PST 2006


    I've found out what was causing the segfault with gcc-3.4, and it
    was not the gc.

    It was in fact the choice-point library, which also deals with the stack,
    in order to release the constraint of longjmp being called from a function
    called from the function calling setjmp.

    Let me explain what was going on, it's a good piece of gcc optimisation problem.

    The problem is the use of an asm() instruction to get the stack pointer,
    as the following simple test_asm.c shows:
    (btw, I could not reproduce it on any other gcc than gcc-3.4,
     so maybe a (know ?) gcc-3.4 bug, or is it simply a bad idea in the first place ?)

    #include <stdio.h>

    void *s1;
    void *s2;

    int main(void) {
      void *s3;
      asm ("mov %%esp,%0" : "=g" (s1) : : "esp");

      asm ("mov %%esp,%0" : "=g" (s2));

      s3=(void *)(((int)s1)+((int)s2));


      printf("s1=%p, s2=%p\n",s1,s2);

      s3=(void *)(((int)s1)+((int)s2));


      return 0;

    $ gcc -Wall -Wstrict-prototypes -O2 test_asm.c -o test_asm
    $ ./test_asm
    s1=0xbfb95350, s2=0xbfb95348

    Pretty odd that s3 does get two different values...

    $ gcc -Wall -Wstrict-prototypes -O2 -S test_asm.c -o test_asm.s

              .file   "test_asm.c"
              .section        .rodata.str1.1,"aMS", at progbits,1
              .string "s3=s1+s2=%p\n"
              .string "s1=%p, s2=%p\n"
              .p2align 2,,3
      .globl main
              .type   main, @function
              pushl   %ebp
              movl    %esp, %ebp
              subl    $8, %esp
              andl    $-16, %esp
              subl    $16, %esp
              mov %esp,%eax          ; here esp in eax
              mov %esp,s1            ; here esp in s1, is the clobber-list the right thing to do ?
              sall    %eax
              subl    $8, %esp       ; here esp change !!
              mov %esp,s2            ; here esp in s2, but we computed with a different value in eax
              pushl   %eax
              pushl   $.LC0
              call    printf
              addl    $12, %esp
              pushl   s2
              pushl   s1
              pushl   $.LC1
              call    printf
              movl    s2, %eax
              popl    %edx
              popl    %ecx
              addl    s1, %eax
              pushl   %eax
              pushl   $.LC0
              call    printf
              xorl    %eax, %eax
              .size   main, .-main
              .comm   s1,4,4
              .comm   s2,4,4
              .section        .note.GNU-stack,"", at progbits
              .ident  "GCC: (GNU) 3.4.4 20050721 (Red Hat 3.4.4-2)"

  gcc doesn't get it that esp is read, and does not save the value
  before it's modified.

  Adding esp in the clobber-list seems to work, but I thought it was for
  written registers.

  Eric Deplagne
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://napali.hpl.hp.com/pipermail/gc/attachments/20061116/ef818568/attachment.pgp

More information about the Gc mailing list