C++(Qt)软件调试---内存调试器Dr.Memory(21)
C++(Qt)软件调试—内存调试器Dr. Memory(21)
更多精彩内容 |
---|
👉内容导航 👈 |
👉C++软件调试、异常定位 👈 |
1、概述🐜
Dr. Memory 是一种开源内存监控工具,能够识别与内存相关的编程错误。例如
- 内存泄漏检测
- 内存越界检测
- 重复释放内存
- 空指针、野指针检测
- 堆栈溢出检测
- 内存分配和释放跟踪
- (在 Windows 上)句柄泄漏检测
- GDI API 使用错误以及访问未保留的线程本地存储槽
同类型工具还有Valgrind、Deleaker 、Asan、VLD、heob等;
- Valgrind不适应于Windows;
- Asan速度快,但在Windows上也不是很好用,VS2019以后版本开始支持,linux下使用;
- Deleaker 是windows下Valgrind的替代,不过是收费的;
- VLD支持Windows,以头文件引入,简单易用;
- Heob适用于Windows,可集成到Qt Creator;
- Dr.Memory开源免费,支持跨平台,不需要参与程序编译。
在性能上Dr. Memory 比包括 Valgrind 在内的同类工具更快。(有时候还是有点慢)
本文会讲解如何使用Dr.Memory以及在Qt Creator和Visual Studio中集成Dr.Memory。
演示环境:
-
系统:
- Windows11
-
编辑器:
- Visual Studio 2017
- Qt Creator10.0.2
- VS Code
-
编译器:
- MSVC2017-32
- MSVC2017-64
- MinGW32
- MinGW64
-
Dr.Memory版本
- DrMemory-Windows-2.6.19989.msi
- DrMemory-Windows-2.3.18696.zip
- DrMemory-Windows-2.4.18900.zip
2、安装Dr.Memory🪲
支持系统:Windows、Linux 和 Mac 系统。
支持编译器:g++、MinGW、MSVC。
目前不支持使用 Cygwin、gcc 或 g++ 构建的应用程序。
使用Dr.Memory需要包含调试符号。
-
这里我使用的是DrMemory 2.3、2.4、2.6三个版本;
- 2.6版本适用于MSVC2017-64、MinGW64,不适用于MSVC2017-32、MinGW32;
- 2.3、2.4版本适用于MSVC2017-32、MSVC2017-64、MinGW64,不适用于MinGW32。
-
下载完成后直接双击进行安装,安装目录为
D:\DrMemory
; -
如果是使用**.msi安装包**进行安装的会自动添加到环境变量;
-
如果是使用**.zip压缩包**,那解压后可选择添加到环境变量,或者使用时用绝对路径访问。
3、命令行使用Dr.Memory🦗
测试代码
/*****************************************************************
* \file ConsoleApplication4.cpp
* \brief 测试Dr.Memory代码,如果编译不通过则打开属性、C/C++、常规、关闭SDL检查
*
* \author MHF
* \date September 2024
*********************************************************************/
#include <iostream>
using namespace std;
// 内存泄漏
void test1()
{
int*p = new int;
cout << p << endl;
}
// 非法访问内存
void test2()
{
char *p = new char[10];
delete[] p;
*p = 123;
}
// 使用未初始化变量
void test3()
{
int a;
int b = a;
}
// 重复释放内存
void test4()
{
char * p = new char;
free(p);
free(p);
}
int main()
{
test1();
test2();
test3();
test4();
cout << "hello" << endl;
return 0;
}
- 编译完成后,进入可执行程序所在路径;
- 鼠标右键选择【在终端中打开】或者打开cmd进入可执行程序所在路径;
- 输入
drmemory.exe -ignore_kernel .\ConsoleApplication4.exe
指令启动Dr.Memory调试; - 注意:drmemory.exe如果在环境变量中无法访问到则需要使用绝对路径;
- 启动时一般会报异常,弹出弹窗,则需要使用
-ignore_kernel
选项,再出现弹窗,点击确认后就可以生成分析报告。-ignore_kernel
选项跳过在不受支持的内核版本上运行的通常致命的使用错误,继续向下执行。
- 检测完成后默认会自动打开分析报告文件。
- 默认生成检测报告文件位置如下图所示,默认生成路径为用户目录下或者DrMemory安装路径下:
C:\Users\MHF\AppData\Roaming\Dr. Memory
D:\DrMemory-2.3\drmemory\logs\
- 使用
-logdir
选项可指定检测报告的生成路径
4、Qt Creator集成使用Dr.Memory🐉
在Qt Creator中有两种方式运行Dr.Memory。
- 以外部工具启动:
- 一次配置适用于所有工程、多个编译器;
- 可添加依赖库环境变量;
- 可配置快捷键启动;
- 需要使用时再运行。
- 以运行配置启动:
- 一次配置只适用于当前配置的工程、当前配置的编译器;
- 可添加依赖库环境变量;
- 不能配置快捷键启动;
- 每次程序编译运行时都会启动。
1.1 以外部工具启动
-
打开【编辑】【Preferences】,打开【首选项】窗口;
-
选择【环境】【外部工具】【添加】,名称命名为
Dr.Memory
; -
主要需要配置【执行档】【参数】【Base environment】3项;
-
执行档: Dr.Memory可执行程序路径;
-
参数: Dr.Memory程序运行的参数,其中可使用QT内置的宏来替换可执行程序路径、输出文件路径等;
-
Base environment: 程序运行所需的环境变量,如果选择【系统环境变量】则当环境变量中找不到Qt动态库时则Dr.Memory会运行失败,所以如果是使用到Qt库的程序,可选择【Curent Build Environment】或者【Curent Run Environment】,这样程序运行时会自动链接到Qt动态库。如果有第三方依赖,则可在【环境】项中添加对应的依赖环境变量。
-
QT内置宏使用: 在【参数】项输入栏右侧点击图标,在打开的窗口中选择内置宏,不同版本的Qt Creator内置宏有一定区别;
-
配置完成后我的参数是
-logdir %{CurrentDocument:Project:RunConfig:Executable:NativePath} -lib_blocklist "*.dll" -ignore_kernel -- %{CurrentDocument:Project:RunConfig:Executable:FilePath}
; -
然后点击【确认】后,就可以在【工具】【外部】【Dr.Memory】启动Dr.Memory检测当前程序;
-
如果觉得每次都打开菜单很麻烦,则可选择配置快捷键;
-
打开【首选项】【环境】【键盘】,过滤器输入
Dr.Memory
; -
选中【Dr.Memory】项后,点击【Record】,然后按下自己习惯的快捷键组合,就可以设置Dr.Memory启动快捷键了,注意快捷键不要存在冲突。
-
按下快捷键后启动Dr.Memory,启动会比较慢,注意Dr.Memory在程序运行结束后才会给出报告,所以当程序运行后,退出程序运行,然后才会打开检测报告。
-
1.2 以运行配置启动
-
点击【项目】,在【构建和运行】中选中编译器【运行】;
-
选中编译器的【运行】后,在【运行】项中点击【添加】【自定义执行档】;
-
【执行档】输入Dr.Memory路径;
-
【Command line arguments】输入Dr.Memory参数;
-
【工作目录】这里设置的是运行目录,用于在
-logdir ./
指定生成检测报告的路径; -
在【环境】项中找到【Path】项,选中后点击【Edit】,添加当前编译器的动态库路径或者使用到的其它依赖库路径,便于运行时通过环境变量链接到动态库,否则找不到动态库则会运行失败。
-
配置完成后,直接编译运行程序,就会自动启动Dr.Memory进行检测分析;
5、Visual Studio集成使用Dr.Memory🐑
在“工具”菜单上添加和管理外部工具 - Visual Studio (Windows) | Microsoft Learn
-
在菜单栏选中【工具】【外部工具】;
-
打开【外部工具】窗口后,点击【添加】,分别输入标题、命令、参数,输入栏右侧的三角形图标按键打开可选择使用VS内置宏;
-
编译完成程序后可点击【工具】【Dr.Memory】选项启动Dr.Memory对当前可执行程序进行分析;
-
如果觉得打开菜单操作复杂,可以选择给外部工具命令添加快捷键;
-
点击【工具】【选项】;
-
打开【选项】窗口后,选择【环境】【键盘】,在【显示目录包含】位置输入工具.外部命令;
-
由于我的Dr.Memory是第四条命令,所以我选择的是工具.外部命令4,选中选项后鼠标点击下方的【按快捷键】输入栏,然后按下设置的快捷键组合,如果快捷键已经被使用了则会在【快捷键的当前使用对象】位置显示,如果没被使用则点击【分配】,然后点击确认就设置完成了。
6、Dr.Memory选项🪰
- 在线文档
- 离线文档:安装路径下
D:\DrMemory\docs
。
7、常见问题及解决办法🐐
-
Dr.Memory检测所有动态库,导致速度慢,生成的报告文件内容非常多,大部分都是无效内容;
- 使用
-lib_blocklist
选项指定动态库不进行检测;
- 使用
-
生成的检测报告文件找不到在哪;
- 默认生成路径在用户目录下或者Dr.Memory安装路径下;
- 可使用
-logdir
选项指令生成路径;
-
在检测完成后没有打开报告文件;
- 可能是使用了
-visual_studio
选项;
- 可能是使用了
-
初次运行Dr.Memory启动很慢;
-
显示内容如下所示:
WARNING: System call information is missing for this operating system version. Attempting to auto-generate system call information... drsys_find_sysnum_libs: C:\Windows\system32\ntdll.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\kernelbase.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\kernel32.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\gdi32.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\imm32.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\user32.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\win32u.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\ntdll.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\kernelbase.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\kernel32.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\gdi32.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\imm32.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\user32.dll is readable drsys_find_sysnum_libs: C:\Windows\system32\win32u.dll is readable Symbol cache directory is "D:\DrMemory-2.3\drmemory\logs\symcache" Fetching symbols for "C:\Windows\system32\ntdll.dll", attempt #0 Successfully fetched or found symbols at "D:\DrMemory-2.3\drmemory\logs\symcache\symbols\ntdll.pdb\3F9B0A9DA2F01CB5571242F6EE73BFD61\ntdll.pdb" Fetching symbols for "C:\Windows\system32\kernelbase.dll", attempt #0
-
默认会检测所有动态库,所以初次启动时会查找所有动态库的pdb符号表,所以会比较慢。
-
-
启动Dr.Memory时出现弹窗,内容如下所示:
~~Dr. M~~ System call information is missing for this operating system: WinVer=105;Rel=2009;Build=22631;Edition=CoreCountrySpecific. Restarting to trigger auto-generation of system call information. Re-run with -ignore_kernel to attempt to continue instead.
- 使用
-ignore_kernel
选项后关闭弹窗; - 或者直接关闭弹窗,等下载完符号表后,后续就不会出现了。
- 使用
-
Dr.Memory启动失败,提示信息如下所示:
~~Dr.M~~ WARNING: unable to locate results file: can't open E:\test\ConsoleApplication4\Debug\/resfile.66196 (code=2). Dr. Memory failed to start the target application, perhaps due to interference from invasive security software. Try disabling other software or running in a virtual machine. WARNING: Examine the following unusual libraries in this process to help identify invasive software that may have affected the target application: C:\Windows\System32\bcrypt.dll Please file a bug about this at http://drmemory.org/issues ~~Dr.M~~ WARNING: application exited with abnormal code 0xffffffff
- 不同版本的Dr.Memory都可能存在一些问题,例如Dr.Memory2.6用于MSVC2017-32编译的程序时就会失败,改为使用Dr.Memory2.3就正常了。
-
Dr.Memory启动失败,提示信息如下:
~~Dr.M~~ WARNING: libraries needed by the application are missing. Check that it runs successfully on its own and check that all needed libraries are in its directory or on the PATH. ~~Dr.M~~ WARNING: application exited with abnormal code 0xc0000135
- 这是由于需要检测的可执行程序启动失败,找不到依赖库,需要将动态库复制到当前路径下或者将动态库路径添加进环境变量。
8、参考🐹
Dr. Memory Runtime 选项参考 (drmemory.org)