setjmp并省略帧指针

时间:2011-05-04 17:39:45

标签: c visual-c++ longjmp setjmp

我一直在尝试跟踪我的代码中的间歇性崩溃错误(使用setjmp),并将其缩小为:在使用/ O2进行编译时出现,与/ O2 / Oy-一起消失,即仅显示省略框架指针。

http://msdn.microsoft.com/en-us/library/2kxx5t2c(v=vs.80).aspx表明setjmp需要一个帧指针。因此:

  1. 似乎当使用/ O2编译使用setjmp的程序时,Visual C ++会静默生成导致间歇性堆栈损坏的代码。这是真的,还是我错过了什么?

  2. 在我看来,只有调用setjmp的函数才需要用帧指针编译,程序的其余部分 - 甚至是调用longjmp的函数 - 应该可以省略帧指针。这是真的吗?

  3. 编辑:我已将其缩小了一点。

    在调用setjmp的函数上启用帧指针没有区别,但那是因为编译器已经这样做了,就像它应该的那样,显然注意到它需要完成,并自动完成。

    有什么区别是在主要上启用帧指针。这并不像听起来那么奇怪,因为坠机是从主要的回归中显现出来的。现在,我想到了它,我可以在快速谷歌搜索setjmp使用中找到的所有示例,在main中执行。也许碰巧Microsoft编译器团队只是这样测试过。

    这是使用它的惯用方法,也许最好的解决方法是让我将setjmp-using函数内联到main。

3 个答案:

答案 0 :(得分:3)

好的,我发布了一个包含自包含测试用例的错误报告,因此希望修复工作正在进行中:http://connect.microsoft.com/VisualStudio/feedback/details/666704/visual-c-generates-incorrect-code-with-omit-frame-pointer-and-setjmp

与此同时,解决方法是要么不使用省略帧指针,要么将调用setjmp的代码放在main中,或者将调用longjmp的函数放在与调用setjmp相同的源文件中。

答案 1 :(得分:0)

您能否详细说明崩溃本身?我的意思是,编译器为longjmp生成了哪些代码,崩溃是在longjmp之后立即发生,还是在您尝试访问自动变量时,或者当您尝试退出函数时?

我想 target 函数必须使用标准堆栈帧进行编译,对使用longjmp的函数似乎没有合理的限制。

答案 2 :(得分:0)

setjmp以很多不同的方式实现,但这可能与您的特定操作系统的程序集实现有关。

使用__stdcall编译函数时,相对于帧指针存储参数。你的实现可能正在访问setjmp相对于所述指针的参数,所以它不必删除多个寄存器来保存它们的上下文(因为这会毁掉setjmp的大部分内容);我似乎记得setjmp是在linux内核中以这种方式实现的。

当然如果msvc没有生成设置ebp的指令,那么这将不起作用,肯定会导致崩溃。