public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* gcc auto-omit-frame-pointer vs msvc longjmp
       [not found]   ` <4E9C3703.3040109@mc.net>
@ 2011-10-17 21:20     ` Richard Henderson
  2011-10-17 21:32       ` [Qemu-devel] " Blue Swirl
  2011-10-17 22:56       ` Bob Breuer
  0 siblings, 2 replies; 21+ messages in thread
From: Richard Henderson @ 2011-10-17 21:20 UTC (permalink / raw)
  To: Bob Breuer; +Cc: Mark Cave-Ayland, qemu-devel, gcc, Kai Tietz

On 10/17/2011 07:09 AM, Bob Breuer wrote:
> I don't think this is a free/g_free issue.  If I use the following
> patch, then I at least get the openbios messages:
> 
> diff --git a/cpu-exec.c b/cpu-exec.c
> index a9fa608..dfbd6ea 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -180,6 +180,7 @@ static void cpu_handle_debug_exception(CPUState
>  /* main execution loop */
> 
>  volatile sig_atomic_t exit_request;
> +register void *ebp asm("ebp");
> 
>  int cpu_exec(CPUState *env)
>  {
> @@ -233,6 +234,8 @@ int cpu_exec(CPUState *env)
> 
>      /* prepare setjmp context for exception handling */
>      for(;;) {
> +        int dummy = 0;
> +        ebp = &dummy;

See if

  asm("" : : : "ebp");

also solves the problem.

> Google finds a mention of longjmp failing with -fomit-frame-pointer:
> http://lua-users.org/lists/lua-l/2005-02/msg00158.html
> 
> Looks like gcc 4.6 turns on -fomit-frame-pointer by default.

Hmm.  This is the first I've heard of a longjmp implementation 
failing without a frame pointer.  Presumably this is with the
mingw i.e. msvc libc?

This is something that could be worked around in gcc, I suppose.
We recognize longjmp for some things, we could force the use of
a frame pointer for msvc targets too.

For now it might be best to simply force -fno-omit-frame-pointer
for mingw host in the configure script.


r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-17 21:20     ` gcc auto-omit-frame-pointer vs msvc longjmp Richard Henderson
@ 2011-10-17 21:32       ` Blue Swirl
  2011-10-17 22:23         ` Richard Henderson
  2011-10-17 22:56       ` Bob Breuer
  1 sibling, 1 reply; 21+ messages in thread
From: Blue Swirl @ 2011-10-17 21:32 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Bob Breuer, Mark Cave-Ayland, Kai Tietz, qemu-devel, gcc

On Mon, Oct 17, 2011 at 5:22 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/17/2011 07:09 AM, Bob Breuer wrote:
>> I don't think this is a free/g_free issue.  If I use the following
>> patch, then I at least get the openbios messages:
>>
>> diff --git a/cpu-exec.c b/cpu-exec.c
>> index a9fa608..dfbd6ea 100644
>> --- a/cpu-exec.c
>> +++ b/cpu-exec.c
>> @@ -180,6 +180,7 @@ static void cpu_handle_debug_exception(CPUState
>>  /* main execution loop */
>>
>>  volatile sig_atomic_t exit_request;
>> +register void *ebp asm("ebp");
>>
>>  int cpu_exec(CPUState *env)
>>  {
>> @@ -233,6 +234,8 @@ int cpu_exec(CPUState *env)
>>
>>      /* prepare setjmp context for exception handling */
>>      for(;;) {
>> +        int dummy = 0;
>> +        ebp = &dummy;
>
> See if
>
>  asm("" : : : "ebp");
>
> also solves the problem.
>
>> Google finds a mention of longjmp failing with -fomit-frame-pointer:
>> http://lua-users.org/lists/lua-l/2005-02/msg00158.html
>>
>> Looks like gcc 4.6 turns on -fomit-frame-pointer by default.
>
> Hmm.  This is the first I've heard of a longjmp implementation
> failing without a frame pointer.  Presumably this is with the
> mingw i.e. msvc libc?
>
> This is something that could be worked around in gcc, I suppose.
> We recognize longjmp for some things, we could force the use of
> a frame pointer for msvc targets too.
>
> For now it might be best to simply force -fno-omit-frame-pointer
> for mingw host in the configure script.

IIRC buggy versions of alloca() could also fail without a frame pointer.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-17 21:32       ` [Qemu-devel] " Blue Swirl
@ 2011-10-17 22:23         ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2011-10-17 22:23 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Bob Breuer, Mark Cave-Ayland, Kai Tietz, qemu-devel, gcc

On 10/17/2011 12:14 PM, Blue Swirl wrote:
> IIRC buggy versions of alloca() could also fail without a frame pointer.

(1) GCC always uses a frame pointer for alloca,
(2) Unless you do -fno-builtin-alloca, we always implement it inline.


r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-17 21:20     ` gcc auto-omit-frame-pointer vs msvc longjmp Richard Henderson
  2011-10-17 21:32       ` [Qemu-devel] " Blue Swirl
@ 2011-10-17 22:56       ` Bob Breuer
  2011-10-18  2:06         ` Kai Tietz
  1 sibling, 1 reply; 21+ messages in thread
From: Bob Breuer @ 2011-10-17 22:56 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Mark Cave-Ayland, Kai Tietz, qemu-devel, gcc

Richard Henderson wrote:
> On 10/17/2011 07:09 AM, Bob Breuer wrote:
>> I don't think this is a free/g_free issue.  If I use the following
>> patch, then I at least get the openbios messages:
>>
>> diff --git a/cpu-exec.c b/cpu-exec.c
>> index a9fa608..dfbd6ea 100644
>> --- a/cpu-exec.c
>> +++ b/cpu-exec.c
>> @@ -180,6 +180,7 @@ static void cpu_handle_debug_exception(CPUState
>>  /* main execution loop */
>>
>>  volatile sig_atomic_t exit_request;
>> +register void *ebp asm("ebp");
>>
>>  int cpu_exec(CPUState *env)
>>  {
>> @@ -233,6 +234,8 @@ int cpu_exec(CPUState *env)
>>
>>      /* prepare setjmp context for exception handling */
>>      for(;;) {
>> +        int dummy = 0;
>> +        ebp = &dummy;
> 
> See if
> 
>   asm("" : : : "ebp");
> 
> also solves the problem.

No, that doesn't fix it.

> 
>> Google finds a mention of longjmp failing with -fomit-frame-pointer:
>> http://lua-users.org/lists/lua-l/2005-02/msg00158.html
>>
>> Looks like gcc 4.6 turns on -fomit-frame-pointer by default.
> 
> Hmm.  This is the first I've heard of a longjmp implementation 
> failing without a frame pointer.  Presumably this is with the
> mingw i.e. msvc libc?

Yeah, mingw from www.mingw.org which I believe uses msvcrt.dll, package
gcc-core-4.6.1-2-mingw32-bin.

> This is something that could be worked around in gcc, I suppose.
> We recognize longjmp for some things, we could force the use of
> a frame pointer for msvc targets too.
> 
> For now it might be best to simply force -fno-omit-frame-pointer
> for mingw host in the configure script.

Here's a testcase that crashes on the longjmp:

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

jmp_buf env;

int test(void)
{
  int i;

  asm("xor %%ebp,%%ebp" ::: "ebp");

  i = setjmp(env);
  printf("i = %d\n", i);

  if (i == 0)
    longjmp(env, 2);

  return i;
}

int main(void)
{
  return test();
}

Remove the asm statement to make it not crash.  Obviously with
omit-frame-pointer, gcc can shove anything into ebp.

Bob

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-17 22:56       ` Bob Breuer
@ 2011-10-18  2:06         ` Kai Tietz
  2011-10-18  4:20           ` Bob Breuer
  0 siblings, 1 reply; 21+ messages in thread
From: Kai Tietz @ 2011-10-18  2:06 UTC (permalink / raw)
  To: Bob Breuer; +Cc: Richard Henderson, Mark Cave-Ayland, qemu-devel, gcc

2011/10/17 Bob Breuer <breuerr@mc.net>:
> Richard Henderson wrote:
>> On 10/17/2011 07:09 AM, Bob Breuer wrote:
>>> I don't think this is a free/g_free issue.  If I use the following
>>> patch, then I at least get the openbios messages:
>>>
>>> diff --git a/cpu-exec.c b/cpu-exec.c
>>> index a9fa608..dfbd6ea 100644
>>> --- a/cpu-exec.c
>>> +++ b/cpu-exec.c
>>> @@ -180,6 +180,7 @@ static void cpu_handle_debug_exception(CPUState
>>>  /* main execution loop */
>>>
>>>  volatile sig_atomic_t exit_request;
>>> +register void *ebp asm("ebp");
>>>
>>>  int cpu_exec(CPUState *env)
>>>  {
>>> @@ -233,6 +234,8 @@ int cpu_exec(CPUState *env)
>>>
>>>      /* prepare setjmp context for exception handling */
>>>      for(;;) {
>>> +        int dummy = 0;
>>> +        ebp = &dummy;
>>
>> See if
>>
>>   asm("" : : : "ebp");
>>
>> also solves the problem.
>
> No, that doesn't fix it.
>
>>
>>> Google finds a mention of longjmp failing with -fomit-frame-pointer:
>>> http://lua-users.org/lists/lua-l/2005-02/msg00158.html
>>>
>>> Looks like gcc 4.6 turns on -fomit-frame-pointer by default.
>>
>> Hmm.  This is the first I've heard of a longjmp implementation
>> failing without a frame pointer.  Presumably this is with the
>> mingw i.e. msvc libc?
>
> Yeah, mingw from www.mingw.org which I believe uses msvcrt.dll, package
> gcc-core-4.6.1-2-mingw32-bin.
>
>> This is something that could be worked around in gcc, I suppose.
>> We recognize longjmp for some things, we could force the use of
>> a frame pointer for msvc targets too.
>>
>> For now it might be best to simply force -fno-omit-frame-pointer
>> for mingw host in the configure script.
>
> Here's a testcase that crashes on the longjmp:
>
> #include <stdio.h>
> #include <setjmp.h>
>
> jmp_buf env;
>
> int test(void)
> {
>  int i;
>
>  asm("xor %%ebp,%%ebp" ::: "ebp");
>
>  i = setjmp(env);
>  printf("i = %d\n", i);
>
>  if (i == 0)
>    longjmp(env, 2);
>
>  return i;
> }
>
> int main(void)
> {
>  return test();
> }
>
> Remove the asm statement to make it not crash.  Obviously with
> omit-frame-pointer, gcc can shove anything into ebp.
>
> Bob

This crash isn'r related to ebp existing, or not. The issue is the
hidden argument of setjmp, which is missing.  If you can try the
following at top of file after include section.

#define setjmp(BUF) _setjmpex((BUF), NULL)
int __cdecl __attribute__ ((__nothrow__,__returns_twice__))
_setjmp3(jmp_buf _Buf, void *_Ctx);
...

This will work as expected with or without omit-frame-pointer.

The issue is that setjmp has a second (undocumented as usual)
argument, which has a meaning.

Regards,
Kai

PS:  _setjmp3 is an export from msvcrt.dll.  So if symbol is missing
on link, simply specify msvcrt.dll as argument to link-line.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-18  2:06         ` Kai Tietz
@ 2011-10-18  4:20           ` Bob Breuer
  2011-10-18  4:22             ` Kai Tietz
  0 siblings, 1 reply; 21+ messages in thread
From: Bob Breuer @ 2011-10-18  4:20 UTC (permalink / raw)
  To: Kai Tietz; +Cc: gcc, Mark Cave-Ayland, qemu-devel, Richard Henderson

Kai Tietz wrote:
> 2011/10/17 Bob Breuer <breuerr@mc.net>:
>> Richard Henderson wrote:
>>> On 10/17/2011 07:09 AM, Bob Breuer wrote:
>>>> I don't think this is a free/g_free issue.  If I use the following
>>>> patch, then I at least get the openbios messages:
>>>>
>>>> diff --git a/cpu-exec.c b/cpu-exec.c
>>>> index a9fa608..dfbd6ea 100644
>>>> --- a/cpu-exec.c
>>>> +++ b/cpu-exec.c
>>>> @@ -180,6 +180,7 @@ static void cpu_handle_debug_exception(CPUState
>>>>  /* main execution loop */
>>>>
>>>>  volatile sig_atomic_t exit_request;
>>>> +register void *ebp asm("ebp");
>>>>
>>>>  int cpu_exec(CPUState *env)
>>>>  {
>>>> @@ -233,6 +234,8 @@ int cpu_exec(CPUState *env)
>>>>
>>>>      /* prepare setjmp context for exception handling */
>>>>      for(;;) {
>>>> +        int dummy = 0;
>>>> +        ebp = &dummy;
>>> See if
>>>
>>>   asm("" : : : "ebp");
>>>
>>> also solves the problem.
>> No, that doesn't fix it.
>>
>>>> Google finds a mention of longjmp failing with -fomit-frame-pointer:
>>>> http://lua-users.org/lists/lua-l/2005-02/msg00158.html
>>>>
>>>> Looks like gcc 4.6 turns on -fomit-frame-pointer by default.
>>> Hmm.  This is the first I've heard of a longjmp implementation
>>> failing without a frame pointer.  Presumably this is with the
>>> mingw i.e. msvc libc?
>> Yeah, mingw from www.mingw.org which I believe uses msvcrt.dll, package
>> gcc-core-4.6.1-2-mingw32-bin.
>>
>>> This is something that could be worked around in gcc, I suppose.
>>> We recognize longjmp for some things, we could force the use of
>>> a frame pointer for msvc targets too.
>>>
>>> For now it might be best to simply force -fno-omit-frame-pointer
>>> for mingw host in the configure script.
>> Here's a testcase that crashes on the longjmp:
>>
>> #include <stdio.h>
>> #include <setjmp.h>
>>
>> jmp_buf env;
>>
>> int test(void)
>> {
>>  int i;
>>
>>  asm("xor %%ebp,%%ebp" ::: "ebp");
>>
>>  i = setjmp(env);
>>  printf("i = %d\n", i);
>>
>>  if (i == 0)
>>    longjmp(env, 2);
>>
>>  return i;
>> }
>>
>> int main(void)
>> {
>>  return test();
>> }
>>
>> Remove the asm statement to make it not crash.  Obviously with
>> omit-frame-pointer, gcc can shove anything into ebp.
>>
>> Bob
> 
> This crash isn'r related to ebp existing, or not. The issue is the
> hidden argument of setjmp, which is missing.  If you can try the
> following at top of file after include section.
> 
> #define setjmp(BUF) _setjmpex((BUF), NULL)
> int __cdecl __attribute__ ((__nothrow__,__returns_twice__))
> _setjmp3(jmp_buf _Buf, void *_Ctx);
> ...

Did you mean _setjmp3 instead of _setjmpex?  With _setjmp3, it works
without the asm, but still crashes if I zero out ebp before the setjmp.
 Aren't the function arguments on the stack anyway?

> 
> This will work as expected with or without omit-frame-pointer.
> 
> The issue is that setjmp has a second (undocumented as usual)
> argument, which has a meaning.

So why does my testcase above fail with the asm, but work without the
asm statement?  Compile it with gcc -O2 and try it yourself.

> 
> Regards,
> Kai
> 
> PS:  _setjmp3 is an export from msvcrt.dll.  So if symbol is missing
> on link, simply specify msvcrt.dll as argument to link-line.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-18  4:20           ` Bob Breuer
@ 2011-10-18  4:22             ` Kai Tietz
  2011-10-20  3:26               ` Bob Breuer
  0 siblings, 1 reply; 21+ messages in thread
From: Kai Tietz @ 2011-10-18  4:22 UTC (permalink / raw)
  To: Bob Breuer; +Cc: gcc, Mark Cave-Ayland, qemu-devel, Richard Henderson

2011/10/18 Bob Breuer <breuerr@mc.net>:
> Kai Tietz wrote:
>> 2011/10/17 Bob Breuer <breuerr@mc.net>:
>>> Richard Henderson wrote:
>>>> On 10/17/2011 07:09 AM, Bob Breuer wrote:
>>>>> I don't think this is a free/g_free issue.  If I use the following
>>>>> patch, then I at least get the openbios messages:
>>>>>
>>>>> diff --git a/cpu-exec.c b/cpu-exec.c
>>>>> index a9fa608..dfbd6ea 100644
>>>>> --- a/cpu-exec.c
>>>>> +++ b/cpu-exec.c
>>>>> @@ -180,6 +180,7 @@ static void cpu_handle_debug_exception(CPUState
>>>>>  /* main execution loop */
>>>>>
>>>>>  volatile sig_atomic_t exit_request;
>>>>> +register void *ebp asm("ebp");
>>>>>
>>>>>  int cpu_exec(CPUState *env)
>>>>>  {
>>>>> @@ -233,6 +234,8 @@ int cpu_exec(CPUState *env)
>>>>>
>>>>>      /* prepare setjmp context for exception handling */
>>>>>      for(;;) {
>>>>> +        int dummy = 0;
>>>>> +        ebp = &dummy;
>>>> See if
>>>>
>>>>   asm("" : : : "ebp");
>>>>
>>>> also solves the problem.
>>> No, that doesn't fix it.
>>>
>>>>> Google finds a mention of longjmp failing with -fomit-frame-pointer:
>>>>> http://lua-users.org/lists/lua-l/2005-02/msg00158.html
>>>>>
>>>>> Looks like gcc 4.6 turns on -fomit-frame-pointer by default.
>>>> Hmm.  This is the first I've heard of a longjmp implementation
>>>> failing without a frame pointer.  Presumably this is with the
>>>> mingw i.e. msvc libc?
>>> Yeah, mingw from www.mingw.org which I believe uses msvcrt.dll, package
>>> gcc-core-4.6.1-2-mingw32-bin.
>>>
>>>> This is something that could be worked around in gcc, I suppose.
>>>> We recognize longjmp for some things, we could force the use of
>>>> a frame pointer for msvc targets too.
>>>>
>>>> For now it might be best to simply force -fno-omit-frame-pointer
>>>> for mingw host in the configure script.
>>> Here's a testcase that crashes on the longjmp:
>>>
>>> #include <stdio.h>
>>> #include <setjmp.h>
>>>
>>> jmp_buf env;
>>>
>>> int test(void)
>>> {
>>>  int i;
>>>
>>>  asm("xor %%ebp,%%ebp" ::: "ebp");
>>>
>>>  i = setjmp(env);
>>>  printf("i = %d\n", i);
>>>
>>>  if (i == 0)
>>>    longjmp(env, 2);
>>>
>>>  return i;
>>> }
>>>
>>> int main(void)
>>> {
>>>  return test();
>>> }
>>>
>>> Remove the asm statement to make it not crash.  Obviously with
>>> omit-frame-pointer, gcc can shove anything into ebp.
>>>
>>> Bob
>>
>> This crash isn'r related to ebp existing, or not. The issue is the
>> hidden argument of setjmp, which is missing.  If you can try the
>> following at top of file after include section.
>>
>> #define setjmp(BUF) _setjmpex((BUF), NULL)
>> int __cdecl __attribute__ ((__nothrow__,__returns_twice__))
>> _setjmp3(jmp_buf _Buf, void *_Ctx);
>> ...
>
> Did you mean _setjmp3 instead of _setjmpex?  With _setjmp3, it works
> without the asm, but still crashes if I zero out ebp before the setjmp.
>  Aren't the function arguments on the stack anyway?

Yes, I mean _setjmp3 (pasto from headers and missed the second line
prototyping _setjmp3).
I repeat myself here.  setjmp() has an hidden arguement, which is
passed on x86 on stack.  By not passing this required argument, setjmp
will take a random-value from stack.  In your case 'i'.  btw if you
would pre-initialize 'i' with zero, I would assume you won't see a
crash, but anyway this is just by chance.
For this I suggest to use here _setjmp3 instead, as here
second-argument is documented as being present.

Btw I tested your code with i686-pc-mingw32 version 4.6.x and 4.7.x
gcc version.  With my suggested pattern, I don't see a crash for your
provide test-code with, or without zero-ing ebp.

Kai

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-18  4:22             ` Kai Tietz
@ 2011-10-20  3:26               ` Bob Breuer
  2011-10-20  4:18                 ` Richard Henderson
                                   ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Bob Breuer @ 2011-10-20  3:26 UTC (permalink / raw)
  To: Kai Tietz; +Cc: gcc, Richard Henderson, qemu-devel, Mark Cave-Ayland

Kai Tietz wrote:
> 2011/10/18 Bob Breuer <breuerr@mc.net>:
>> Kai Tietz wrote:
>>> 2011/10/17 Bob Breuer <breuerr@mc.net>:
>>>> Richard Henderson wrote:
>>>>> On 10/17/2011 07:09 AM, Bob Breuer wrote:
>>>>>> Google finds a mention of longjmp failing with -fomit-frame-pointer:
>>>>>> http://lua-users.org/lists/lua-l/2005-02/msg00158.html
>>>>>>
>>>>>> Looks like gcc 4.6 turns on -fomit-frame-pointer by default.
>>>>> Hmm.  This is the first I've heard of a longjmp implementation
>>>>> failing without a frame pointer.  Presumably this is with the
>>>>> mingw i.e. msvc libc?
>>>> Yeah, mingw from www.mingw.org which I believe uses msvcrt.dll, package
>>>> gcc-core-4.6.1-2-mingw32-bin.
>>>>
>>>>> This is something that could be worked around in gcc, I suppose.
>>>>> We recognize longjmp for some things, we could force the use of
>>>>> a frame pointer for msvc targets too.
>>>>>
>>>>> For now it might be best to simply force -fno-omit-frame-pointer
>>>>> for mingw host in the configure script.
>>>> Here's a testcase that crashes on the longjmp:
>>>>
>>>> #include <stdio.h>
>>>> #include <setjmp.h>
>>>>
>>>> jmp_buf env;
>>>>
>>>> int test(void)
>>>> {
>>>>  int i;
>>>>
>>>>  asm("xor %%ebp,%%ebp" ::: "ebp");
>>>>
>>>>  i = setjmp(env);
>>>>  printf("i = %d\n", i);
>>>>
>>>>  if (i == 0)
>>>>    longjmp(env, 2);
>>>>
>>>>  return i;
>>>> }
>>>>
>>>> int main(void)
>>>> {
>>>>  return test();
>>>> }
>>>>
>>>> Remove the asm statement to make it not crash.  Obviously with
>>>> omit-frame-pointer, gcc can shove anything into ebp.
>>>>
>>>> Bob
>>> This crash isn'r related to ebp existing, or not. The issue is the
>>> hidden argument of setjmp, which is missing.  If you can try the
>>> following at top of file after include section.
>>>
>>> #define setjmp(BUF) _setjmpex((BUF), NULL)
>>> int __cdecl __attribute__ ((__nothrow__,__returns_twice__))
>>> _setjmp3(jmp_buf _Buf, void *_Ctx);
>>> ...
>> Did you mean _setjmp3 instead of _setjmpex?  With _setjmp3, it works
>> without the asm, but still crashes if I zero out ebp before the setjmp.
>>  Aren't the function arguments on the stack anyway?
> 
> Yes, I mean _setjmp3 (pasto from headers and missed the second line
> prototyping _setjmp3).
> I repeat myself here.  setjmp() has an hidden arguement, which is
> passed on x86 on stack.  By not passing this required argument, setjmp
> will take a random-value from stack.  In your case 'i'.  btw if you
> would pre-initialize 'i' with zero, I would assume you won't see a
> crash, but anyway this is just by chance.
> For this I suggest to use here _setjmp3 instead, as here
> second-argument is documented as being present.
> 
> Btw I tested your code with i686-pc-mingw32 version 4.6.x and 4.7.x
> gcc version.  With my suggested pattern, I don't see a crash for your
> provide test-code with, or without zero-ing ebp.


We probably have a difference in build or run environment.  I've
double-checked with another machine and can get the same crash in
longjmp when running the test executable on both WinXP and Win2k, but
not on Win7.  So it looks like Microsoft may have changed this "feature"
somewhere between WinXP and Win7.

The msvcrt implementation of longjmp (or at least the one I'm looking
at) does a ebp based access using the saved value of ebp.  Here's the
relevant disassembly of longjmp:

0x7801e6f3 in longjmpex () from C:\WINNT\system32\msvcrt.dll
(gdb) disas
Dump of assembler code for function longjmpex:
   0x7801e6ef <+0>:     mov    0x4(%esp),%ebx
=> 0x7801e6f3 <+4>:     mov    (%ebx),%ebp
...
   0x7801e73d <+78>:    call   0x7800bd5e <abnormal_termination+56>
...
   0x7800bd5e <+56>:    push   %ebx
   0x7800bd5f <+57>:    push   %ecx
   0x7800bd60 <+58>:    mov    $0x7803dc64,%ebx
=> 0x7800bd65 <+63>:    mov    0x8(%ebp),%ecx

It crashes on the access of 0x8(%ebp).  Those are the only 2 places
where this version of longjmp touches ebp.  Is it possible to force a
stackframe by just adding a suitable attribute to either the setjmp
function prototype, or the function which calls setjmp?

Bob

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-20  3:26               ` Bob Breuer
@ 2011-10-20  4:18                 ` Richard Henderson
  2011-10-20  6:08                 ` xunxun
  2011-10-20 14:16                 ` jojelino
  2 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2011-10-20  4:18 UTC (permalink / raw)
  To: Bob Breuer; +Cc: Kai Tietz, gcc, qemu-devel, Mark Cave-Ayland

On 10/19/2011 02:05 PM, Bob Breuer wrote:
> Is it possible to force a
> stackframe by just adding a suitable attribute to either the setjmp
> function prototype, or the function which calls setjmp?

The only thing I can think of that'll be portable to a large number
of versions of GCC is

  {
    int n; char *p;
    asm("" : "=r"(n) : "0"(1));
    p = __builtin_alloca(n);
    asm("" : : "r"(p));
  }

The first asm prevents constant propagation of the 1 to the alloca;
the second asm prevents the alloca from being considered dead code.


r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-20  3:26               ` Bob Breuer
  2011-10-20  4:18                 ` Richard Henderson
@ 2011-10-20  6:08                 ` xunxun
  2011-10-20 15:01                   ` Kai Tietz
  2011-10-20 14:16                 ` jojelino
  2 siblings, 1 reply; 21+ messages in thread
From: xunxun @ 2011-10-20  6:08 UTC (permalink / raw)
  To: Bob Breuer
  Cc: Kai Tietz, gcc, Richard Henderson, qemu-devel, Mark Cave-Ayland

Hi, all

I think this issue causes the gdb crash on XP.
You can see the thread: http://sourceware.org/ml/gdb/2011-10/msg00056.html

My many friends and I can reproduce this crash issue, but no problem on Win7.

On Thu, Oct 20, 2011 at 5:05 AM, Bob Breuer <breuerr@mc.net> wrote:
> Kai Tietz wrote:
>> 2011/10/18 Bob Breuer <breuerr@mc.net>:
>>> Kai Tietz wrote:
>>>> 2011/10/17 Bob Breuer <breuerr@mc.net>:
>>>>> Richard Henderson wrote:
>>>>>> On 10/17/2011 07:09 AM, Bob Breuer wrote:
>>>>>>> Google finds a mention of longjmp failing with -fomit-frame-pointer:
>>>>>>> http://lua-users.org/lists/lua-l/2005-02/msg00158.html
>>>>>>>
>>>>>>> Looks like gcc 4.6 turns on -fomit-frame-pointer by default.
>>>>>> Hmm.  This is the first I've heard of a longjmp implementation
>>>>>> failing without a frame pointer.  Presumably this is with the
>>>>>> mingw i.e. msvc libc?
>>>>> Yeah, mingw from www.mingw.org which I believe uses msvcrt.dll, package
>>>>> gcc-core-4.6.1-2-mingw32-bin.
>>>>>
>>>>>> This is something that could be worked around in gcc, I suppose.
>>>>>> We recognize longjmp for some things, we could force the use of
>>>>>> a frame pointer for msvc targets too.
>>>>>>
>>>>>> For now it might be best to simply force -fno-omit-frame-pointer
>>>>>> for mingw host in the configure script.
>>>>> Here's a testcase that crashes on the longjmp:
>>>>>
>>>>> #include <stdio.h>
>>>>> #include <setjmp.h>
>>>>>
>>>>> jmp_buf env;
>>>>>
>>>>> int test(void)
>>>>> {
>>>>>  int i;
>>>>>
>>>>>  asm("xor %%ebp,%%ebp" ::: "ebp");
>>>>>
>>>>>  i = setjmp(env);
>>>>>  printf("i = %d\n", i);
>>>>>
>>>>>  if (i == 0)
>>>>>    longjmp(env, 2);
>>>>>
>>>>>  return i;
>>>>> }
>>>>>
>>>>> int main(void)
>>>>> {
>>>>>  return test();
>>>>> }
>>>>>
>>>>> Remove the asm statement to make it not crash.  Obviously with
>>>>> omit-frame-pointer, gcc can shove anything into ebp.
>>>>>
>>>>> Bob
>>>> This crash isn'r related to ebp existing, or not. The issue is the
>>>> hidden argument of setjmp, which is missing.  If you can try the
>>>> following at top of file after include section.
>>>>
>>>> #define setjmp(BUF) _setjmpex((BUF), NULL)
>>>> int __cdecl __attribute__ ((__nothrow__,__returns_twice__))
>>>> _setjmp3(jmp_buf _Buf, void *_Ctx);
>>>> ...
>>> Did you mean _setjmp3 instead of _setjmpex?  With _setjmp3, it works
>>> without the asm, but still crashes if I zero out ebp before the setjmp.
>>>  Aren't the function arguments on the stack anyway?
>>
>> Yes, I mean _setjmp3 (pasto from headers and missed the second line
>> prototyping _setjmp3).
>> I repeat myself here.  setjmp() has an hidden arguement, which is
>> passed on x86 on stack.  By not passing this required argument, setjmp
>> will take a random-value from stack.  In your case 'i'.  btw if you
>> would pre-initialize 'i' with zero, I would assume you won't see a
>> crash, but anyway this is just by chance.
>> For this I suggest to use here _setjmp3 instead, as here
>> second-argument is documented as being present.
>>
>> Btw I tested your code with i686-pc-mingw32 version 4.6.x and 4.7.x
>> gcc version.  With my suggested pattern, I don't see a crash for your
>> provide test-code with, or without zero-ing ebp.
>
>
> We probably have a difference in build or run environment.  I've
> double-checked with another machine and can get the same crash in
> longjmp when running the test executable on both WinXP and Win2k, but
> not on Win7.  So it looks like Microsoft may have changed this "feature"
> somewhere between WinXP and Win7.
>
> The msvcrt implementation of longjmp (or at least the one I'm looking
> at) does a ebp based access using the saved value of ebp.  Here's the
> relevant disassembly of longjmp:
>
> 0x7801e6f3 in longjmpex () from C:\WINNT\system32\msvcrt.dll
> (gdb) disas
> Dump of assembler code for function longjmpex:
>   0x7801e6ef <+0>:     mov    0x4(%esp),%ebx
> => 0x7801e6f3 <+4>:     mov    (%ebx),%ebp
> ...
>   0x7801e73d <+78>:    call   0x7800bd5e <abnormal_termination+56>
> ...
>   0x7800bd5e <+56>:    push   %ebx
>   0x7800bd5f <+57>:    push   %ecx
>   0x7800bd60 <+58>:    mov    $0x7803dc64,%ebx
> => 0x7800bd65 <+63>:    mov    0x8(%ebp),%ecx
>
> It crashes on the access of 0x8(%ebp).  Those are the only 2 places
> where this version of longjmp touches ebp.  Is it possible to force a
> stackframe by just adding a suitable attribute to either the setjmp
> function prototype, or the function which calls setjmp?
>
> Bob
>



-- 
Best Regards,
xunxun

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-20  3:26               ` Bob Breuer
  2011-10-20  4:18                 ` Richard Henderson
  2011-10-20  6:08                 ` xunxun
@ 2011-10-20 14:16                 ` jojelino
  2 siblings, 0 replies; 21+ messages in thread
From: jojelino @ 2011-10-20 14:16 UTC (permalink / raw)
  To: gcc; +Cc: qemu-devel

On 2011-10-20 AM 6:05, Bob Breuer wrote:
>
> We probably have a difference in build or run environment.  I've
> double-checked with another machine and can get the same crash in
> longjmp when running the test executable on both WinXP and Win2k, but
> not on Win7.  So it looks like Microsoft may have changed this "feature"
> somewhere between WinXP and Win7.
YEES! It does crash in winxp.
>
> The msvcrt implementation of longjmp (or at least the one I'm looking
> at) does a ebp based access using the saved value of ebp.  Here's the
> relevant disassembly of longjmp:
>
> 0x7801e6f3 in longjmpex () from C:\WINNT\system32\msvcrt.dll
> (gdb) disas
> Dump of assembler code for function longjmpex:
>     0x7801e6ef<+0>:     mov    0x4(%esp),%ebx
> =>  0x7801e6f3<+4>:     mov    (%ebx),%ebp
> ...
>     0x7801e73d<+78>:    call   0x7800bd5e<abnormal_termination+56>
> ...
>     0x7800bd5e<+56>:    push   %ebx
>     0x7800bd5f<+57>:    push   %ecx
>     0x7800bd60<+58>:    mov    $0x7803dc64,%ebx
> =>  0x7800bd65<+63>:    mov    0x8(%ebp),%ecx
>
> It crashes on the access of 0x8(%ebp).  Those are the only 2 places
> where this version of longjmp touches ebp.  Is it possible to force a
> stackframe by just adding a suitable attribute to either the setjmp
> function prototype, or the function which calls setjmp?
and we had relevant report in ruby.
http://redmine.ruby-lang.org/issues/5375

Kai, would you mind if i reopen this bug you rejected?
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49230

>
> Bob
>
>


-- 
Regards.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-20  6:08                 ` xunxun
@ 2011-10-20 15:01                   ` Kai Tietz
  2011-10-20 17:12                     ` Kai Tietz
  0 siblings, 1 reply; 21+ messages in thread
From: Kai Tietz @ 2011-10-20 15:01 UTC (permalink / raw)
  To: xunxun; +Cc: Bob Breuer, gcc, Richard Henderson, qemu-devel, Mark Cave-Ayland

2011/10/20 xunxun <xunxun1982@gmail.com>:
> Hi, all
>
> I think this issue causes the gdb crash on XP.
> You can see the thread: http://sourceware.org/ml/gdb/2011-10/msg00056.html
>
> My many friends and I can reproduce this crash issue, but no problem on Win7.
>
> On Thu, Oct 20, 2011 at 5:05 AM, Bob Breuer <breuerr@mc.net> wrote:
>> Kai Tietz wrote:
>>> 2011/10/18 Bob Breuer <breuerr@mc.net>:
>>>> Kai Tietz wrote:
>>>>> 2011/10/17 Bob Breuer <breuerr@mc.net>:
>>>>>> Richard Henderson wrote:
>>>>>>> On 10/17/2011 07:09 AM, Bob Breuer wrote:
>>>>>>>> Google finds a mention of longjmp failing with -fomit-frame-pointer:
>>>>>>>> http://lua-users.org/lists/lua-l/2005-02/msg00158.html
>>>>>>>>
>>>>>>>> Looks like gcc 4.6 turns on -fomit-frame-pointer by default.
>>>>>>> Hmm.  This is the first I've heard of a longjmp implementation
>>>>>>> failing without a frame pointer.  Presumably this is with the
>>>>>>> mingw i.e. msvc libc?
>>>>>> Yeah, mingw from www.mingw.org which I believe uses msvcrt.dll, package
>>>>>> gcc-core-4.6.1-2-mingw32-bin.
>>>>>>
>>>>>>> This is something that could be worked around in gcc, I suppose.
>>>>>>> We recognize longjmp for some things, we could force the use of
>>>>>>> a frame pointer for msvc targets too.
>>>>>>>
>>>>>>> For now it might be best to simply force -fno-omit-frame-pointer
>>>>>>> for mingw host in the configure script.
>>>>>> Here's a testcase that crashes on the longjmp:
>>>>>>
>>>>>> #include <stdio.h>
>>>>>> #include <setjmp.h>
>>>>>>
>>>>>> jmp_buf env;
>>>>>>
>>>>>> int test(void)
>>>>>> {
>>>>>>  int i;
>>>>>>
>>>>>>  asm("xor %%ebp,%%ebp" ::: "ebp");
>>>>>>
>>>>>>  i = setjmp(env);
>>>>>>  printf("i = %d\n", i);
>>>>>>
>>>>>>  if (i == 0)
>>>>>>    longjmp(env, 2);
>>>>>>
>>>>>>  return i;
>>>>>> }
>>>>>>
>>>>>> int main(void)
>>>>>> {
>>>>>>  return test();
>>>>>> }
>>>>>>
>>>>>> Remove the asm statement to make it not crash.  Obviously with
>>>>>> omit-frame-pointer, gcc can shove anything into ebp.
>>>>>>
>>>>>> Bob
>>>>> This crash isn'r related to ebp existing, or not. The issue is the
>>>>> hidden argument of setjmp, which is missing.  If you can try the
>>>>> following at top of file after include section.
>>>>>
>>>>> #define setjmp(BUF) _setjmpex((BUF), NULL)
>>>>> int __cdecl __attribute__ ((__nothrow__,__returns_twice__))
>>>>> _setjmp3(jmp_buf _Buf, void *_Ctx);
>>>>> ...
>>>> Did you mean _setjmp3 instead of _setjmpex?  With _setjmp3, it works
>>>> without the asm, but still crashes if I zero out ebp before the setjmp.
>>>>  Aren't the function arguments on the stack anyway?
>>>
>>> Yes, I mean _setjmp3 (pasto from headers and missed the second line
>>> prototyping _setjmp3).
>>> I repeat myself here.  setjmp() has an hidden arguement, which is
>>> passed on x86 on stack.  By not passing this required argument, setjmp
>>> will take a random-value from stack.  In your case 'i'.  btw if you
>>> would pre-initialize 'i' with zero, I would assume you won't see a
>>> crash, but anyway this is just by chance.
>>> For this I suggest to use here _setjmp3 instead, as here
>>> second-argument is documented as being present.
>>>
>>> Btw I tested your code with i686-pc-mingw32 version 4.6.x and 4.7.x
>>> gcc version.  With my suggested pattern, I don't see a crash for your
>>> provide test-code with, or without zero-ing ebp.
>>
>>
>> We probably have a difference in build or run environment.  I've
>> double-checked with another machine and can get the same crash in
>> longjmp when running the test executable on both WinXP and Win2k, but
>> not on Win7.  So it looks like Microsoft may have changed this "feature"
>> somewhere between WinXP and Win7.
>>
>> The msvcrt implementation of longjmp (or at least the one I'm looking
>> at) does a ebp based access using the saved value of ebp.  Here's the
>> relevant disassembly of longjmp:
>>
>> 0x7801e6f3 in longjmpex () from C:\WINNT\system32\msvcrt.dll
>> (gdb) disas
>> Dump of assembler code for function longjmpex:
>>   0x7801e6ef <+0>:     mov    0x4(%esp),%ebx
>> => 0x7801e6f3 <+4>:     mov    (%ebx),%ebp
>> ...
>>   0x7801e73d <+78>:    call   0x7800bd5e <abnormal_termination+56>
>> ...
>>   0x7800bd5e <+56>:    push   %ebx
>>   0x7800bd5f <+57>:    push   %ecx
>>   0x7800bd60 <+58>:    mov    $0x7803dc64,%ebx
>> => 0x7800bd65 <+63>:    mov    0x8(%ebp),%ecx
>>
>> It crashes on the access of 0x8(%ebp).  Those are the only 2 places
>> where this version of longjmp touches ebp.  Is it possible to force a
>> stackframe by just adding a suitable attribute to either the setjmp
>> function prototype, or the function which calls setjmp?
>>
>> Bob
>>
>
>
>
> --
> Best Regards,
> xunxun

This now makes sense. I use here Vista 64-bit, and Win7 64-bit and I
didn't found the issue.  But well, it is indeed related to different
msvcrt-version.

So there might be some need to have for a function using setjmp the
frame-pointer enabled.  I can confirm this by an older msvcrt.dll
version on my 64-bit box, too.

So bug can be re-opened.

Thanks,
Kai

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-20 15:01                   ` Kai Tietz
@ 2011-10-20 17:12                     ` Kai Tietz
  2011-10-21 22:47                       ` jojelino
                                         ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Kai Tietz @ 2011-10-20 17:12 UTC (permalink / raw)
  To: xunxun; +Cc: Bob Breuer, gcc, Richard Henderson, qemu-devel, Mark Cave-Ayland

Hi,

For trunk-version I have a tentative patch for this issue.  On 4.6.x
and older branches this doesn't work, as here we can't differenciate
that easy between ms- and sysv-abi.

But could somebody give this patch a try?

Regards,
Kai

ChangeLog

        * config/i386/i386.c (ix86_frame_pointer_required): Enforce use of
        frame-pointer for 32-bit ms-abi, if setjmp is used.

Index: i386.c
===================================================================
--- i386.c      (revision 180099)
+++ i386.c      (working copy)
@@ -8391,6 +8391,10 @@
   if (SUBTARGET_FRAME_POINTER_REQUIRED)
     return true;

+  /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
+  if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
+    return true;
+
   /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
      turns off the frame pointer by default.  Turn it back on now if
      we've not got a leaf function.  */

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-20 17:12                     ` Kai Tietz
@ 2011-10-21 22:47                       ` jojelino
  2011-10-22 12:30                         ` xunxun
  2011-10-22 22:59                       ` asmwarrior
  2011-10-24 20:05                       ` [Qemu-devel] " Bob Breuer
  2 siblings, 1 reply; 21+ messages in thread
From: jojelino @ 2011-10-21 22:47 UTC (permalink / raw)
  To: gcc; +Cc: qemu-devel

On 2011-10-21 AM 12:34, Kai Tietz wrote:
> Hi,
>
> For trunk-version I have a tentative patch for this issue.  On 4.6.x
> and older branches this doesn't work, as here we can't differenciate
> that easy between ms- and sysv-abi.
>
> But could somebody give this patch a try?
>
> Regards,
> Kai
>
> ChangeLog
>
>          * config/i386/i386.c (ix86_frame_pointer_required): Enforce use of
>          frame-pointer for 32-bit ms-abi, if setjmp is used.
>
> Index: i386.c
> ===================================================================
> --- i386.c      (revision 180099)
> +++ i386.c      (working copy)
> @@ -8391,6 +8391,10 @@
>     if (SUBTARGET_FRAME_POINTER_REQUIRED)
>       return true;
>
> +  /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
> +  if (TARGET_32BIT_MS_ABI&&  cfun->calls_setjmp)
> +    return true;
> +
>     /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
>        turns off the frame pointer by default.  Turn it back on now if
>        we've not got a leaf function.  */
>

I tried this. it seems that problem is fixed. please apply this to 
trunk. although this workaround would not be needed anymore if mingw 
runtime provide longjmp which doesn't use _NLG_Notify.
-- 
Regards.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-21 22:47                       ` jojelino
@ 2011-10-22 12:30                         ` xunxun
  2011-10-22 13:18                           ` xunxun
  0 siblings, 1 reply; 21+ messages in thread
From: xunxun @ 2011-10-22 12:30 UTC (permalink / raw)
  To: jojelino; +Cc: gcc, qemu-devel, Kai Tietz

[-- Attachment #1: Type: text/plain, Size: 535 bytes --]

Hi, all

     It seems that gcc's auto-omit-frame-pointer has other problems.

     The example is from mingw bug tracker: 
http://sourceforge.net/tracker/?func=detail&aid=3426555&group_id=2435&atid=102435

     g++ -O3 main.cpp       running will crash.
     g++ -O2 main.cpp       running no crash.
     g++ -O3 -fno-omit-frame-pointer    running no crash.

     I don't know in the end which optimize option defaultly contains 
this switch "-fomit-frame-pointer" on i686-pc-mingw32 or x86_64-w64-mingw32?

-- 
Best Regards,
xunxun


[-- Attachment #2: main.cpp --]
[-- Type: text/plain, Size: 750 bytes --]

#include <vector>

typedef void (*Func)(char*);

bool lie = false;
Func dummy = 0;

void moveToWindowsRecycler(const std::vector<int>& filesToDelete = std::vector<int>())  //throw FileError
{
    if (!lie)
        throw 1;

    char errorMessage[20000];

    Func fun = lie ?  dummy : 0;
    fun(errorMessage);

    std::vector<int> fileNames;

    for (std::vector<int>::const_iterator iter = filesToDelete.begin(); iter != filesToDelete.end(); ++iter)
        fileNames.push_back(*iter);
}

void wgfdfsdgfsdgfsdg()  //throw FileError
{
    ::moveToWindowsRecycler();  //throw FileError
}

int main()
{
    try
    {
        moveToWindowsRecycler()  ;//throw FileError
    }
    catch (...) {}

    return 0;
}

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-22 12:30                         ` xunxun
@ 2011-10-22 13:18                           ` xunxun
  2011-10-22 14:21                             ` Kai Tietz
  0 siblings, 1 reply; 21+ messages in thread
From: xunxun @ 2011-10-22 13:18 UTC (permalink / raw)
  To: jojelino; +Cc: gcc, qemu-devel, Kai Tietz

于 2011/10/22 13:13, xunxun 写道:
> Hi, all
>
>     It seems that gcc's auto-omit-frame-pointer has other problems.
>
>     The example is from mingw bug tracker: 
> http://sourceforge.net/tracker/?func=detail&aid=3426555&group_id=2435&atid=102435
>
>     g++ -O3 main.cpp       running will crash.
>     g++ -O2 main.cpp       running no crash.
>     g++ -O3 -fno-omit-frame-pointer    running no crash.
>
>     I don't know in the end which optimize option defaultly contains 
> this switch "-fomit-frame-pointer" on i686-pc-mingw32 or 
> x86_64-w64-mingw32?
>
It crashes on Win7.

-- 
Best Regards,
xunxun

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-22 13:18                           ` xunxun
@ 2011-10-22 14:21                             ` Kai Tietz
  0 siblings, 0 replies; 21+ messages in thread
From: Kai Tietz @ 2011-10-22 14:21 UTC (permalink / raw)
  To: xunxun; +Cc: jojelino, gcc, qemu-devel

2011/10/22 xunxun <xunxun1982@gmail.com>:
> 于 2011/10/22 13:13, xunxun 写道:
>>
>> Hi, all
>>
>>    It seems that gcc's auto-omit-frame-pointer has other problems.
>>
>>    The example is from mingw bug tracker:
>> http://sourceforge.net/tracker/?func=detail&aid=3426555&group_id=2435&atid=102435
>>
>>    g++ -O3 main.cpp       running will crash.
>>    g++ -O2 main.cpp       running no crash.
>>    g++ -O3 -fno-omit-frame-pointer    running no crash.
>>
>>    I don't know in the end which optimize option defaultly contains this
>> switch "-fomit-frame-pointer" on i686-pc-mingw32 or x86_64-w64-mingw32?
>>
> It crashes on Win7.

Well, this issue isn't related to this thread.  It is more related to
dw2 and SjLj used.  For toolchains using dw2 exception mechanism, you
will see this crash.  By using SjLj you won't (thanks for checking
this).
This shows indeed my strong concerns about dw2 exception mechanism for
32-bit Windows targets.  The implementation depends too much on
code-patterns and is therefore a bit inconsitant.  Secondly it causes
harm if you try to throw exceptions over VC generated code.  So I
would strongly recomment to use the slower, but more reliable SjLj
throwing mechanism on Windows 32-bit.

Regards,
Kai

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-20 17:12                     ` Kai Tietz
  2011-10-21 22:47                       ` jojelino
@ 2011-10-22 22:59                       ` asmwarrior
  2011-10-24 20:05                       ` [Qemu-devel] " Bob Breuer
  2 siblings, 0 replies; 21+ messages in thread
From: asmwarrior @ 2011-10-22 22:59 UTC (permalink / raw)
  To: Kai Tietz
  Cc: xunxun, Bob Breuer, gcc, Richard Henderson, qemu-devel, Mark Cave-Ayland

On 2011-10-20 23:34, Kai Tietz wrote:
> Hi,
> 
> For trunk-version I have a tentative patch for this issue.  On 4.6.x
> and older branches this doesn't work, as here we can't differenciate
> that easy between ms- and sysv-abi.
> 
> But could somebody give this patch a try?
> 
> Regards,
> Kai
> 
> ChangeLog
> 
>          * config/i386/i386.c (ix86_frame_pointer_required): Enforce use of
>          frame-pointer for 32-bit ms-abi, if setjmp is used.
> 
> Index: i386.c
> ===================================================================
> --- i386.c      (revision 180099)
> +++ i386.c      (working copy)
> @@ -8391,6 +8391,10 @@
>     if (SUBTARGET_FRAME_POINTER_REQUIRED)
>       return true;
> 
> +  /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
> +  if (TARGET_32BIT_MS_ABI&&  cfun->calls_setjmp)
> +    return true;
> +
>     /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
>        turns off the frame pointer by default.  Turn it back on now if
>        we've not got a leaf function.  */
> 

I just see two related links about this issue:

see:
http://stackoverflow.com/questions/5887552/setjmp-and-omit-frame-pointer

and

http://connect.microsoft.com/VisualStudio/feedback/details/666704/visual-c-generates-incorrect-code-with-omit-frame-pointer-and-setjmp

I'm not sure microsoft has fix this issue.

asmwarrior
ollydbg from codeblocks' forum

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-20 17:12                     ` Kai Tietz
  2011-10-21 22:47                       ` jojelino
  2011-10-22 22:59                       ` asmwarrior
@ 2011-10-24 20:05                       ` Bob Breuer
  2011-10-24 23:25                         ` Kai Tietz
  2 siblings, 1 reply; 21+ messages in thread
From: Bob Breuer @ 2011-10-24 20:05 UTC (permalink / raw)
  To: Kai Tietz; +Cc: xunxun, gcc, qemu-devel, Mark Cave-Ayland, Richard Henderson

Kai Tietz wrote:
> Hi,
> 
> For trunk-version I have a tentative patch for this issue.  On 4.6.x
> and older branches this doesn't work, as here we can't differenciate
> that easy between ms- and sysv-abi.
> 
> But could somebody give this patch a try?
> 
> Regards,
> Kai
> 
> ChangeLog
> 
>         * config/i386/i386.c (ix86_frame_pointer_required): Enforce use of
>         frame-pointer for 32-bit ms-abi, if setjmp is used.
> 
> Index: i386.c
> ===================================================================
> --- i386.c      (revision 180099)
> +++ i386.c      (working copy)
> @@ -8391,6 +8391,10 @@
>    if (SUBTARGET_FRAME_POINTER_REQUIRED)
>      return true;
> 
> +  /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
> +  if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
> +    return true;
> +
>    /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
>       turns off the frame pointer by default.  Turn it back on now if
>       we've not got a leaf function.  */
> 

For a gcc 4.7 snapshot, this does fix the longjmp problem that I
encountered.  So aside from specifying -fno-omit-frame-pointer for
affected files, what can be done for 4.6?

Bob

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-24 20:05                       ` [Qemu-devel] " Bob Breuer
@ 2011-10-24 23:25                         ` Kai Tietz
  2011-10-25 17:00                           ` Bob Breuer
  0 siblings, 1 reply; 21+ messages in thread
From: Kai Tietz @ 2011-10-24 23:25 UTC (permalink / raw)
  To: Bob Breuer; +Cc: xunxun, gcc, qemu-devel, Mark Cave-Ayland, Richard Henderson

2011/10/24 Bob Breuer <breuerr@mc.net>:
> Kai Tietz wrote:
>> Hi,
>>
>> For trunk-version I have a tentative patch for this issue.  On 4.6.x
>> and older branches this doesn't work, as here we can't differenciate
>> that easy between ms- and sysv-abi.
>>
>> But could somebody give this patch a try?
>>
>> Regards,
>> Kai
>>
>> ChangeLog
>>
>>         * config/i386/i386.c (ix86_frame_pointer_required): Enforce use of
>>         frame-pointer for 32-bit ms-abi, if setjmp is used.
>>
>> Index: i386.c
>> ===================================================================
>> --- i386.c      (revision 180099)
>> +++ i386.c      (working copy)
>> @@ -8391,6 +8391,10 @@
>>    if (SUBTARGET_FRAME_POINTER_REQUIRED)
>>      return true;
>>
>> +  /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
>> +  if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
>> +    return true;
>> +
>>    /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
>>       turns off the frame pointer by default.  Turn it back on now if
>>       we've not got a leaf function.  */
>>
>
> For a gcc 4.7 snapshot, this does fix the longjmp problem that I
> encountered.  So aside from specifying -fno-omit-frame-pointer for
> affected files, what can be done for 4.6?
>
> Bob

Well, for 4.6.x (or older) we just can use the mingw32.h header in
gcc/config/i386/ and define here a subtarget-macro to indicate that.
The only incompatible point here might be for Wine using the
linux-compiler to build Windows related code.

A possible patch for 4.6 gcc versions I attached to this mail.

Regards,
Kai

Index: mingw32.h
===================================================================
--- mingw32.h   (revision 180393)
+++ mingw32.h   (working copy)
@@ -239,3 +239,8 @@
 /* We should find a way to not have to update this manually.  */
 #define LIBGCJ_SONAME "libgcj" /*LIBGCC_EH_EXTN*/ "-12.dll"

+/* For 32-bit Windows we need valid frame-pointer for function using
+   setjmp.  */
+#define SUBTARGET_SETJMP_NEED_FRAME_POINTER \
+  (!TARGET_64BIT && cfun->calls_setjmp)
+
Index: i386.c
===================================================================
--- i386.c      (revision 180393)
+++ i386.c      (working copy)
@@ -8741,6 +8741,12 @@
   if (SUBTARGET_FRAME_POINTER_REQUIRED)
     return true;

+#ifdef SUBTARGET_SETJMP_NEED_FRAME_POINTER
+  /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
+  if (SUBTARGET_SETJMP_NEED_FRAME_POINTER)
+    return true;
+#endif
+
   /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
      turns off the frame pointer by default.  Turn it back on now if
      we've not got a leaf function.  */

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] gcc auto-omit-frame-pointer vs msvc longjmp
  2011-10-24 23:25                         ` Kai Tietz
@ 2011-10-25 17:00                           ` Bob Breuer
  0 siblings, 0 replies; 21+ messages in thread
From: Bob Breuer @ 2011-10-25 17:00 UTC (permalink / raw)
  To: Kai Tietz; +Cc: xunxun, Richard Henderson, qemu-devel, Mark Cave-Ayland, gcc

Kai Tietz wrote:
> 2011/10/24 Bob Breuer <breuerr@mc.net>:
>> Kai Tietz wrote:
>>> Hi,
>>>
>>> For trunk-version I have a tentative patch for this issue.  On 4.6.x
>>> and older branches this doesn't work, as here we can't differenciate
>>> that easy between ms- and sysv-abi.
>>>
>>> But could somebody give this patch a try?
>>>
>>> Regards,
>>> Kai
>>>
>>> ChangeLog
>>>
>>>         * config/i386/i386.c (ix86_frame_pointer_required): Enforce use of
>>>         frame-pointer for 32-bit ms-abi, if setjmp is used.
>>>
>>> Index: i386.c
>>> ===================================================================
>>> --- i386.c      (revision 180099)
>>> +++ i386.c      (working copy)
>>> @@ -8391,6 +8391,10 @@
>>>    if (SUBTARGET_FRAME_POINTER_REQUIRED)
>>>      return true;
>>>
>>> +  /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
>>> +  if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
>>> +    return true;
>>> +
>>>    /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
>>>       turns off the frame pointer by default.  Turn it back on now if
>>>       we've not got a leaf function.  */
>>>
>> For a gcc 4.7 snapshot, this does fix the longjmp problem that I
>> encountered.  So aside from specifying -fno-omit-frame-pointer for
>> affected files, what can be done for 4.6?
>>
>> Bob
> 
> Well, for 4.6.x (or older) we just can use the mingw32.h header in
> gcc/config/i386/ and define here a subtarget-macro to indicate that.
> The only incompatible point here might be for Wine using the
> linux-compiler to build Windows related code.
> 
> A possible patch for 4.6 gcc versions I attached to this mail.
> 
> Regards,
> Kai
> 
> Index: mingw32.h
> ===================================================================
> --- mingw32.h   (revision 180393)
> +++ mingw32.h   (working copy)
> @@ -239,3 +239,8 @@
>  /* We should find a way to not have to update this manually.  */
>  #define LIBGCJ_SONAME "libgcj" /*LIBGCC_EH_EXTN*/ "-12.dll"
> 
> +/* For 32-bit Windows we need valid frame-pointer for function using
> +   setjmp.  */
> +#define SUBTARGET_SETJMP_NEED_FRAME_POINTER \
> +  (!TARGET_64BIT && cfun->calls_setjmp)
> +
> Index: i386.c
> ===================================================================
> --- i386.c      (revision 180393)
> +++ i386.c      (working copy)
> @@ -8741,6 +8741,12 @@
>    if (SUBTARGET_FRAME_POINTER_REQUIRED)
>      return true;
> 
> +#ifdef SUBTARGET_SETJMP_NEED_FRAME_POINTER
> +  /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
> +  if (SUBTARGET_SETJMP_NEED_FRAME_POINTER)
> +    return true;
> +#endif
> +
>    /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
>       turns off the frame pointer by default.  Turn it back on now if
>       we've not got a leaf function.  */
> 

That works for me. Thanks.

Bob

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2011-10-25 15:14 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <4E9BB180.6080506@mc.net>
     [not found] ` <4E9C0497.2000605@siriusit.co.uk>
     [not found]   ` <4E9C3703.3040109@mc.net>
2011-10-17 21:20     ` gcc auto-omit-frame-pointer vs msvc longjmp Richard Henderson
2011-10-17 21:32       ` [Qemu-devel] " Blue Swirl
2011-10-17 22:23         ` Richard Henderson
2011-10-17 22:56       ` Bob Breuer
2011-10-18  2:06         ` Kai Tietz
2011-10-18  4:20           ` Bob Breuer
2011-10-18  4:22             ` Kai Tietz
2011-10-20  3:26               ` Bob Breuer
2011-10-20  4:18                 ` Richard Henderson
2011-10-20  6:08                 ` xunxun
2011-10-20 15:01                   ` Kai Tietz
2011-10-20 17:12                     ` Kai Tietz
2011-10-21 22:47                       ` jojelino
2011-10-22 12:30                         ` xunxun
2011-10-22 13:18                           ` xunxun
2011-10-22 14:21                             ` Kai Tietz
2011-10-22 22:59                       ` asmwarrior
2011-10-24 20:05                       ` [Qemu-devel] " Bob Breuer
2011-10-24 23:25                         ` Kai Tietz
2011-10-25 17:00                           ` Bob Breuer
2011-10-20 14:16                 ` jojelino

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).