Monday, November 10

致命的BUG:KB326219

下午我在做一个WinForm in VB.Net的程序时遇到了奇怪的问题,在设置好LABEL的字体后,运行出错,是奇怪的System.ArithmeticException,可是出错的位置是VS自动生成的code。google之后发现,这是一个臭名昭著的问题:326219 - PRB: System.Arithmetic Exception Error When You Change the Floating-Point Control Register in a Managed Application
看了这篇KB,我非常奇怪,是什么改变了浮点控制寄存器呢?
我一个一个地关掉我桌面上的程序, 发现罪魁就是早上安装的WORKTIME,在这个程序里一定是使用了这个寄存器,而dotNet在使用它时没有正确地初始化。
按照KB的指示,我们必须在每new一个form之前样做浮点精度指定。就像这样:
Imports System.Runtime.InteropServices
Module StartUp

_
Overloads Function _controlfp(ByVal n As Integer, ByVal mask As Integer) As Integer
End Function

_
Public Sub Main()
FixArithBug()

' Starts the application.
Application.Run(New Form1())
End Sub

Public Sub FixArithBug()
'PRB: System.Arithmetic Exception Error When You Change the Floating-Point Control Register in a Managed Application
'http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B326219 Const _MCW_EM As Integer = &H8001F
Const _RC_NEAR As Integer = &H0
Const _PC_53 As Integer = &H10000
Const _EM_INVALID As Integer = &H10
Const _EM_ZERODIVIDE As Integer = &H8
Const _EM_OVERFLOW As Integer = &H4
Const _EM_UNDERFLOW As Integer = &H2
Const _EM_INEXACT As Integer = &H1
Const _EM_DENORMAL As Integer = &H80000
Const _CW_DEFAULT As Integer = (_RC_NEAR + _PC_53 + _EM_INVALID + _EM_ZERODIVIDE + _EM_OVERFLOW + _EM_UNDERFLOW + _EM_INEXACT + _EM_DENORMAL)
_controlfp(_CW_DEFAULT, &HFFFFF)
End Sub
End Module

这个问题同时出现在framework1.0和1.1里面。
我实在不希望还出现在1.2里,因为这种程序之间互相干扰的问题有时候是很难发现。
类似的VS2003也对别的程序有影响。
这种类型的问题往往是因为WINDOWS的消息机制引起的,错误地发送消息给一个Window程序是常见的原因。但是因为寄存器的原因,我还是头一次遇到。

No comments: