文章目录

  • 前言
  • crash
  • anr
  • memory leak
  • dead lock
  • high cpu usage
  • Profile
  • 手工复原堆栈
    • GFlags

前言

我们使用调试工具的时候,一般是要处理以下问题:

  1. crash
  2. anr application no response
  3. memory leak
  4. dead lock
  5. high cpu usage

Windows平台上有很多对应的处理方案,不过现有的方案一般都有一个通病:一旦打开某些调试功能或者系统设置,调试目标的性能就会成倍下降。这一点有时候会对调试来带很大的干扰,比如出现目标程序UI线程卡顿,导致无法正常操作,或者没发现要调查的问题,反而是发现了一堆性能方面的问题。

crash

崩溃的情况可以从几个正交的维度来划分:是否必现,开发的机器上是否可以复现,是否抓到crash dump。

一旦接手一个crash问题排查,可以按照下面的步骤来排查:

  1. 发现问题的机器上是否可以复现。可以复现的情况又分为:

    • 必现 : 这个情况是最简单了。
    • 高概率复现 :这个也比较简单。
    • 低概率复现,甚至只出现一次 :这个最棘手,作为开发最怕遇到这类问题。但是理论上讲,只要能发现一次就一定有一个必现的路径,只不过实践中碰到的概率低而已。套用一句话来描述就是:crash只有0次和无数次。
  2. 能复现的话,是否有复现路径。
    • 有的话,开发的机器上是否可以复现:那么直接用调试器来看就好了,这个最简单了,调试器就可以直接抓到crash点。
    • 开发的机器上不能复现的话,qa的机器上是否可以复现:可以通过远程调试的方法来处理。
    • 如果开发和测试的机器都不能复现的话,可能就需要联系客户了。这个要做好准备,这时候可以使用的方法就是:日志+dump。
      • 使用dump还要看是否能(尽量)跑debug版本,因为有时候release版本缺少一些符号信息,可能会出现即使复现了,但由于缺少符号,缺少active信息而导致无法进一步查问题。
      • 提一下,日志对于crash问题来说往往帮助不大,不过聊胜于无。
  3. 走到这一步,那就是说这个问题很可能不好复现,而且拿不到dump信息,那么这时候问题的解决就很可能没希望了。留下最后一个办法就是:耐心。排查代码,不论使用什么方法,在怀疑的点上加日志,做好准备抓dump,部署到目标环境,然后静候crash发生。

对于上面的场景,其实概括起来处理方法就三种:

  1. 本地调试:一般是使用MSVC
  2. 远程调试:MSVC或者WinDbg都可以
  3. 抓dump分析:MSVC或者WinDbg都可以,生成dump的方式,可以在资源管理器里面找到目标进程,右键执行创建转储文件;或者使用MSVC/WinDbg的创建dump功能。

anr

首先,对于anr的问题要注意的一个问题是,一定要确定anr确实发生了,因为有时候可能是程序运行环境配置较差导致的,静置一会儿看看是否就没问题了。当然如果干脆就不允许出现anr,那么应该有两方面的考虑:给出最低环境配置和找出造成anr的问题代码(比较有追求的做法)。

确定是anr问题了,那么接下来就要采取一些措施,比如动态抓dump看UI线程卡在哪里了。或者直接制造一个crash,也是得到dump,调查一下UI线程卡在哪里了。当然如果能上(本地或者远程)调试器的话是最好的了,anr的时候直接让程序停下来就可以在call stack中看到UI线程在干嘛。

另外提一下,mac上有一个不错的工具,可以在活动监视器里面采样,从而直观地看到哪行代码有问题。Windows系统上就只能用msvc工具来查了,但毕竟并不是所有(测试/客户的)环境都有调试工具,不是很好查;同时这个问题还可能与high cpu usage或者dead lock有点关联。

memory leak

内存泄露问题,可以:

  • 使用msvc的Heap Profiling工具,通过take snapshot不同时间点的内存快照,进行对比得到内存泄露的点。
  • Windows 10上可以使用UMDH工具来做类似的动作。
  • Dr. Memory,下载地址
  • Top 20+ Memory Leak Detection Tools For Java, C++ On Linux And Windows
  • 通过Application Verifier工具中的内存相关功能查看。通过WinDbg配合Application Verifier来调试是一个不错的组合,WinDBg可以及时地查看出问题时对应句柄等资源的信息。
  • 使用 Debug Diagnostic Tool,根据指定的内存阈值抓取dump,这个工具的另一个名字叫 “DebugDiag”。参考 Memory dumps to study a high-CPU performance issue,使用这个工具需要对系统的各种计数器的含义比较了解。调试诊断工具 (DebugDiag) 旨在帮助解决诸如挂起、性能下降、内存泄漏或内存碎片以及任何用户模式进程中的崩溃等问题。
  • Physical and Virtual Memory in Windows 10 介绍Windows 10上内存知识很全面的一篇文档,里面有很多精美的插图。
  • Deleaker Blog Visual Studio 20xx的一个付费插件。
  • 微软官方工具介绍的一个视频集合:Defrag Tools
  • 原本在channel9上的两个内存管理的视频:Mysteries of Memory Management Revealed Part1,Part2
  • A story of fixing a memory leak in MiniDumper 使用VMMap + WPT分析内存泄露的一个不错的例子。
  • milostosic/MTuner is a C/C++ memory profiler and memory leak finder

dead lock

发现死锁本身就是一个问题,比如非UI线程死锁,可能就没有UI线程卡死那么直观。可能是某些对该线程的同步调用卡住,或者异步调用没有结果返回才能发现。

发现之后可以抓dump,或者上调试器。

high cpu usage

Windows上由于缺少一个对进程的各个线程采样统计的工具(我没发现),所以这个问题查起来没有那么直接。WinDbg上可以用!runaway来查CPU的使用时间,但是这个使用时间,我们无法指定开始统计和结束统计的时间点,也就是说真正耗时的操作可能会被很早运行的线程运行时长超过,导致我们定位不出来。

Profile

PC Profile工具

手工复原堆栈

参考 Manually Walking a Stack

堆栈失效,可能是由于对无效地址的调用导致调试器丢失了返回地址的位置;或者您可能遇到了无法直接获取堆栈跟踪的堆栈指针;或者可能存在其他一些调试器问题。

思路是:

  • 先从检查符号开始 x *! 命令
  • dd esp/rsp 查看栈指针附近的信息,找出可能是函数指针的值,这里要注意排除掉下面的值:
    • 一般整数比较小,dd的时候大部分位是0,这类值不太可能是函数地址
    • 英文字符的范围一般在 [20,7f] 区间
    • 指向栈上的指针变量大小一般与esp/rsp接近
    • 函数指针一般不太可能重复
    • 状态码通常以 ac (c00000d6) 开头
    • 最后,栈的地址应该位于模块的区间内,也就是在第一步x命令找到的模块的地址区间内
  • 这样得到一组函数指针备选集,然后逐个使用ln address查看对应符号,得到一组可能的函数调用符号
  • 然后通过反汇编指令u 函数指针备选集合中的每一个元素的前一个地址,看看得到的结果是否匹配上面那组符号,从而构建出调用堆栈来。

GFlags

Windows上好多调试功能都需要 gflags 这个工具。

GFlags(全局标志编辑器)gflags.exe 启用和禁用高级调试、诊断和故障排除功能

gflags官方有一个实例说明:GFlags Examples

Windows调试技巧工具相关推荐

  1. QT调试技巧-使用静态代码检测工具Cppcheck检测代码

    #QT调试技巧-使用静态代码检测工具Cppcheck检测代码 如需转载请标明出处:http://blog.csdn.net/itas109 QQ技术交流群:129518033 环境: Qt Creat ...

  2. vs调试技巧和诀窍系列_维护Windows PC的35个最佳技巧和窍门

    vs调试技巧和诀窍系列 When working (or playing) on your computer, you probably don't think much about how you ...

  3. 【Windows 逆向】OD 调试器工具 ( 分析 OD 硬件断点处的关键代码 | 添加硬件断点 | 关键代码 | MOV 指令 | EAX 寄存器值分析 | 使用命令查看 esi+0cc 地址 )

    文章目录 一.添加硬件断点 二.关键代码 三.MOV 汇编指令格式 四.EAX 寄存器值分析 五.使用命令查看 esi+0cc 地址 一.添加硬件断点 在上一篇博客中 , 在子弹个数数据内存地址 07 ...

  4. 【Windows 逆向】OD 调试器工具 ( OD 调试数据时硬件断点对应的关键代码 | 删除硬件端点恢复运行 )

    文章目录 前言 一.OD 调试数据时硬件断点对应的关键代码 二.删除硬件端点恢复运行 前言 在 [Windows 逆向]OD 调试器工具 ( CE 中获取子弹动态地址前置操作 | OD 中调试指定地址 ...

  5. 【Windows 逆向】OD 调试器工具 ( CE 中获取子弹动态地址前置操作 | OD 中调试指定地址的数据 )

    文章目录 一.CE 中获取子弹动态地址前置操作 二.OD 中调试子弹数据 一.CE 中获取子弹动态地址前置操作 在上一篇博客 [Windows 逆向]OD 调试器工具 ( CE 工具通过查找访问的方式 ...

  6. 【Windows 逆向】OD 调试器工具 ( CE 工具通过查找访问的方式找到子弹数据基地址 | 使用 OD 工具附加游戏进程 | 在 OD 工具中查看子弹数据地址 | 推荐 )

    文章目录 前言 一.CE 工具通过查找访问的方式找到子弹数据基地址 二.使用 OD 工具附加游戏进程 三.在 OD 工具中查看 058E2F1C 地址数据 前言 上一篇博客 [Windows 逆向]O ...

  7. 【Windows 逆向】OD 调试器工具 ( OD 附加进程 | OD 调试器面板简介 | 反汇编窗口 | 寄存器窗口 | 数据窗口 | 堆栈窗口 )

    文章目录 一.OD 附加进程 二.OD 调试器面板简介 ( 反汇编窗口 | 寄存器窗口 | 数据窗口 | 堆栈窗口 ) 一.OD 附加进程 先启动游戏 , 打开 OD 调试工具 ; 游戏 参考 [Wi ...

  8. 工具:分享IntelliJ IDEA 5条调试技巧,太实用了!

    一.条件断点 循环中经常用到这个技巧,比如:遍历1个大List的过程中,想让断点停在某个特定值. 参考上图,在断点的位置,右击断点旁边的小红点,会出来一个界面,在Condition这里填入断点条件即可 ...

  9. xcode开发html5工具,5个Xcode开发调试技巧

    1.Enable NSZombie Objects(开启僵尸对象) Enable NSZombie Objects可能是整个Xcode开发环境中最有用的调试技巧.这个技巧非常非常容易追踪到重复释放的问 ...

  10. 无法从命令行或调试器启动服务,必须首先安装Windows服务(使用installutil.exe),然后用ServerExplorer、Windows服务器管理工具或NET START命令启动它

    无法从命令行或调试器启动服务,必须首先安装Windows服务(使用installutil.exe),然后用ServerExplorer.Windows服务器管理工具或NET START命令启动它 1. ...

最新文章

  1. VIL-100: 一个新的车道线检测数据集和基线模型(ICCV2021)
  2. java中capitals,Java GlobalConfiguration.isCapitalMode方法代码示例
  3. jquery技巧(持续更新。。)
  4. python去重复元素_python 去除单个list中的重复元素
  5. pwd 查看”当前工作目录“的完整路径
  6. java 图片去除黑边_根据 Map 上的变量绘制彩色和形状的点时,保持符号的黑色边框(geom_point)...
  7. 如何导出项目到本地_如何在win10中导入/导出组策略设置,这个技巧很实用
  8. spring boot整合cxf发布和调用webservice
  9. V-SQL的简单使用
  10. 游戏音效制作中难or不难?
  11. 为什么计算机能读懂 1 和 0 ?
  12. 图片加水印怎么加?教你一个好操作的办法
  13. TypeError: ToTensor() takes no arguments
  14. Python股票分析系列——数据整理和绘制.p2
  15. 力扣(LeetCode)个人主页draw()方法怎么画出好看图案? // 使用函数 draw 绘制图形,反斜杠 “\“ 请使用 “\\“ 转义
  16. 遇见错误:ValueError: Classification metrics can‘t handle a mix of binary and continuous targets
  17. 北京工商大学计算机考研818真题,北京工商大学考研真题汇总
  18. SQL SERVER根据符号将一列拆分多行
  19. SpringBoot整合activiti5-业务表单
  20. 假如再有三年生命,世界的教育改革家--乔布斯

热门文章

  1. 英语不好学计算机特长,指导:英语学不好,是因为你没养成这些好习惯
  2. .NET西安社区「拥抱开源,又见 .NET:壹周年Party」活动简报
  3. Android 10.0修改签名文件test-keys为release-keys
  4. Numpy 中某个矩阵的平方距离计算方法
  5. 塔防游戏制作教程(二)
  6. C盘扩容好帮手——傲梅分区助手
  7. 怎么用静图做gif动图?三步教你轻松做动图
  8. ansys添加力矩_ansys中施加力矩
  9. html点击登陆、注册等时候出现等待图标代码
  10. 强大的vim配置文件,让编程更随意【http://www.cnblogs.com/ma6174/】