This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GCC reuses stack slot in setjmp-calling function -- is it a bug or feature?


Hi,

Minimal reproduction for x86:

#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>

jmp_buf something_happened;
int key_gdata = 2;

int store_data;

void __attribute__((noinline))
initiate(void)
{
  longjmp(something_happened, 1);
}

int __attribute__ ((noinline))
foo(int x)
{
  return x + 1;
}

int __attribute__((noinline))
amibuggy(int x, int y1, int y2, int y3)
{
  int nextdata, idx, key_data;

  key_data = key_gdata;

  if (setjmp(something_happened))
    {
      if (key_data != key_gdata)
        {
          fprintf(stderr, "Test failed: data = %d, g_data = %d\n",
key_data, key_gdata);
          abort();
        }
      else
        {
          fprintf(stdout, "Test passed\n");
          fprintf(stdout, "data = %d, g_data = %d\n", key_data, key_gdata);
          return 0;
        }
    }

  store_data = key_data;
  nextdata = key_gdata;

  idx = foo(nextdata);

  for (;idx != 0; --idx)
    {
      int tmp = store_data;
      nextdata += foo(tmp);
      store_data = foo(nextdata);
    }

  initiate();
  return 0;
}

int
main(void)
{
  amibuggy(9, 5, 16, 36);
  amibuggy(0, 0, 0, 0);
  return 0;
}


Compile with gcc-4.7.2 with line:

gcc -O2 repro.c -o repro.x86

Now run and you will see test "magically" failed.

What happens? Compiler on register allocation pass decided to reuse
stack slot 12(%rsp) where key_data persisted.

movl key_gdata(%rip), %eax
movl %eax, 12(%rsp)
call _setjmp

... and later ...

.L10:
movl 12(%rsp), %edi <--- oops!
call foo

setjmp stored stack pointer, next frame slot is overwritten by
spill/fill (because compiler thinks that key_data is already dead at
this point. Then everything explodes.

I am not sure that it is a bug, but situation is rather complicated
for programmer -- I think in this case programmer really may rely on
context restoring after longjmp, and surprise is really great.

Question to gcc-help: Please comment on should I file this in
bugzilla, or should I live with it.

Question to gcc: Really I found this problem in private backend and
want to fix it for my users, no matter first answer is yes or no.
Maybe somehow restrict stack slot reusage if function calls setjmp.
But I am not so good in reload internals. Any advices about how to
locally fix it in private backend sources (I haven't still done any
changes to normal gcc-4.7.2, just added new machine description) are
very appreciated.

---
With best regards, Konstantin


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]