Question

I've been trying to track down an intermittent crashing bug in my code (which uses setjmp), and narrowed it down to: shows up when compiling with /O2, goes away with /O2 /Oy-, i.e. only shows up with omit frame pointer.

http://msdn.microsoft.com/en-us/library/2kxx5t2c(v=vs.80).aspx suggests setjmp requires a frame pointer. Thus:

  1. It seems that when a program that uses setjmp is compiled with /O2, Visual C++ silently generates code that causes intermittent stack corruption. Is this true, or am I missing something?

  2. It seems to me that only the function that invokes setjmp should need to be compiled with frame pointer, the rest of the program - even the functions that call longjmp - should be okay to omit frame pointer. Is this true?

Edit: I've narrowed it down a little further.

Enabling frame pointer on the function that was calling setjmp made no difference, but that's because the compiler was doing that already, just as it should, obviously noticing it needed to be done, and doing it automatically.

What did make a difference was enabling frame pointer on main. That's not as bizarre as it sounds, since the crash was manifesting in return from main. Now that I think of it, all the examples I can find in a quick google search of setjmp usage, do it in main. Perhaps it happened that the Microsoft compiler team only tested it that way.

That being the idiomatic way to use it, perhaps the best workaround would be for me to just inline the setjmp-using function into main.

Was it helpful?

Solution

Okay, I've posted a bug report with a self-contained test case, so hopefully a fix is in the pipeline: http://connect.microsoft.com/VisualStudio/feedback/details/666704/visual-c-generates-incorrect-code-with-omit-frame-pointer-and-setjmp

In the meantime, the workaround is either don't use omit frame pointer, or put the code that calls setjmp in main, or put the function that calls longjmp in the same source file as the call to setjmp.

OTHER TIPS

Can you please specify more info about the crash itself? I mean, which code the compiler generated for the longjmp, does the crash happen immediately after the longjmp, or when you try to access automatic variables, or when you try to exit the function?

I guess that the target function must be compiled with standard stack frame, there seems to be no reasonable limitation to the function that uses longjmp.

setjmp is implemented in a lot of different ways, but this probably has something to do with the assembly implementation for your particular OS.

When a function is compiled using __stdcall, arguments are stored relative to the frame pointer. Your implementation may be accessing the arguments to setjmp relative to said pointer so it doesn't have to trash multiple registers saving the context to them (since this would ruin much of the point of setjmp); I seem to remember setjmp is implemented this way in the linux kernel.

Of course if msvc doesn't generate instructions to set ebp, then this won't work and will surely cause a crash.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top