专栏首页林德熙的博客记一次调试资源管理器未响应经验

记一次调试资源管理器未响应经验

有小伙伴告诉我一台设备全触摸失效了,但实际上是资源管理器未响应。通过本文可以了解到调试的思路和用到的工具

不要相信测试

测试小伙伴发现,在进行100次开机关机之后,可能会有触摸失效。触摸失效是桌面触摸没反应,但是有时在桌面触摸没反应时,触摸任务栏又能恢复,但是过一会又不能触摸

也就是看起来是触摸屏没有告诉系统有触摸,可能是只有任务栏所在的范围可以触摸

于是我就猜关机会关闭触摸屏,触摸屏在开机的时候,进入了休眠。需要有触摸才能唤醒,但是触摸屏的上面部分没有开启,只有下面任务栏部分开启。当触摸到下面部分,将会接收触摸,触摸屏唤醒。这是硬件的问题

触摸屏有两个模式,和显示器一样,一个是节能模式,一个是工作模式,进入节能模式需要收到触摸或其他硬件唤醒才进入工作模式

硬件小伙伴准备拿着 BusHound 去抓触摸屏发送的消息,发现插入鼠标时点击桌面也没有打开,于是这个问题就不是触摸问题

测试套路

在发现这个问题不是触摸屏问题时,我就需要去调试。但是在调试之前,可以请测试工程师多做一些协助,这就是测试套路

对于不是一定能触发的坑,测试的思路是找到更短步骤

现在是 100 次才触发,能不能找到某个方法可以做到 10 次以内就触发。现在需要关机,关电源,等待一会,然后开机,等待开机完成,触摸一下。能不能找到其他方式,如只需要重启

猜可能的问题

遇到这个没有思路的问题,那么按照我是逗比开发的思路,我可以如何作出让资源管理器没有响应输入

假设我做了一个透明窗口,这个透明窗口是开机自动启动,作为最大化窗口。此时这个窗口将会吃掉所有的除任务栏的输入

这个假设有这样的问题,为什么点击任务栏就能恢复?回应原因是点击任务栏应用失去焦点,失去焦点窗口自动关闭

或者我做了一个全局钩子,这个钩子将会吃掉所有点击桌面的输入

根据可能调试

我的小伙伴伟霖大佬发现了用键盘打开任务管理器,此时任务管理器可以响应输入,但是桌面依然不可以。此时说明上面的猜测都是不对的,因为点击任务管理器也就是透明窗口失去焦点,如果他会隐藏,那么就隐藏了。如果是全局钩子,那么也点不到任务管理器

所以上面的思路是不对的

实际问题

在任务管理器发现了资源管理器没有响应

也就是实际问题就是资源管理器没有响应,需要了解为什么资源管理器没有响应和可以如何解决

如果这个问题在网上问,基本上小伙伴都会说升级系统,和打补丁。这也是我的思路,假设这个问题微软已经解决了,我也就不需要再进行调试。但是打上了补丁发现依然存在这个问题,于是接下来就是本文的核心,进行调试

搜寻信息

我信仰微软,我不相信全球有这么多用户量的系统,会出现这样的问题。我按照描述在网上搜了很久,虽然也有相近的博客,但是说的都不是我遇到的问题

在发现系统的软件出现问题,第一反应应该是去系统日志查看,通过右击此电脑点击管理可以找到系统日志,很多都能在系统日志看到信息。但是这次没有发现有用的信息

因为这个设备是自主研发的,同时装上了很多自主研发的软件,特别是我写的逗比软件,这个问题可能是自己写出来的问题

软件未响应可能的原因

按照调试方法,首先需要想存在哪些原因,然后测试原因

软件无响应的方法,假设是存在某个逗比软件,如何让另一个程序未响应?我和伟霖说简单的方法是不断发送 windows 消息给另一个程序,因为微软判断程序是否响应是依靠消息的处理

此时小伙伴使用 Spyxx 工具附加到桌面,查看收到的消息

实际上是没有特别的消息,所以这个思路不对

调试资源管理器

现在也没有想到好的思路,那么直接调试资源管理器

调试资源管理器的方法主要用到 WinDbg 工具,打开 WinDbg 工具,通过 File 附加进程,附加到资源管理器,此时进入断点

对我来说,我需要关注一个第三方的应用未响应的只有堆栈和线程

因为老司机告诉我,如果一个程序未响应,在资源管理器看到 CPU 不动,那么原因就是程序在等待。等待的原因可能是有两个线程相互等待,也有可能是等待另一个进程。这部分请看 dotnet 代码调试方法

通过 WinDbg 打开线程界面和堆栈界面,可以看到线程在等待

这里是如何判断主线程是哪个线程?通过堆栈存在 DispatchMessage 找到主线程

可以看到主线程在等待,但不是在等待消息。那么是不是在等待其他线程?看到其他线程也有在等待锁,但是不确定哪个线程等待的锁和主线程相同。 于是不断在 windbg 按下 g 继续执行,然后暂停,可以找到一些线程的变化。通过这个方法发现了资源管理器不是在等待自己进程内的线程,这和我上面说的一样,有这么多用户的系统的稳当性是很重要

另一个小伙伴通过资源管理器拿到转储文件,通过转储文件可以使用 WinDbg 调试到对应的内存对应的变量和调用方法的局部变量

他找到的是在这个方法里面调用了 SendMessage 方法卡住,发送的消息是 WM_Notify 消息,那么在进程里面发送消息有什么用。可能是做进程的通信也可能做线程的通信。等等上面是不是乱说,为什么线程的通信会用到消息。假设这个软件都是一个开发,那么线程之间可以访问到内存,此时使用内存通信就可以。但是资源管理器会使用很多 COM 这部分不是一个开发,通过传内存也不是很好,就通过传 Windows 消息的方式通信

在自定义控件发生了特殊的事件需要通知父窗口时,可以通过发送 WM_Notify 消息,这部分请看 WinFroms 编程相关

我在网上搜 spy notify idctrl NMHDR 找到最相近的博客是 Problem with WM_NOTIFY from a ClistViewCtrl 这是一篇在 18 years ago 写的博客,如果你是搜这几个关键词进入本文,那么我告诉你这条路是走不通的,现在有三个小伙伴在这里用了 1 个小时了。如果你继续往这条路走,如果失败了,请告诉我你使用的时间

安全模式

在不知道如何调试时,可以使用二分法,因为这是自主研发的设备,那么问题要么在微软的系统,要么在自主开发的软件,要么在自主研发的硬件。首先我认为微软的系统没有问题,那么剩下的就是自主研发的软件或硬件。难道此时需要一个个软件卸载,这样的效率太低,同时软件卸载可能会修改系统,简单的方法是进入系统的安全模式,进入安全模式就不会执行自主研发的软件,除了 HAL 层以下的驱动都不会执行

进入安全模式发现依然存在资源管理器未响应,那么现在能知道的是自主研发的软件是没有问题的。或者在运行的自主研发软件是没有问题的。但是可能自主研发的软件在安装过程修改了系统,也可能更底层的驱动存在问题,也可能是硬件存在问题

继续进行二分法,干掉不清真的硬件。通过设备管理器禁用了很多设备之后,发现依然存在问题,所以接下来就需要了解还有哪些会影响到资源管理器

监控进程

调试一个未响应的资源管理器是没有什么用的,但是刚才说的测试步骤还有一步是点击任务栏恢复。那么是如何恢复的,我怂恿伟霖大佬用 WinDbg 附加调试到点击任务栏看这个进程在做什么,不过他拒绝了我这个逗比方法,因为在使用 WinDbg 调试这么长的步骤,是需要用很长的时间

刚才的测试步骤还有一步是点击任务栏恢复之后,等待一段时间,资源管理器又不能使用

那么资源管理器从可以使用到不可以使用之间发生了什么,资源管理器是在做了什么事情,然后就未响应

用微软极品工具箱Process Monitor 可以知道某个进程访问的文件,读写的注册表,访问的网络

这里只需要知道资源管理器访问的文件和读取的注册表等,所以在 Process Monitor 开启过滤,设置 ProcessName 为 Explorer.exe 注意需要加上 .exe 这样就输出资源管理器的

使用 DebugView 可以收到内核的消息和 Win32 的消息,因为资源管理器未响应可能和内核有关系

实际上我不喜欢用到这个工具,因为用这个工具调试的效率将会很低,这个工具会输出大量的信息,需要一个个看

我发现在点击任务栏恢复实际是结束当前进程,打开一个新的资源管理器,那么在这个进程结束之前是做了什么,通过 Process Monitor 可以找到是在读一个 dll 文件

在 Process Monitor 看到读 dll 文件不一定是做文件读写,可能是在做加载。也就是程序需要调用 dll 之前,需要将 dll 读入,此时就存在读 dll 文件

需要关注的是PID的值,在 9876 进程退出之前做的就是读取某个 dll 而进程退出将会释放内核句柄,也就是后面看到的 CloseFile 信息

那么这个 dll 是什么,通过路径可以知道这是蓝牙驱动相关的

为什么资源管理器会执行蓝牙相关的逻辑,原因是资源管理器会加载很多 COM 组件

可能是有逗比程序的右键菜单或插件,在安全模式下,资源管理器也会读取注册表加载插件,也就是插件依然可以执行

使用微软极品工具箱的 AutoRun 可以禁用所有插件

禁用之后发现依然存在问题

通过 ShellExView 可以禁用组件,在组件找到了蓝牙相关的,全部禁用

注意需要使用管理员权限运行 ShellExView 工具

禁用之后发现开关机没有问题

那么这个 蓝牙FTP 是什么,在伟霖大佬的帮助,在注册表找到了图标

这个图标是什么意思,在 DefaultIcon 可以找到相关的信息,只是从资源dll加载图标的方法

用 resource hacker 工具查看这个 dll 可以找到对应的图标

这个图标和桌面的相同

但是,小伙伴是不是记得在资源管理器退出之前读取的文件的路径,是相同路径的 mfc90u.dll 文件

那么这个文件和 mfc90u.dll 有什么联系,我将这个文件夹复制到我的电脑,通过 VisualStudio 的开发者命令行进入我的电脑复制到的文件夹,使用 dumpbin 工具找引用

dumpbin /imports FtpShellExt.dll

此时在输出可以发现有引用 mfc90u.dll 文件,也就是最后资源管理器的退出是在执行 FtpShellExt.dll 的逻辑,而在 FtpShellExt.dll 里面需要调用 mfc90u.dll 的方法,于是资源管理器就读取了文件

    mfc90u.dll
             18002BA90 Import Address Table
             1800401D0 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                             Ordinal   760
                             Ordinal   568
                             Ordinal  1071
                             Ordinal  1232

调试到这里可以发现这是蓝牙驱动相关的问题,这部分在我能力之外,我需要找驱动的小伙伴调试

这次的调试算完成,资源管理器未响应的原因是蓝牙驱动问题,是在资源管理器加载组件执行逻辑。但更多细节包括资源管理器是如何执行 FtpShellExt.dll 的逻辑,执行的是什么逻辑就没有调试,需要请驱动的小伙伴

解决方法

  1. 删除桌面 蓝牙FTP 快捷方式图标
  2. 删除资源管理器蓝牙FTP组件,通过 Shell View 工具删除

经验

首先不要相信测试,要自己去测试,可以请测试帮忙找到短路径。先进行猜测,然后测试猜测。如果没有思路就在网上搜关键词。如果找不到有用信息,尝试进行二分法。使用二分法注意控制变量,也需要了解业务。如果做 Windows 开发,需要的知识会虐前端几倍,从系统到驱动,从整个程序是如何运行的到系统机制

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • visual Studio 无法调试,提示程序跟踪已退出

    今天在打码出现了vs无法调试,我在网上查了很久没有发现一个方法。 vs点击启动时,出现了一下提示

    林德熙
  • 在 Windows 下那些好用的调试软件

    在开发 Windows 程序经常需要调试软件,本文介绍 Windows Sysinternals 的好用的工具。

    林德熙
  • win10 uwp 渲染原理 DirectComposition 渲染 例子创建工程如何写显示CompositionSurfaceBrush

    本文来告诉大家一个新的技术DirectComposition,在 win7 之后(实际上是 vista),微软正在考虑一个新的渲染机制。

    林德熙
  • visual Studio 无法调试,提示程序跟踪已退出

    今天在打码出现了vs无法调试,我在网上查了很久没有发现一个方法。 vs点击启动时,出现了一下提示

    林德熙
  • android AlarmManager讲解

    Android系统闹钟定时功能框架,总体来说就是用数据库存储定时数据,有一个状态管理器来统一管理这些定时状态的触发和更新。在Andriod系统中实现定时功能,...

    xiangzhihong
  • js实现限定范围拖拽

    星辉
  • 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](六)

    又是星期五,很兴奋,很高兴,很high…啦啦啦。。。 Rector在图享网又和大家见面啦!!!上一篇《一步一步创建ASP.NET MVC5程序[Reposito...

    Rector
  • rabbitmq消息队列——"发布订阅"

    三、”发布订阅” 上一节的练习中我们创建了一个工作队列。队列中的每条消息都会被发送至一个工作进程。这节,我们将做些完全不同的事情——我们将发送单个消息发送至多个...

    用户1141560
  • 【项目】2017年最佳的30个机器学习项目

    本文比较了在过去的一年里8800个开源机器学习项目,并从中选取了前30个制成这份清单。它涵盖了2017年1月和12月之间发布的最佳开源机器学习库,数据集和应用程...

    AiTechYun
  • 技术分享:MSSQL注入xp_cmdshell

    存储过程为数据库提供了强大的功能,其类似UDF,在MSSQL中xp_cmdshell可谓臭名昭著了。MSSQL强大的存储过程也为黑客提供了遍历,在相应的权限下,...

    FB客服

扫码关注云+社区

领取腾讯云代金券