BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

.NET 4.6的RyuJIT编译器中发现严重的Bug

| 作者 Jeff Martin 关注 17 他的粉丝 ,译者 邵思华 关注 3 他的粉丝 发布于 2015年7月30日. 估计阅读时间: 4 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

来自Stack Exchange的开发者Nick Craver与Marc Gravell在.NET 4.6中引入的RyuJIT编译器中发现了一个严重的bug,.NET 4.6会随着Visual Studio 2015一起安装,并且也预装在Windows 10操作系统中。Craver 和 Gravell已经提交了这个bug的详细说明,他们追踪到问题的根源来自于RyuJIT在处理尾调用优化时的一个问题。这个问题产生的结果是“……我们所调用的方法没有获得所传入的参数”,正如他们所说,如果受到此问题影响的变量原本是用于处理重要的值,那么将因此造成严重的后果。

来自微软的Matt Mitchell对这个发现做出了回应,他提交了一个补丁(通过pull request)以修复这个问题。有趣的是,有人发现这个问题本来已经被修复了,但在三天前(7月24日)又被微软的另一位开发者撤消了。Craver指出,这个bug的存在之所以不那么容易立即发现,是由于以下几点原因:

  • 这个问题只有在应用了代码优化之后才会出现,由于多数开发者与项目都是在DEBUG模式开发的,因此在本地环境中看不出来。
    • 这也意味着你只能在RELEASE模式下发现它,对于多数人来说,这就意味着它只存在于生产环境。
  • 一旦为进程附加了调试器就会改变它的行为,这几乎让这个问题完全隐形了。
  • 如果在代码中加入一句Debug.WriteLine(),就很可能修复这个问题,因为尾调用的方式产生了变化。

有一个重要的提示:即使微软已经在GitHub代码库中接受了这个补丁,也不意味着这个问题就此结束了。对于已经安装了.NET 4.6的用户来说,微软必须为他们提供新的二进制包。Craver建议,如果开发者还没有在生产环境上部署.NET 4.6,那么请耐心等待打了补丁的安装包出现。而如果你已经安装了.NET 4.6(无论在哪一种环境中),Craver建议你立即关闭RyuJIT,并且通过一些概念验证式的代码告诉开发者如何进行操作。另外还有一个重要的提示,由于这个问题所影响的是RyuJIT编译器,因此它同样会影响那些目标为较早版本的.NET运行时。

微软的回应(更新于2015年7月28日)

来自微软的Rich Lander对于Craver与Gravell的报告进行了正式的回应,他在回应中提到这个bug仅会影响64位进程,而不会影响32位进程。虽然Lander表示他的团队目前并不认为这个问题会被人利用,但他们还是会将修复代码提交至发布流程中。

在Lander的说明中,他也推荐在使用.NET Framework 4.6的环境中关闭RyuJIT的方式,直到补丁包出现为止。不过,考虑到故障检测不等人,最好还是先研究一下这个bug是否确实对你的实际情况生产了影响,因为如果你的应用程序有什么异常的行为,也有可能是别的原因引起的。

根据Lander的说明,F#的开发者最有可能遇到由这个bug所引起的问题,因此应当尽量避免安装.NET 4.6,Lander在文中给出了如何重现这个问题的C#与F#示例代码。微软目前还没有说明这个补丁的发布日期。

查看英文原文:Critical Bug Revealed in .NET 4.6's RyuJIT Compiler

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

太重要了。 by wu wei

如题

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

1 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT