内存泄漏之如何通过WinDbg工具来跟踪内存泄漏?

ops/2024/10/15 18:24:19/

使用WinDbg来跟踪内存泄漏是一个强大且复杂的任务,因为它涉及到对Windows内存管理机制的深入理解,以及对WinDbg调试工具的熟练使用。以下是一个基本的步骤指南,用于通过WinDbg来检测和跟踪内存泄漏

两种方式:

windbggflagsexeumdhexe_3">一、通过windbg辅助工具gflags.exe和umdh.exe

需要使用windbgs的安装目录下的gflags.exe和umdh.exe完成从内存检测,下面的命令需要以管理员权限运行cmd命令行窗口程序,并切换到windbg目录。

1、管理员权限启动cmd命令;
2、进入到Debugging Tools for Windows (x86)目录:

cd C:\Program Files (x86)\Debugging Tools for Windows (x86)

在这里插入图片描述

1、设置pdb符号路径

umdh分析出使用堆内存的函数调用堆栈,为方便查看看函数调用堆栈中的具体函数,可以先设置符号的pdb文件路径,设置的变量名称必须为: _NT_SYMBOL_PATH,设置后需要重启电脑。
不设置会报如下错误:

Warning: _NT_SYMBOL_PATH variable is not defined. Will be set to %windir%\symbols.

在这里插入图片描述

1)、通过系统设置:

在这里插入图片描述

2)、通过cmd命令设置:

#设置符号路径
set  _NT_SYMBOL_PATH="c:\Symbols\;SRV*c:\Symbols\*http://msdl.microsoft.com/download/symbols"

3、启动应用程序

确保你的应用程序在调试模式下编译,并且包含了完整的调试信息(PDB文件)。

在这里插入图片描述

gflagsexe_32">4、使用gflags.exe设置要监控内存状态的进程

glags也在Debugging Tools for Windows (x86)目录下,和windbg同步目录,下面以监控test.exe为例:
在这里插入图片描述

umdhexe_35">5、使用umdh.exe获取进程的内存数据和堆栈变化结果。

umdh也在Debugging Tools for Windows (x86)目录下,和windbg同步目录。

1)、启动cmd命令;
2)、进入到Debugging Tools for Windows (x86)目录:cd C:\Program Files (x86)\Debugging Tools for Windows (x86)
3)、查看进程某一时刻的内存状态,并保存下来:umdh.exe -p:21564 -f:D:/aaa.txt,其中-p后面是进程的PID,-f后接的是文件保存路径
在这里插入图片描述
4)、间隔一段时间,重复步骤3),但保存文件名记得修改:
umdh.exe -p:21564 -f:D:/bbb.txt
umdh.exe -p:21564 -f:D:/ccc.txt
在这里插入图片描述
5)、比较两个内存数据的状态,找到两个时刻的变化,并将比较结果保存到reslut.txt中。
umdh.exe D:/aaa.txt D:/bbb.txt -f:D/:reslut.txt
在这里插入图片描述
6)、查看分析结果
比较aaa.txt和bbb.txt两个文件中堆内存的使用变化量,得出统计数据保存到reslut.txt中,即可查看到堆内存的变化情况,按堆内存的数量从高到低排列,而且有详细的函数的调用堆栈,分析使用量较高的几项即可在这里插入图片描述
抓取第一次堆内存快照后,间隔了比较长的时间,抓取了第二次。

23fbeb0 ( 2409090 - d1e0) 240909 allocs BackTrace6A
23fbeb ( 240909 - d1e) BackTrace6A allocations

格式说明:
23fbeb0 : 表示两次内存快照之间,增加的内存,
2409090:第二次使用内存快照时该堆占用内存,
d1e0:第一次使用内存快照时该堆占用的内存
240909:总的分配次数
23fbeb:两次之间,多分配的次数
240909:第二次内存快照到第一次之间分配次数
d1e:第一次的内存快照分配的次数
0x23fbeb0/0x23fbeb = 0x10 刚好16个字节,符合我们前面分析的内存泄露的字节大小,
从调用堆栈上看,内存泄露的地方像是在使用标准的std::string 中发生的,根据调用堆栈提示的代码行数,找到对应的代码部分。
在这里插入图片描述

windbg_67">二、通过windbg附加进程方式

使用 Windbg 来跟踪内存泄漏是一个强大的方法,特别是针对 Windows 应用程序。Windbg 是 Microsoft 提供的强大的调试工具,它不仅可以用来调试崩溃问题,还可以用来分析内存泄漏等性能问题。

1. 准备环境

  • 确保你的应用程序有调试符号(PDB 文件)。这些文件包含了源代码和二进制之间的映射,使得调试器能够显示源代码行号等信息。
  • 安装并配置 Windbg。
  • 设置符号路径,设置方式可以跟前文中提到的设置环境变量方式,也可以如下图,加入pdb所在目录。
    在这里插入图片描述
  • 设置源文件所在路径
    在这里插入图片描述

2. 附加到进程

  • 启动你的应用程序。
  • 打开 Windbg,并使用 File > Attach to a Process 菜单项附加到正在运行的应用程序进程。
    在这里插入图片描述

3. 设置断点(可选)

  • 如果你知道内存泄漏可能发生在代码的特定部分,你可以设置断点来暂停执行。使用 bp <模块名>!<函数名> 命令来设置断点。

4. 使用扩展命令分析内存

Windbg 提供了多个扩展命令来帮助分析内存,其中 .dmp 命令用于创建内存转储,而 !heap!analyze -v!eeheap -gc(对于托管代码)等命令则用于分析内存状态。
在这里插入图片描述

  • 对于非托管代码

    • 使用 !heap -s 查看堆的摘要信息。
    • 使用 !heap -stat 查看堆上对象的统计信息。
    • 使用 !heap -l 列出堆上的所有分配。
    • 使用 !heap -p -a <地址> 查看特定内存地址的详细信息。
  • 对于托管代码(.NET 应用程序):

    • 使用 !dumpheap -stat 查看托管堆上的对象统计信息。
    • 使用 !dumpheap -type <类型名> 查看特定类型的所有实例。
    • 使用 !gcroot <对象地址> 查找导致对象保持活动的根。

5. 监视内存变化

  • 在应用程序运行期间,定期使用上述命令来监视内存的变化。
  • 特别注意那些数量不断增加的对象类型,它们可能是内存泄漏的源头。

6. 深入分析

  • 如果发现可疑的对象或内存区域,使用 Windbg 的其他命令或扩展来进一步分析。
  • 你可以使用 !dso!clrstack 等命令来查看调用栈,了解对象是如何被创建和引用的。

7. 解决问题

  • 根据分析结果,修改代码以修复内存泄漏
  • 重复上述步骤以验证问题是否已解决。

8. 记录和文档

  • 记录你的发现、分析和解决方案,以便将来参考。

使用 Windbg 跟踪内存泄漏需要一定的学习和实践,但一旦你掌握了它,它将是一个非常强大的工具,可以帮助你解决复杂的内存问题。

注意事项

  • 内存泄漏的检测和修复是一个迭代过程,可能需要多次尝试才能找到问题的根源。
  • 深入理解你的应用程序和所使用的库的内部工作机制对于有效地使用WinDbg进行内存泄漏分析至关重要。

通过遵循上述步骤,你可以使用WinDbg来有效地跟踪和修复内存泄漏问题。不过,这需要对WinDbg及其扩展工具的深入了解和大量的实践。


http://www.ppmy.cn/ops/94988.html

相关文章

<Qt> 系统 - 网络编程 | 音视频

目录 前言&#xff1a; 一、QUdpSocket &#xff08;一&#xff09;核心 API 概览 &#xff08;二&#xff09;设计一个UDP回显服务器 二、QTCPSocket &#xff08;一&#xff09;核心 API 概览 &#xff08;二&#xff09;设计一个TCP回显服务器 三、HTTP Client 四、…

智能视界:一文掌握Transformer视频分类核心技术

视频分类&#xff1a;技术与实践 概述 视频分类是计算机视觉领域的一项基本任务&#xff0c;目标是从连续的图像序列中识别出视频的主题或内容类别。与图像分类不同&#xff0c;视频分类不仅要理解单帧画面&#xff0c;还需捕捉时间序列中的动态信息&#xff0c;这对于自动标…

关于SOA和微服务

面向服务的架构&#xff08;SOA&#xff09; 想象一下&#xff0c;你正在经营一家大型超市&#xff0c;超市里有各种各样的商品和服务。SOA 就像是超市的各个部门&#xff0c;比如生鲜区、家电区、收银台等等&#xff0c;每个部门提供特定的服务。这些服务&#xff08;部门&am…

在亚马逊云科技上利用生成式AI开发用户广告营销平台

项目简介&#xff1a; 小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践&#xff0c;并应用到自己的日常工作里。 本次介绍的是如何利用亚马逊云科技大模型托…

Spring Boot集成sentinel快速入门Demo

1.什么是sentinel&#xff1f; 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、…

WebRTC音视频开发读书笔记(三)

当采集音频或视频时&#xff0c;设备会源源不断地产生媒体数据&#xff0c;这些数据就是媒体流&#xff0c;从Canvas&#xff0c;桌面&#xff0c;摄像头捕获的流为视频流&#xff0c;从麦克风捕获的的流称为音频流&#xff0c;媒体流中混入的可能是多种数据 &#xff0c;因此W…

IOS 06 OC调用Swift第三方框架

前面文章05讲的是在OC项目中&#xff0c;调用Swift代码&#xff0c;而在真实开发过程中&#xff0c;在OC项目中调用Swift第三方框架场景用的是非常多的&#xff0c;所以我们也了解在OC项目如何使用Swift写的三方框架。 实现流程&#xff1a; 1、OCUseSwiftTest&#xff1b;在…

力扣 3152. 特殊数字Ⅱ

题目描述 queries二维数组是nums数组待判断的索引区间&#xff08;左闭右闭&#xff09;。需要判断每个索引区间中的nums相邻元素奇偶性是否不同&#xff0c;如果都不同则该索引区间的搜索结果为True&#xff0c;否则为False。 暴力推演&#xff1a;也是我最开始的思路 遍历q…