System.AccessViolationException Occurs With ToolTips in Windows Forms Application

Applies to: .NET Framework 4.5

Symptoms


You have developed a Microsoft .NET Windows Forms application which uses a ToolTip control. When a Tooltip is displayed, you may receive a System.AccessViolationException and the application may terminate. 

Cause


This occurs when the application is using version 5.0 of the Windows Common Controls in comctl32.dll. The problem occurs due to a re-entrancy/timing issue that takes place when the application is attempting to display the ToolTip control, but then takes a code path which actually attempts to hide it before it was initially displayed. This is a bug in version 5.0 of the Windows Common Controls (comctl32.dll) provided by the operating system.

Resolution


This problem was corrected by version 6.0 of comctl32.dll. You can resolve the issue in a Windows Forms application by modifying the application to opt into version 6.0 of comctl32.dll. To opt into version 6.0 of comctl32.dll, Windows Forms applications should call Application.EnableVisualStyles.

For more information on the Application.EnableVisualStyles method, please see the following MSDN documentation.

Application.EnableVisualStyles Method
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.enablevisualstyles.aspx

More Information


When the Tooltip is being created, comctl32.dll stores internal state information which will be used later. When the user switches to another application, the application still has code pending that will be used to display the Tooltip. When the application detects it is being deactivated, comctl32.dll handles this by destroying the internal state information for the ToolTip. After this has completed, the call stack unwinds back to the original code which was attempting to display the Tooltip. The state information is accessed without being checked for null, which results in an access violation.

The faulting callstack will resemble the following when debugging.

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
  at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr, IntPtr, Int32, IntPtr, IntPtr)
  at System.Windows.Forms.NativeWindow.DefWndProc(System.Windows.Forms.Message ByRef)   
  at System.Windows.Forms.ToolTip.WndProc(System.Windows.Forms.Message ByRef)   
  at System.Windows.Forms.ToolTip+ToolTipNativeWindow.WndProc(System.Windows.Forms.Message ByRef)   
  at System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)  


If debugging this under a native debugger, such as Windbg, you will see the following access violation and callstack.

0:000> r 
eax=00000000 ebx=77392673 ecx=0012e59c edx=7c82845c esi=05d3cb80 edi=fffffdf7 
eip=775744b3 esp=0012e5c0 ebp=0012e604 iopl=0 nv up ei pl nz ac po nc 
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010212 
comctl32!DoShowBubble+0xc2: 
775744b3 8b480c mov ecx,dword ptr [eax+0Ch] ds:0023:0000000c=???????? 
 
0:000> knL 
# ChildEBP RetAddr
00 0012e604 775746d8 comctl32!DoShowBubble+0xc2 
01 0012e618 77543d63 comctl32!ShowBubbleForTool+0x32 
02 0012e62c 775358c3 comctl32!TTHandleTimer+0x8b 
03 0012e74c 7739b6e3 comctl32!ToolTipsWndProc+0x311 
04 0012e778 7739b874 user32!InternalCallWinProc+0x28 
05 0012e7f0 7739bfce0 user32!UserCallWinProcCheckWow+0x151
06 0012e820 7739bf74 user32!CallWindowProcAorW+0x98 
07 0012e840 7b56a9ad user32!CallWindowProcW+0x1b 
08 0012e898 7b52b79d System_Windows_Forms_ni!System.Windows.Forms.NativeWindow.DefWndProc(System.Windows.Forms.Message ByRef)+0x6d 
09 0012e97c 7b52b70e System_Windows_Forms_ni!System.Windows.Forms.ToolTip.WndProc(System.Windows.Forms.Message ByRef)+0x81 
0a 0012e9d4 7b56a256 System_Windows_Forms_ni!System.Windows.Forms.ToolTip+ToolTipNativeWindow.WndProc(System.Windows.Forms.Message ByRef)+0x12 
0b 0012e9d4 010e20bd System_Windows_Forms_ni!System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)+0x96 


By default, new Windows Forms applications should automatically call Application.EnableVisualStyles. In C# projects, this method call is added in the application's entry point in void Main() within Program.cs. In Visual Basic .Net projects, this method is called automatically if the "Enable Application Framework" and "Enable XP Visual Styles" options are selected in the project's Properties window.