Nick Craver 與 Marc Gravell 在 .NET 4.6 中引入的 RyuJIT 編譯器中發(fā)現(xiàn)了一個(gè)嚴(yán)重的 bug,.NET 4.6 會(huì)隨著 Visual Studio 2015 一起安裝,并且也預(yù)裝在 Windows 10 操作系統(tǒng)中。Craver 和 Gravell 已經(jīng)提交了這個(gè) bug 的詳細(xì)說(shuō)明,他們追蹤到問(wèn)題的根源來(lái)自于 RyuJIT 在處理尾調(diào)用優(yōu)化時(shí)的一個(gè)問(wèn)題。這個(gè)問(wèn)題產(chǎn)生的結(jié)果是“……我們所調(diào)用的方法沒(méi)有獲得所傳入的參數(shù)”,正如他們所說(shuō),如果受到此問(wèn)題影響的變量原本是用于處理重要的值,那么將因此造成嚴(yán)重的后果。
來(lái)自微軟的 Matt Mitchell 對(duì)這個(gè)發(fā)現(xiàn)做出了回應(yīng),他提交了一個(gè)補(bǔ)?。ㄍㄟ^(guò) pull request)以修復(fù)這個(gè)問(wèn)題。有趣的是,有人發(fā)現(xiàn)這個(gè)問(wèn)題本來(lái)已經(jīng)被修復(fù)了,但在三天前(7 月 24 日)又被微軟的另一位開(kāi)發(fā)者撤消了。Craver 指出,這個(gè) bug 的存在之所以不那么容易立即發(fā)現(xiàn),是由于以下幾點(diǎn)原因:
這個(gè)問(wèn)題只有在應(yīng)用了代碼優(yōu)化之后才會(huì)出現(xiàn),由于多數(shù)開(kāi)發(fā)者與項(xiàng)目都是在 DEBUG 模式開(kāi)發(fā)的,因此在本地環(huán)境中看不出來(lái)。
這也意味著你只能在 RELEASE 模式下發(fā)現(xiàn)它,對(duì)于多數(shù)人來(lái)說(shuō),這就意味著它只存在于生產(chǎn)環(huán)境。
一旦為進(jìn)程附加了調(diào)試器就會(huì)改變它的行為,這幾乎讓這個(gè)問(wèn)題完全隱形了。
如果在代碼中加入一句 Debug.WriteLine (),就很可能修復(fù)這個(gè)問(wèn)題,因?yàn)槲舱{(diào)用的方式產(chǎn)生了變化。
有一個(gè)重要的提示:即使微軟已經(jīng)在 GitHub 代碼庫(kù)中接受了這個(gè)補(bǔ)丁,也不意味著這個(gè)問(wèn)題就此結(jié)束了。對(duì)于已經(jīng)安裝了 .NET 4.6 的用戶(hù)來(lái)說(shuō),微軟必須為他們提供新的二進(jìn)制包。Craver 建議,如果開(kāi)發(fā)者還沒(méi)有在生產(chǎn)環(huán)境上部署 .NET 4.6,那么請(qǐng)耐心等待打了補(bǔ)丁的安裝包出現(xiàn)。而如果你已經(jīng)安裝了 .NET 4.6(無(wú)論在哪一種環(huán)境中),Craver 建議你立即關(guān)閉 RyuJIT,并且通過(guò)一些概念驗(yàn)證式的代碼告訴開(kāi)發(fā)者如何進(jìn)行操作。另外還有一個(gè)重要的提示,由于這個(gè)問(wèn)題所影響的是 RyuJIT 編譯器,因此它同樣會(huì)影響那些目標(biāo)為較早版本的 .NET 運(yùn)行時(shí)。
微軟的回應(yīng)(更新于 2015 年 7 月 28 日)
來(lái)自微軟的 Rich Lander 對(duì)于 Craver 與 Gravell 的報(bào)告進(jìn)行了正式的回應(yīng),他在回應(yīng)中提到這個(gè) bug 僅會(huì)影響 64 位進(jìn)程,而不會(huì)影響 32 位進(jìn)程。雖然 Lander 表示他的團(tuán)隊(duì)目前并不認(rèn)為這個(gè)問(wèn)題會(huì)被人利用,但他們還是會(huì)將修復(fù)代碼提交至發(fā)布流程中。
在 Lander 的說(shuō)明中,他也推薦在使用 .NET Framework 4.6 的環(huán)境中關(guān)閉 RyuJIT 的方式,直到補(bǔ)丁包出現(xiàn)為止。不過(guò),考慮到故障檢測(cè)不等人,最好還是先研究一下這個(gè) bug 是否確實(shí)對(duì)你的實(shí)際情況生產(chǎn)了影響,因?yàn)槿绻愕膽?yīng)用程序有什么異常的行為,也有可能是別的原因引起的。
根據(jù) Lander 的說(shuō)明,F(xiàn)#的開(kāi)發(fā)者最有可能遇到由這個(gè) bug 所引起的問(wèn)題,因此應(yīng)當(dāng)盡量避免安裝 .NET 4.6,Lander 在文中給出了如何重現(xiàn)這個(gè)問(wèn)題的 C# 與F#示例代碼。微軟目前還沒(méi)有說(shuō)明這個(gè)補(bǔ)丁的發(fā)布日期。