5

我一直在尝试在我的代码(它使用 setjmp)中追踪一个间歇性崩溃错误,并将其缩小为:使用 /O2 编译时出现,使用 /O2 /Oy- 消失,即只显示 omit帧指针。

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

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

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

编辑:我进一步缩小了范围。

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

真正有所作为的是在 main.js 上启用了帧指针。这并不像听起来那么奇怪,因为崩溃是从 main 的回报中体现出来的。现在我想到了,我可以在谷歌快速搜索 setjmp 用法中找到的所有示例,在 main.js 中执行。也许碰巧微软编译器团队只是这样测试它。

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

4

3 回答 3

3

好的,我已经发布了一个带有独立测试用例的错误报告,所以希望修复正在酝酿中:http ://connect.microsoft.com/VisualStudio/feedback/details/666704/visual-c-generates-不正确的代码与省略帧指针和 setjmp

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

于 2011-05-12T16:59:10.310 回答
0

您能否详细说明有关崩溃本身的信息?我的意思是,编译器为 生成的代码是longjmplongjmp

我猜目标函数必须使用标准堆栈框架编译,似乎对使用的函数没有合理的限制longjmp

于 2011-05-12T17:37:09.420 回答
0

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

当使用 __stdcall 编译函数时,参数是相对于帧指针存储的。您的实现可能正在访问相对于所述指针的 setjmp 的参数,因此它不必丢弃多个寄存器,将上下文保存到它们(因为这会破坏 setjmp 的大部分要点);我似乎记得 setjmp 在 linux 内核中是这样实现的。

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

于 2011-11-05T17:26:28.633 回答