Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.AccessViolationException: Attempted to read or write protected memory error in WinQuickLook app #33620

Closed
DotNetAppCompatFeiWang opened this issue Mar 16, 2020 · 18 comments

Comments

@DotNetAppCompatFeiWang
Copy link

Application Name: WinQuickLook
OS: Windows 10 RS5
CPU: X64
.NET Build Number: 5.0.100-preview.2.20163.4
App Location:
App Source on GitHub link : https://github.com/shibayan/WinQuickLook

Verify Scenarios:
1). Windows 10 RS5 X64 + .NET Core SDK build : 3.1 : Pass
2). Windows 10 RS5 X64 + .NET Core SDK build : 5.0.100-preview.1.20125.9: Pass
3). Windows 10 RS5 X64 + .NET Core SDK build : 5.0.100-preview.2.20163.4: Fail

Repro Machine Environment Info :

.NET Core SDK (reflecting any global.json):
Version: 5.0.100-preview.2.20163.4
Commit: b5bccca3f5

Runtime Environment:
OS Name: Windows
OS Version: 10.0.18363
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.100-preview.2.20163.4\

Host (useful for support):
Version: 5.0.0-preview.2.20160.6
Commit: d12f79a

.NET Core SDKs installed:
5.0.100-preview.2.20163.4 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.App 5.0.0-preview.2.20160.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 5.0.0-preview.2.20160.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 5.0.0-preview.2.20160.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Repro steps:

On the repro machine (10.159.67.178)

  1. Start application from "C:\Repro\WinQuickLook\WinQuickLook.exe"
  2. Open Windows Explorer, select any item, folder or file
  3. Press Space bar

Expected Result:
It should show information about selected item in windows explorer

Actual Result:
Application crashes

Event Viewer Log :
Application: dotnet.exe
CoreCLR Version: 5.0.20.16006
.NET Core Version: 5.0.0-preview.2.20160.6
Description: The process was terminated due to an internal error in the .NET Runtime at IP 00007FFBEF05C2E4 (00007FFBEEED0000) with exit code c0000005.

Faulting application name: dotnet.exe, version: 5.0.20.16006, time stamp: 0x5e67fb06
Faulting module name: coreclr.dll, version: 5.0.20.16006, time stamp: 0x5e67eae9
Exception code: 0xc0000005
Fault offset: 0x000000000018c2e4
Faulting process id: 0x1a54
Faulting application start time: 0x01d5fad8a8bf9c6b
Faulting application path: C:\Program Files\dotnet\dotnet.exe
Faulting module path: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.0-preview.2.20160.6\coreclr.dll
Report Id: c07817b9-df85-4a2a-9cbc-c57e9c05aaa3
Faulting package full name:
Faulting package-relative application ID:

Stack Trace :
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at WinQuickLook.WinExplorerHelper.GetSelectedItemCore(WinQuickLook.Interop.IWebBrowserApp)
at WinQuickLook.WinExplorerHelper.GetSelectedItem()
at WinQuickLook.App.PerformQuickLook()
at System.Windows.Threading.DispatcherOperation.InvokeDelegateCore()
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(System.Object)
at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
at System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(System.Object)
at System.Windows.Application.RunInternal(System.Windows.Window)
at System.Windows.Application.Run()
at WinQuickLook.App.Main()

Findings:
Source code can be found at repro machine : C:\Repro\WinQuickLook_source

System.AccessViolationException Exception after this line:
shellFolder.GetDisplayNameOf(pidl, SHGDNF.FORPARSING, out var str)
https://github.com/shibayan/WinQuickLook/blob/master/WinQuickLook/Interop/ComInterfaceExtension.cs

Repro machine could be found at: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1082949

@dotnet-actwx-bot FYI

@Dotnet-GitSync-Bot
Copy link
Collaborator

I couldn't add an area label to this Issue.

Checkout this page to find out which area owner to ping, or please add exactly one area label to help train me in the future.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label Mar 16, 2020
@danmoseley
Copy link
Member

@DotNetAppCompatFeiWang can you please get full native call stack? Attach VS native debugger or windbg and repro it.

@danmoseley
Copy link
Member

@AaronRobinsonMSFT i put the interop label given that's apparently the point of the AV and the code worked in 3.1

@DotNetAppCompatFeiWang
Copy link
Author

DotNetAppCompatFeiWang commented Mar 17, 2020

Add Call Stack :

# Child-SP          RetAddr           Call Site
00 00000089`4d77d4c0 00007ffa`615fbc39 WinQuickLook!WinQuickLook.WinExplorerHelper.GetSelectedItemCore(WinQuickLook.Interop.IWebBrowserApp)+0x188
01 00000089`4d77d5b0 00007ffa`615fb5d4 WinQuickLook!WinQuickLook.WinExplorerHelper.GetSelectedItem()+0x2a9
02 00000089`4d77d700 00007ffa`bedecdd5 WinQuickLook!WinQuickLook.App.PerformQuickLook()+0x34
03 00000089`4d77d760 00007ffa`bedeccc7 WindowsBase!System.Windows.Threading.DispatcherOperation.InvokeDelegateCore()+0x15
04 00000089`4d77d790 00007ffa`bedecbd2 WindowsBase!System.Windows.Threading.DispatcherOperation.InvokeImpl()+0xe7
05 00000089`4d77d800 00007ffa`bed86777 WindowsBase!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(System.Object)+0x22
06 00000089`4d77d830 00007ffa`c02f0af6 WindowsBase!MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(System.Object)+0x37
07 00000089`4d77d870 00007ffa`c02c3a1f System_Private_CoreLib!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x76
08 00000089`4d77d8f0 00007ffa`bed866c3 System_Private_CoreLib!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0xf
09 00000089`4d77d920 00007ffa`bedeca22 WindowsBase!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object)+0xf3
0a 00000089`4d77d970 00007ffa`bede975f WindowsBase!System.Windows.Threading.DispatcherOperation.Invoke()+0x42
0b 00000089`4d77d9d0 00007ffa`bede9c96 WindowsBase!System.Windows.Threading.Dispatcher.ProcessQueue()+0x25f
0c 00000089`4d77da70 00007ffa`bed76cb6 WindowsBase!System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)+0x86
0d 00000089`4d77db00 00007ffa`bed75e19 WindowsBase!MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)+0xa6
0e 00000089`4d77db90 00007ffa`bede5f65 WindowsBase!MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)+0x79
0f 00000089`4d77dbe0 00007ffa`bede5df6 WindowsBase!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)+0xd5
10 00000089`4d77dc40 00007ffa`bede831e WindowsBase!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)+0x36
11 00000089`4d77dc90 00007ffa`bed75bbc WindowsBase!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)+0x16e
12 00000089`4d77dd20 00007ffa`60db2882 WindowsBase!MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)+0x21c
13 00000089`4d77de50 00007ffa`c090634b DirectWriteForwarder!ILStubClass.IL_STUB_ReversePInvoke(Int64, Int32, Int64, Int64)+0x42
14 00000089`4d77dea0 00007ffb`07805c0d coreclr!coreclr_shutdown_2+0xef2b
15 00000089`4d77df30 00007ffb`07805602 USER32!CallWindowProcW+0x3bd
16 00000089`4d77e0c0 00007ffa`615d203b USER32!DispatchMessageW+0x1f2
17 00000089`4d77e140 00007ffa`bede9932 DirectWriteForwarder!ILStubClass.IL_STUB_PInvoke(System.Windows.Interop.MSG ByRef)+0x7b
18 00000089`4d77e200 00007ffa`bede6ed1 WindowsBase!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)+0xd2
19 00000089`4d77e290 00007ffa`bede6e7e WindowsBase!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame)+0x41
1a 00000089`4d77e2c0 00007ffa`bf5fbeec WindowsBase!System.Windows.Threading.Dispatcher.Run()+0x3e
1b 00000089`4d77e2f0 00007ffa`bf5fa4f1 PresentationFramework!System.Windows.Application.RunDispatcher(System.Object)+0x1c
1c 00000089`4d77e320 00007ffa`bf5f740c PresentationFramework!System.Windows.Application.RunInternal(System.Windows.Window)+0x161
1d 00000089`4d77e370 00007ffa`60d90f2e PresentationFramework!System.Windows.Application.Run()+0x2c
1e 00000089`4d77e3a0 00007ffa`c0906233 WinQuickLook!WinQuickLook.App.Main()+0x5e
1f 00000089`4d77e3f0 00007ffa`c084918f coreclr!coreclr_shutdown_2+0xee13
20 00000089`4d77e430 00007ffa`c08bb8eb coreclr+0x8918f
21 00000089`4d77e570 00007ffa`c08bb736 coreclr!coreclr_initialize+0x3bbb
22 00000089`4d77e6a0 00007ffa`c08bb4a3 coreclr!coreclr_initialize+0x3a06
23 00000089`4d77e750 00007ffa`c08bb24e coreclr!coreclr_initialize+0x3773
24 00000089`4d77eaf0 00007ffa`c08b7a1a coreclr!coreclr_initialize+0x351e
25 00000089`4d77ec60 00007ffa`d3ea4f1d coreclr!coreclr_execute_assembly+0xfa
26 00000089`4d77ed00 00007ffa`d3eb441c hostpolicy+0x4f1d
27 00000089`4d77ed50 00007ffa`d3eb3eac hostpolicy+0x1441c
28 00000089`4d77eeb0 00007ffa`d3eb5aa5 hostpolicy+0x13eac
29 00000089`4d77eef0 00007ffa`d8c4bcca hostpolicy!corehost_main+0x255
2a 00000089`4d77f0d0 00007ffa`d8c4f41c hostfxr!hostfxr_set_runtime_property_value+0x37ba
2b 00000089`4d77f1a0 00007ffa`d8c4e1d7 hostfxr!hostfxr_set_runtime_property_value+0x6f0c
2c 00000089`4d77f2a0 00007ffa`d8c4b94b hostfxr!hostfxr_set_runtime_property_value+0x5cc7
2d 00000089`4d77f330 00007ffa`d8c47f9c hostfxr!hostfxr_set_runtime_property_value+0x343b
2e 00000089`4d77f470 00007ff6`dfd5fa1f hostfxr!hostfxr_main_startupinfo+0x9c
2f 00000089`4d77f570 00007ff6`dfd5fdf7 apphost+0xfa1f
30 00000089`4d77f780 00007ff6`dfd61fa8 apphost+0xfdf7
31 00000089`4d77f8a0 00007ffb`06ed7bd4 apphost+0x11fa8
32 00000089`4d77f8e0 00007ffb`0812ced1 KERNEL32!BaseThreadInitThunk+0x14
33 00000089`4d77f910 00000000`00000000 ntdll!RtlUserThreadStart+0x21

@AaronRobinsonMSFT
Copy link
Member

I am unable to see this failure anywhere. I keep getting the following and then an immediate crash. @DotNetAppCompatFeiWang can you please collect a full DMP and leave it on the machine so someone can investigate. Thanks.

0:000> !pe
Exception object: 000002498036bf60
Exception type:   System.Exception
Message:          Element not found. (0x80070490)
InnerException:   <none>
StackTrace (generated):
    SP               IP               Function
    000000C80837D880 0000000000000000 Windows_ApplicationModel!Windows.ApplicationModel.StartupTask.GetAsync(System.String)+0x1
    000000C80837D990 00007FFB8EC4DDC9 WinQuickLook!WinQuickLook.NotifyIconWrapper+<<InitializeContextMenus>b__1_0>d.MoveNext()+0x79
    000000C80837D940 00007FFBED8B0261 System_Private_CoreLib!System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()+0x21
    000000C80837D970 00007FFBEDA1F608 System_Private_CoreLib!System.Threading.Tasks.Task+<>c.<ThrowAsync>b__139_0(System.Object)+0x18
    000000C80837D9A0 00007FFC02825F85 WindowsBase!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)+0xf5
    000000C80837DA00 00007FFC02825DF6 WindowsBase!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)+0x36
    000000C80837DA50 00007FFC0282CD28 WindowsBase!System.Windows.Threading.DispatcherOperation.InvokeImpl()+0x148
    000000C80837DAC0 00007FFC0282CBD2 WindowsBase!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(System.Object)+0x22
    000000C80837DAF0 00007FFC027C6777 WindowsBase!MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(System.Object)+0x37
    000000C80837DB30 00007FFBED930AF6 System_Private_CoreLib!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x76
    000000C80837DB00 00007FFBED8B0261 System_Private_CoreLib!System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()+0x21
    000000C80837DB30 00007FFBED930B5E System_Private_CoreLib!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0xde
    000000C80837DBB0 00007FFBED903A1F System_Private_CoreLib!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0xf
    000000C80837DBE0 00007FFC027C66C3 WindowsBase!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object)+0xf3
    000000C80837DC30 00007FFC0282CA22 WindowsBase!System.Windows.Threading.DispatcherOperation.Invoke()+0x42
    000000C80837DC90 00007FFC0282975F WindowsBase!System.Windows.Threading.Dispatcher.ProcessQueue()+0x25f
    000000C80837DD30 00007FFC02829C96 WindowsBase!System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)+0x86
    000000C80837DDC0 00007FFC027B6CB6 WindowsBase!MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)+0xa6
    000000C80837DE50 00007FFC027B5E19 WindowsBase!MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)+0x79
    000000C80837DEA0 00007FFC02825F65 WindowsBase!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)+0xd5
    000000C80837DF00 00007FFC02825DF6 WindowsBase!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)+0x36
    000000C80837DF50 00007FFC0282831E WindowsBase!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)+0x16e
    000000C80837DFE0 00007FFC027B5BBC WindowsBase!MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)+0x21c
    000000C80837E400 0000000000000000 WindowsBase!MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)+0x1
    000000C80837E4C0 00007FFC02829932 WindowsBase!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)+0xd2
    000000C80837E550 00007FFC02826ED1 WindowsBase!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame)+0x41
    000000C80837E580 00007FFC02826E7E WindowsBase!System.Windows.Threading.Dispatcher.Run()+0x3e
    000000C80837E5B0 00007FFBE55EBEEC PresentationFramework!System.Windows.Application.RunDispatcher(System.Object)+0x1c
    000000C80837E5E0 00007FFBE55EA4F1 PresentationFramework!System.Windows.Application.RunInternal(System.Windows.Window)+0x161
    000000C80837E630 00007FFBE55E740C PresentationFramework!System.Windows.Application.Run()+0x2c
    000000C80837E660 00007FFB8E3F10FE WinQuickLook!WinQuickLook.App.Main()+0x5e

StackTraceString: <none>
HResult: 80070490

@DotNetAppCompatFeiWang
Copy link
Author

Saved on the repro machine at "C:\Repro\WinQuicklook.dmp".

BTW, after launch application, don't click on notifyicon, it crashes, we ignore it because it is same on 3.0.x & 3.1.x.

@danmoseley
Copy link
Member

@AaronRobinsonMSFT do you have what you need? I know @richaverma1 is tracking this one.

@AaronRobinsonMSFT
Copy link
Member

@danmosemsft I didn't realize the urgency of this issue. I have all that I need locally. Focusing on this issue.

@AaronRobinsonMSFT AaronRobinsonMSFT removed the untriaged New issue has not been triaged by the area owner label Mar 24, 2020
@AaronRobinsonMSFT AaronRobinsonMSFT added this to the 5.0 milestone Mar 24, 2020
@danmoseley
Copy link
Member

@DotNetAppCompatFeiWang when posting blocks of output like the callstack above, please surround with triple back ticks (```) on their own line above and their own line below. This fixes the formatting. You see I have done that with your callstack above, as Aaron did with his.

@AaronRobinsonMSFT
Copy link
Member

Okay I think this is more likely a JIT bug. Here is how I am getting there.

The following is the failing stack:

>	WinQuickLook.dll!WinQuickLook.Interop.ComInterfaceExtension.GetDisplayNameOf(WinQuickLook.Interop.IShellFolder shellFolder, System.IntPtr pidl, WinQuickLook.Interop.SHGDNF uFlags) Line 54	C#
 	WinQuickLook.dll!WinQuickLook.WinExplorerHelper.GetSelectedItemCore(WinQuickLook.Interop.IWebBrowserApp webBrowserApp) Line 144	C#
 	WinQuickLook.dll!WinQuickLook.WinExplorerHelper.GetSelectedItem() Line 105	C#
 	WinQuickLook.dll!WinQuickLook.App.PerformQuickLook() Line 68	C#
 	WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeDelegateCore()	Unknown

Disassembly of top frame:

00007FFA0A7F5BA4 48 8B 55 18          mov         rdx,qword ptr [rbp+18h]  
00007FFA0A7F5BA8 49 BB E8 19 7A 09 FA 7F 00 00 mov         r11,7FFA097A19E8h  
00007FFA0A7F5BB2 41 B8 00 80 00 00    mov         r8d,8000h  
00007FFA0A7F5BB8 39 09                cmp         dword ptr [rcx],ecx  
00007FFA0A7F5BBA FF 15 28 BE FA FE    call        qword ptr [7FFA097A19E8h]  
00007FFA0A7F5BC0 90                   nop  
00007FFA0A7F5BC1 48 8D 8D F8 FE FF FF lea         rcx,[rbp-108h]  
00007FFA0A7F5BC8 4C 8D 85 F0 FE FF FF lea         r8,[rbp-110h]  
00007FFA0A7F5BCF 48 8B 55 18          mov         rdx,qword ptr [rbp+18h]  
00007FFA0A7F5BD3 E8 A8 02 90 FF       call        00007FFA0A0F5E80  
00007FFA0A7F5BD8 90                   nop  
00007FFA0A7F5BD9 48 8B 85 F0 FE FF FF mov         rax,qword ptr [rbp-110h]  
00007FFA0A7F5BE0 48 89 85 E8 FE FF FF mov         qword ptr [rbp-118h],rax  
00007FFA0A7F5BE7 90                   nop  
00007FFA0A7F5BE8 EB 00                jmp         00007FFA0A7F5BEA  
00007FFA0A7F5BEA 48 8B 85 E8 FE FF FF mov         rax,qword ptr [rbp-118h]  
00007FFA0A7F5BF1 48 8D 65 00          lea         rsp,[rbp]  
00007FFA0A7F5BF5 5D                   pop         rbp  
00007FFA0A7F5BF6 C3                   ret  

Register state after 00007FFA0A7F5BF5 above.

RAX = 000001BD252728B8
RBX = 000001BD25271D88
RCX = 000000402B1FE378
RDX = 000001BD2317B200
RSI = 000001BD24CCC300
RDI = 000001BD24DC4280
R8  = 0000000000000140
R9  = 0000000000000006
R10 = 0000000000000140
R11 = 0000000000000060
R12 = 000001BD34C8BCC0
R13 = 0000000000000000
R14 = 0000000000000000
R15 = 00000000FFFFFFFF
RIP = 00007FFA0A7F5BF6
RSP = 000000402B1FD6D8
RBP = 0000000000000000
EFL = 00000246

Once the frame returns, the RBP register is dereferenced as follows at 00007FFA0A7F4CE8 thus leading to the A/V.

00007FFA0A7F4CE3 E8 A0 CD FF FF       call        00007FFA0A7F1A88  
00007FFA0A7F4CE8 48 89 85 68 FF FF FF mov         qword ptr [rbp-98h],rax  
00007FFA0A7F4CEF 48 8B 8D 68 FF FF FF mov         rcx,qword ptr [rbp-98h] 

I have a local repro and can provide additional information if needed. Perhaps JITDump of ComInterfaceExtension.GetDisplayNameOf()?

/cc @BruceForstall @dotnet/jit-contrib

@briansull
Copy link
Contributor

Source code for
WinQuickLook.Interop.ComInterfaceExtension.GetDisplayNameOf(WinQuickLook.Interop.IShellFolder shellFolder, System.IntPtr pidl, WinQuickLook.Interop.SHGDNF uFlags)

    public static string GetDisplayNameOf(this IShellFolder shellFolder, IntPtr pidl, SHGDNF uFlags)
    {
        shellFolder.GetDisplayNameOf(pidl, SHGDNF.FORPARSING, out var str);

        NativeMethods.StrRetToBSTR(ref str, pidl, out var buffer);

        return buffer;
    }

@briansull
Copy link
Contributor

briansull commented Mar 24, 2020

Debug instructions:

Set a breakpoint upon entry of the method
ComInterfaceExtension.GetDisplayNameOf

There should be a push rbp at the start of the method.

Step past it (observe the value being pushed is not zero)
then set a data break point on the stack area where rbp was saved.

hit go and find out who is overruning the stack and writing a zero value on the saved rbp

@AaronRobinsonMSFT
Copy link
Member

Simplified repro below.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Text;

using ComTypes = System.Runtime.InteropServices.ComTypes;
using System.Threading;

public static class ComInterfaceExtension
{
    public static TInterface QueryInterface<TInterface>(this IUnknown obj)
    {
        return (TInterface)obj;
    }

    public static TInterface QueryService<TInterface>(this IServiceProviderAlt serviceProvider, Guid guidService)
    {
        serviceProvider.QueryService(guidService, typeof(TInterface).GUID, out var ppvObject);

        return (TInterface)ppvObject;
    }

    public static IShellView QueryActiveShellView(this IShellBrowser shellBrowser)
    {
        shellBrowser.QueryActiveShellView(out var ppshv);

        return ppshv;
    }

    public static TInterface GetFolder<TInterface>(this IFolderView folderView)
    {
        folderView.GetFolder(typeof(TInterface).GUID, out var ppv);

        return (TInterface)ppv;
    }

    public static int GetFocusedItem(this IFolderView folderView)
    {
        folderView.GetFocusedItem(out var piItem);

        return piItem;
    }

    public static IntPtr Item(this IFolderView folderView, int index)
    {
        folderView.Item(index, out var pidl);

        return pidl;
    }

    public static string GetDisplayNameOfHelper(this IShellFolder shellFolder, IntPtr pidl, SHGDNF uFlags)
    {
        STRRET str;
        shellFolder.GetDisplayNameOf(pidl, SHGDNF.FORPARSING, out str);

        NativeMethods.StrRetToBSTR(ref str, pidl, out var buffer);

        return buffer;
    }
}

public static class SID
{
    public static readonly Guid STopLevelBrowser = new Guid(0x4C96BE40, 0x915C, 0x11CF, 0x99, 0xD3, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37);
}

public unsafe class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Attach...");
        Console.ReadLine();

        Console.WriteLine("Switch to a Windows explorer window and select an item...");
        Thread.Sleep(5000);

        var foregroundHwnd = NativeMethods.GetForegroundWindow();
        Console.WriteLine($"Foreground HWND: 0x{foregroundHwnd.ToInt64():x}");

        var shellWindows = (IShellWindows)Activator.CreateInstance(CLSID.ShellWindowsType);

        string fileName = string.Empty;

        for (int i = 0; i < shellWindows.Count; i++)
        {
            var webBrowserApp = (IWebBrowserApp)shellWindows.Item(i);

            var hwnd = webBrowserApp.get_HWND();

            Console.WriteLine($"HWND: 0x{hwnd.ToInt64():x}");

            if (hwnd == foregroundHwnd)
            {
                Console.WriteLine($"HWND is foreground!");
                fileName = GetSelectedItemCore(webBrowserApp);

                Marshal.FinalReleaseComObject(webBrowserApp);

                break;
            }

            Marshal.FinalReleaseComObject(webBrowserApp);
        }

        Console.WriteLine($"Filename: {fileName}");
    }

    private static string GetSelectedItemCore(IWebBrowserApp webBrowserApp)
    {
        var serviceProvider = webBrowserApp.QueryInterface<IServiceProviderAlt>();

        var shellBrowser = serviceProvider.QueryService<IShellBrowser>(SID.STopLevelBrowser);

        var shellView = shellBrowser.QueryActiveShellView();

        var folderView = shellView.QueryInterface<IFolderView>();

        int focus = folderView.GetFocusedItem();

        var persistFolder2 = folderView.GetFolder<IPersistFolder2>();

        var shellFolder = persistFolder2.QueryInterface<IShellFolder>();

        var pidl = folderView.Item(focus);

        //GC.Collect();
        var fileName = shellFolder.GetDisplayNameOfHelper(pidl, SHGDNF.FORPARSING);

        // Cleanup
        Marshal.FreeCoTaskMem(pidl);

        Marshal.FinalReleaseComObject(shellFolder);
        Marshal.FinalReleaseComObject(folderView);
        Marshal.FinalReleaseComObject(shellBrowser);
        Marshal.FinalReleaseComObject(serviceProvider);

        return fileName;
    }
}

public static class CLSID
{
    public static readonly Guid ShellWindows = new Guid("9BA05972-F6A8-11CF-A442-00A0C90A8F39");
    public static readonly Type ShellWindowsType = Type.GetTypeFromCLSID(ShellWindows);
}

internal static class NativeMethods
{
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr SetWindowsHookEx(int hookType, LowLevelKeyboardProc hookDelegate, IntPtr module, uint threadId);

    [DllImport("user32.dll")]
    public static extern bool UnhookWindowsHookEx(IntPtr hook);

    [DllImport("user32.dll")]
    public static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("shlwapi.dll")]
    public static extern void StrRetToBSTR([In, Out] ref STRRET pstr, [In] IntPtr pidl, [Out, MarshalAs(UnmanagedType.BStr)] out string pbstr);
}

[StructLayout(LayoutKind.Explicit, Size = 264)]
public struct STRRET
{
    [FieldOffset(0)]
    public uint uType;

    [FieldOffset(4)]
    public IntPtr pOleStr;

    [FieldOffset(4)]
    public uint uOffset;

    [FieldOffset(4)]
    public IntPtr cStr;
}

public interface IUnknown
{
}

[ComImport]
[Guid("85CB6900-4D95-11CF-960C-0080C7F4EE85")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IShellWindows : IUnknown
{
    int Count { get; }

    [return: MarshalAs(UnmanagedType.IDispatch)]
    object Item([In, Optional, MarshalAs(UnmanagedType.Struct)] object index);

    [return: MarshalAs(UnmanagedType.IUnknown)]
    object _NewEnum();

    void Register([In, MarshalAs(UnmanagedType.IDispatch)] object pid, [In] IntPtr hwnd, [In] int swClass, [Out] out int plCookie);

    void RegisterPending([In] int lThreadId, [In] object pvarloc, [In] object pvarlocRoot, [In] int swClass, [Out] out int plCookie);

    void Revoke(int lCookie);

    void OnNavigate([In] int lCookie, [In] object pvarLoc);

    void OnActivated([In] int lCookie, [In, MarshalAs(UnmanagedType.VariantBool)] bool fActive);

    //void FindWindowSW([In] ref object pvarLoc, [In] ref object pvarLocRoot, [In] ShellWindowTypeConstants swClass, [Out] out IntPtr phwnd, [In] ShellWindowFindWindowOptions swfwOptions, [Out, MarshalAs(UnmanagedType.Interface)] out IWebBrowserApp ppdispOut);

    void FindWindowSW_PlaceHolder();

    void OnCreated([In] long lCookie, [In, MarshalAs(UnmanagedType.IUnknown)] object punk);

    void ProcessAttachDetach([In, MarshalAs(UnmanagedType.VariantBool)] bool fAttach);
}

[ComImport]
[Guid("0002DF05-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IWebBrowserApp : IUnknown
{
    void GoBack();

    void GoForward();

    void GoHome();

    void GoSearch();

    void Navigate([In] string url, [In, Optional] object flags, [In, Optional] object targetFrameName, [In, Optional] object postData, [In, Optional] object headers);

    void Refresh();

    void Refresh2([In, Optional] object level);

    void Stop();

    [return: MarshalAs(UnmanagedType.IDispatch)]
    object get_Application();

    [return: MarshalAs(UnmanagedType.IDispatch)]
    void get_Parent();

    [return: MarshalAs(UnmanagedType.IDispatch)]
    void get_Container();

    [return: MarshalAs(UnmanagedType.IDispatch)]
    void get_Document();

    [return: MarshalAs(UnmanagedType.VariantBool)]
    bool get_TopLevelContainer();

    string get_Type();

    int get_Left();

    void put_Left([In] int left);

    int get_Top();

    void put_Top([In] int top);

    int get_Width();

    void put_Width([In] int width);

    int get_Height();

    void put_Height([In] int height);

    string get_LocationName();

    string get_LocationURL();

    [return: MarshalAs(UnmanagedType.VariantBool)]
    bool get_Busy();

    // IWebBrowserApp
    void Quit();

    void ClientToWindow([In, Out] ref int pcx, [In, Out] ref int pcy);

    void PutProperty([In] string property, [In] object vtValue);

    object GetProperty([In] string property);

    string get_Name();

    IntPtr get_HWND();

    string get_FullName();

    string get_Path();

    [return: MarshalAs(UnmanagedType.VariantBool)]
    bool get_Visible();

    void put_Visible([In, MarshalAs(UnmanagedType.VariantBool)] bool value);

    [return: MarshalAs(UnmanagedType.VariantBool)]
    bool get_StatusBar();

    void put_StatusBar([In, MarshalAs(UnmanagedType.VariantBool)] bool value);

    string get_StatusText();

    void put_StatusText([In] string statusText);

    int get_ToolBar();

    void put_ToolBar([In] int value);

    [return: MarshalAs(UnmanagedType.VariantBool)]
    bool get_MenuBar();

    void put_MenuBar([In, MarshalAs(UnmanagedType.VariantBool)] bool value);

    [return: MarshalAs(UnmanagedType.VariantBool)]
    bool get_FullScreen();

    void put_FullScreen([In, MarshalAs(UnmanagedType.VariantBool)] bool bFullScreen);
}

[ComImport]
[Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IServiceProviderAlt : IUnknown
{
    [PreserveSig]
    [return: MarshalAs(UnmanagedType.I4)]
    int QueryService([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidService, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object ppvObject);
}

[ComImport]
[Guid("000214E2-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellBrowser : IUnknown
{
    void GetWindow([Out] IntPtr phwnd);

    void ContextSensitiveHelp([In] bool fEnterMode);

    void InsertMenusSB([In] IntPtr hmenuShared, [In, Out] IntPtr lpMenuWidths);

    void SetMenuSB([In] IntPtr hmenuShared, [In] IntPtr holemenuRes, [In] IntPtr hwndActiveObject);

    void RemoveMenusSB([In] IntPtr hmenuShared);

    void SetStatusTextSB([In, MarshalAs(UnmanagedType.LPWStr)] string pszStatusText);

    void EnableModelessSB([In] bool fEnable);

    void TranslateAcceleratorSB([In] IntPtr pmsg, [In] ushort wId);

    void BrowseObject([In] IntPtr pidl, [In] uint wFlags);

    void GetViewStateStream([In] uint grfMode, [Out] out IntPtr ppStrm);

    void GetControlWindow([In] uint id, [Out] IntPtr phwnd);

    void SendControlMsg([In] uint id, [In] uint uMsg, [In] uint wParam, [In] uint lParam, [Out] IntPtr pret);

    void QueryActiveShellView([Out] out IShellView ppshv);

    void OnViewWindowActive([In] IShellView pshv);

    void SetToolbarItems([In] IntPtr lpButtons, [In] uint nButtons, [In] uint uFlags);
}

[ComImport]
[Guid("000214E3-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellView : IUnknown
{
}

[ComImport]
[Guid("cde725b0-ccc9-4519-917e-325d72fab4ce")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFolderView : IUnknown
{
    void GetCurrentViewMode([Out] out uint pViewMode);

    void SetCurrentViewMode([In] uint viewMode);

    void GetFolder([In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object ppv);

    void Item([In] int iItemIndex, [Out] out IntPtr ppidl);

    void ItemCount([In] uint uFlags, [Out] out int pcItems);

    void Items([In] uint uFlags, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object ppv);

    void GetSelectionMarkedItem([Out] out int piItem);

    void GetFocusedItem([Out] out int piItem);

    void GetItemPosition([In] IntPtr pidl, [Out] out POINT ppt);

    void GetSpacing([In, Out] ref POINT ppt);

    void GetDefaultSpacing([Out] out POINT ppt);

    void GetAutoArrange();

    void SelectItem([In] int iItem, [In] uint dwFlags);

    void SelectAndPositionItems([In] uint cidl, [In] IntPtr apidl, [In] IntPtr apt, [In] uint dwFlags);
}

[ComImport]
[Guid("1AC3D9F0-175C-11d1-95BE-00609797EA4F")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersistFolder2 : IUnknown
{
    void GetClassID([Out] IntPtr pClassId);

    void Initialize([In] IntPtr pidl);

    void GetCurFolder([Out] IntPtr ppidl);
}

[ComImport]
[Guid("000214E6-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellFolder : IUnknown
{
    void ParseDisplayName([In] IntPtr hwnd, [In] IntPtr pbc, [In, MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName, [In, Out] ref uint pchEaten, [Out] out IntPtr ppidl, [In, Out] ref uint pdwAttributes);

    void EnumObjects([In] IntPtr hwnd, [In] uint grfFlags, [Out] IntPtr ppenumIdList);

    void BindToObject([In] IntPtr pidl, [In] IntPtr pbc, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object ppv);

    void BindToStorage([In] IntPtr pidl, [In] IntPtr pbc, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object ppv);

    void CompareIDs([In] uint lParam, [In] IntPtr pidl1, [In] IntPtr pidl2);

    void CreateViewObject([In] IntPtr hwndOwner, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object ppv);

    void GetAttributesOf([In] uint cidl, [In] IntPtr apidl, [In, Out] ref IntPtr rgfInOut);

    void GetUIObjectOf([In] IntPtr hwndOwner, [In] uint cidl, [In] IntPtr apidl, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [In, Out] ref uint rgfReserved, [Out, MarshalAs(UnmanagedType.Interface)] out object ppv);

    void GetDisplayNameOf([In] IntPtr pidl, [In] SHGDNF uFlags, [Out] out STRRET pName);

    void SetNameOf([In] IntPtr hwnd, [In] IntPtr pidl, [In, MarshalAs(UnmanagedType.LPWStr)] string pszName, [In] uint uFlags, [Out] out IntPtr ppidlOut);
}


[Flags]
public enum SHGDNF : uint
{
    NORMAL = 0,
    INFOLDER = 0x1,
    FOREDITING = 0x1000,
    FORADDRESSBAR = 0x4000,
    FORPARSING = 0x8000
}

[StructLayout(LayoutKind.Sequential)]
public struct SIZE
{
    public int cx;
    public int cy;

    public SIZE(int cx, int cy)
    {
        this.cx = cx;
        this.cy = cy;
    }
}

[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
    public int x;
    public int y;

    public POINT(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

@DotNetAppCompatFeiWang
Copy link
Author

Any update about this?

@AaronRobinsonMSFT AaronRobinsonMSFT added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI area-Interop-coreclr and removed area-Interop-coreclr area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI labels Apr 21, 2020
@AaronRobinsonMSFT
Copy link
Member

AaronRobinsonMSFT commented Apr 21, 2020

@DotNetAppCompatFeiWang This appears to have uncovered a long standing bug in the interaction between the JIT and COM-RPC. The size of the struct defined above is incorrect based on its official MIDL definition for 64-bit. For a 64-bit process the size should be 272. In a 32-bit process the size is 264. That is the issue. The JIT has gotten smarter and this incorrect size definition has lurked for a long time. Note that the defined offsets are also incorrect for 64-bit - they should be 8.

I have some investigations I want to perform to provide the best guidance on how to fix the definition. At the moment and probably the best fix is to indicate the maximum size the struct could ever be which is 272. That size will work for both 32 and 64 bit.

@AaronRobinsonMSFT
Copy link
Member

After an additional investigation into this issue, it has been determined this is indeed a long standing issue with the current definition when used in a 64-bit process (i.e. it worked by accident). The official native definition of STRRET doesn't define the type in terms of COM-RPC, that is found in ShTypes.Idl and comes with the Windows SDK. The correct managed layouts that are compatible with COM-RPC are as follows:

Managed definition 32-bit:

[StructLayout(LayoutKind.Explicit, Size = 264)]
public struct STRRET
{
    [FieldOffset(0)]
    public uint uType;

    [FieldOffset(4)]
    public IntPtr pOleStr;

    [FieldOffset(4)]
    public uint uOffset;

    [FieldOffset(4)]
    public IntPtr cStr;
}

Managed definition 64-bit:

[StructLayout(LayoutKind.Explicit, Size = 272)]
public struct STRRET
{
    [FieldOffset(0)]
    public uint uType;

    [FieldOffset(8)]
    public IntPtr pOleStr;

    [FieldOffset(8)]
    public uint uOffset;

    [FieldOffset(8)]
    public IntPtr cStr;
}

@AaronRobinsonMSFT AaronRobinsonMSFT added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Apr 21, 2020
@AaronRobinsonMSFT AaronRobinsonMSFT removed the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Apr 21, 2020
@DotNetAppCompatFeiWang
Copy link
Author

This bug found by AppCompat lab, documentation was added. It is not a breaking change but changes in JIT exposed a longstanding bug but since this usage is common, it is addressed with product documentation and add a link to the PR below.
dotnet/docs#18087

@AaronRobinsonMSFT
Copy link
Member

@DotNetAppCompatFeiWang Thanks for closing the loop here. Appreciate the diligence.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants