这是一位老师向我反馈的问题,我的一个 WPF 应用程序在他的设备上,任何弹出保存文件对话框或打开文件对话框的功能,都会导致进程闪退。经过进一步调查,我发现他电脑上任何软件弹出文件保存对话框都会闪烁,问题本身和 WPF 无关。最终调查到是 Office 的一个注入组件导致的问题

问题现象:

任何 32 位应用程序调用 Win32 的保存文件对话框或打开文件对话框时,将会导致进程闪退

问题分析:

通过 procdump 工具,执行如下命令捞取到 DUMP 文件

procdump -ma -t 10384

更多 procdump 工具介绍和用法,请参阅 dotnet 代码调试方法

捞取到 DUMP 文件之后,用 7z 压缩传输回我的开发设备,拖入 Visual Studio 开启混合调试模式

可见进程崩溃的原因是 “该线程尝试读写某个虚拟地址,而它对该地址不具有相应的访问权限” 导致的,如下图所示

此时的异常堆栈如下

>	msvcp140.dll!mtx_do_lock(_Mtx_internal_imp_t * mtx=0x7c041850, const xtime * target=0x00000000) 行 103	C++
 	msvcp140.dll!_Mtx_lock(_Mtx_internal_imp_t * mtx=0x7c041850) 行 176	C++
 	GROOVEEX.DLL!7bdf3702()	未知
 	[下面的框架可能不正确和/或缺失,没有为 GROOVEEX.DLL 加载符号]	
 	GROOVEEX.DLL!7bdfbc8e()	未知
 	GROOVEEX.DLL!7bf05eb8()	未知
 	GROOVEEX.DLL!7bf05643()	未知
 	GROOVEEX.DLL!7bf0a7bb()	未知
 	combase.dll!7656b791()	未知
 	combase.dll!76568951()	未知
 	combase.dll!765688ff()	未知
 	combase.dll!765668bc()	未知
 	combase.dll!76564b85()	未知
 	combase.dll!76572e45()	未知
 	combase.dll!765e2cf5()	未知
 	combase.dll!765e2bad()	未知
 	combase.dll!765e2b31()	未知
 	combase.dll!7657230d()	未知
 	combase.dll!76572b4d()	未知
 	combase.dll!76572314()	未知
 	combase.dll!76572e45()	未知
 	combase.dll!7659a5a2()	未知
 	combase.dll!765dc1f6()	未知

异常信息如下

0x66A25883 (msvcp140.dll) (3ea524df923b4d8483fedff3e2e4b1a3.dmp 中)处有未经处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突。

通过模块窗口可见 GROOVEEX.DLL 的路径是: C:\Program Files\Microsoft Office\root\vfs\ProgramFilesX86\Microsoft Office\Office16\GROOVEEX.DLL

出现问题的 GROOVEEX.DLL 文件的版本是 16.0.19509.20000

查看签名文件确实是微软的签名,预计就是软软写错了什么代码导致的问题

尝试将 C:\Program Files\Microsoft Office\root\vfs\ProgramFilesX86\Microsoft Office\Office16\GROOVEEX.DLL 文件干掉后重启电脑,就不会出现问题了。如此也可证明确实是 Office 投毒

在网上搜到了对 grooveex.dll 文件的描述:

The grooveex.dll is an application extension for OneDrive for Business (Groove.exe).

The new OneDrive sync client (OneDrive.exe) doesn’t use this file. As you mentioned that the issue is caused by the grooveex.dll, for this situation, we suggest you exclude the groove.exe when you install Office with Office Deployment Tool. Then you can use the new OneDrive sync client instead of the groove.exe.

和:

As Rena mentioned in the former thread, the GROOVEEX.DLL file is related to the legacy OneDrive for Business sync client. Before, this sync client will be automatically installed with the Office suite from Office 365 for Business plans. If it still causes some issues on your computer, you may consider removing it with the steps mentioned in Rena’s post. To learn more, see Changes to the previous OneDrive sync client (Groove.exe) in Office 2016 Click-to-Run.

可见这是一个用在 OneDrive 上的组件

类似的 GROOVEEX.DLL 导致其他进程崩溃的记录如下:

如此可见 GROOVEEX.DLL 导致崩溃是一直都有人反馈的

特别感谢 lsj 的协助,让我了解了更本质的原因。通过错误堆栈 msvcp140.dll!_Mtx_lock(_Mtx_internal_imp_t * mtx=0x7c041850) 在网上搜,可见这是 https://github.com/microsoft/STL/issues/4730 问题导致的。我的应用程序是自己带 VC 运行时的,我自己带的 VC 运行时比较旧,而 GROOVEEX.DLL 依赖新的 VC 运行时,此行为触发了此 VC 运行时问题

这就意味着应用程序如果加载了自己带的旧版本的 VC 运行时,那么弹出文件对话框时,加载了 GROOVEEX.DLL 组件,将会由于 VC 版本兼容性问题导致进程崩溃

参考文档:


本文会经常更新,请阅读原文: https://blog.lindexi.com/post/Office-%E5%B7%B2%E7%9F%A5%E9%97%AE%E9%A2%98-GROOVEEX.DLL-%E5%B8%A6%E5%B4%A9%E8%BF%9B%E7%A8%8B.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者收藏我的博客导航

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

微软最具价值专家


无盈利,不卖课,做纯粹的技术博客

以下是广告时间

推荐关注 Edi.Wang 的公众号

欢迎进入 Eleven 老师组建的 .NET 社区

以上广告全是友情推广,无盈利