2011-05-04 42 views
5

我一直在試圖追蹤我的代碼(使用setjmp)中的間歇性崩潰錯誤,並將其縮小爲:與/ O2編譯時出現,與/ O2/Oy一起消失 - ,即只顯示與省略幀指針。setjmp和省略幀指針

http://msdn.microsoft.com/en-us/library/2kxx5t2c(v=vs.80).aspx建議setjmp需要一個幀指針。因此:

  1. 看來,當使用的setjmp一個程序與/ O2編譯時,Visual C++默默生成使間歇堆棧損壞代碼。這是真的,還是我錯過了什麼?

  2. 在我看來,只有調用setjmp的函數需要用frame指針進行編譯,程序的其餘部分 - 即使是調用longjmp的函數 - 也應該可以省略frame指針。這是真的?

編輯:我已經收窄,進一步一點。

在調用setjmp的函數上啓用幀指針沒有什麼區別,但那是因爲編譯器已經這樣做了,就像它應該那樣,顯然注意到它需要完成並自動完成。

有什麼有所作爲是啓用主指針。這聽起來並不奇怪,因爲這次事故是從主要的回報中顯現出來的。現在我想到了,我可以在快速的谷歌搜索setjmp用法中找到所有的例子,在main中做。也許碰巧微軟編譯團隊只是這樣測試的。

這是使用它的慣用方式,也許最好的解決方法是我將setjmp-using函數內聯到main中。

+4

這聽起來像是MSVC中的一個錯誤。我無法理解如何在沒有幀指針時執行失敗的'setjmp' /'longjmp'。看起來你必須竭盡全力讓它們破裂。無論如何,我只是在全局啓用幀指針;它對性能沒有太大的影響。 – 2011-05-04 17:46:35

+0

什麼是崩潰的調用堆棧? – 2011-05-06 03:45:59

+1

嗨,我想說這個bug仍然存在。請參閱關於gcc maillist的討論:http://gcc.gnu.org/ml/gcc/2011-10/msg00253.html – ollydbg23 2011-10-22 14:36:33

回答

3

好啦,我已經貼有一個自包含的測試案例的bug報告,所以希望修復是在管道:http://connect.microsoft.com/VisualStudio/feedback/details/666704/visual-c-generates-incorrect-code-with-omit-frame-pointer-and-setjmp

與此同時,解決辦法是要麼不使用省略幀指針,或者將調用setjmp的代碼放在main中,或者將調用longjmp的函數放在與setjmp調用相同的源文件中。

+0

它現在標記爲解決固定。 – rwallace 2011-06-29 18:29:26

0

你能指定更多關於崩潰本身的信息嗎?我的意思是,編譯器爲longjmp生成的代碼是否在longjmp之後立即發生崩潰,或者當您嘗試訪問自動變量,或者嘗試退出該函數時?

我想目標函數必須用標準堆棧框架編譯,似乎沒有合理的限制,使用longjmp功能。

+0

崩潰發生在從main返回的情況下,在setjmp-ing函數有幀指針但main沒有的情況下。讓我知道你是否想要一個測試用例的副本,如果是這樣,用什麼媒介;或者如果您想自己創建一個函數,關鍵的一點是setjmp-ing和longjmp-ing函數必須位於不同的翻譯單元中。 – rwallace 2011-05-12 19:34:03

0

setjmp以許多不同的方式實現,但這可能與您的特定操作系統的程序集實現有關。

當使用__stdcall編譯函數時,參數將相對於幀指針進行存儲。您的實現可能正在訪問相對於所述指針的setjmp參數,因此它不必垃圾多個寄存器將上下文保存到它們中(因爲這會破壞setjmp的大部分);我似乎記得setjmp在linux內核中以這種方式實現。

當然,如果msvc不生成設置ebp的指令,那麼這將不起作用,並且肯定會導致崩潰。