更多精彩内容 |
---|
个人内容分类汇总 |
C++软件调试、异常定位 |
离线版下载
ProcDump是一个由Microsoft Sysinternals开发的命令行小工具,用于在Windows系统上监视和生成进程转储文件。
它可以监视进程在CPU使用率、内存占用、I/O操作等方面的性能,并在进程崩溃时自动生成转储文件,以便进行后续调试和分析。
ProcDump的主要功能包括:
- 支持监视进程的CPU使用率、内存占用、I/O操作等性能指标;
- 支持生成进程转储文件以进行后续调试和分析;
- 支持设置条件触发进程转储,如CPU使用率超过某个阈值;
- 支持生成完整的进程转储文件或者只生成异常堆栈信息;
- 支持远程监视和生成进程转储文件。(windows服务器)
ProcDump是一款功能强大的小工具,对于Windows系统下的进程监视和调试非常有帮助。
在Github上也有一个ProcDump工具,可用于Linux系统(linux上功能没有Windows的强)。。
- 之前用过的方法DbgHelp、qBreakpad生成Dump、Linux下配置ulimit -c unlimited生成core的方式功能都比较单一,并且需要配置环境,在程序中调用库,使用较为复杂。
- 而ProcDump 使用非常简单,不需要配置环境,不需要修改代码,将程序下载到本地后,通过命令行设置监听条件、需要监听的程序,然后就可以在条件满足或者目标程序崩溃时快速生成进程转储文件。
- 在Windows中还可以为MinGW编译的程序生成dump文件,这是之前的几种方法不支持的。
- 并且procdump和之前的几种捕获dump/core的方式并不冲突,可以一起使用。
下载地址及官方资料
测试环境:
如图所示,点击直接下载,非常小的工具,还不到1M;
解压后如下图所示;
因为会经常用到,所以最好把Procdump文件夹添加进环境变量中;
搜索环境变量,打开【编辑系统编辑变量】程序;
点击【环境变量】按键;
双击【Path】->【新建】->加入Procdump所在路径,然后全部点确定;
打开一个cmd窗口,输入procdump,如果打印出help信息则安装成功;
注意:这里有一个有意思的现象,解压文件夹下原来有3个文件,但是当运行procdump后就会发现procdump64不见了;
下载地址及官方资料
这里的安装方法适用于Ubuntu,其它Linux系统可以看Github上的安装教程;
适用于Ubuntu 16.04, 18.04, 20.04 & 22.04 & 22.10
测试环境:
安装方式1:
注册微软密钥和源:
wget -q https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
安装程序转储
sudo apt-get update
sudo apt-get install procdump
安装方式2:
安装方式3:
使用下列命令下载源码;
git clone https://github.com/Sysinternals/ProcDump-for-Linux.git
然后按照源码中README.md文件中的方法编译源码。
在终端窗口中输入procdump
,回车后如果显示帮助信息则按照成功;
ProcDump从使用方式上可以分为两种:
- 第一种是每次使用命令行指定要监控、捕获的目标程序,只对这一个程序生效;
- 第二种是将ProcDump安装到AeDebug中,只需要执行一次安装命令,后续不用重复设置,可对所有程序生效,只要有程序异常退出就可以在指定目录下生成Dump文件。
捕获目标程序语法:
procdump.exe [-mm] [-ma] [-mt] [-mp] [-mc <Mask>] [-md <Callback_DLL>] [-mk]
[-n <Count>]
[-s <Seconds>]
[-c|-cl <CPU_Usage> [-u]]
[-m|-ml <Commit_Usage>]
[-p|-pl <Counter> <Threshold>]
[-h]
[-e [1] [-g] [-b] [-ld] [-ud] [-ct] [-et]]
[-l]
[-t]
[-f <Include_Filter>, ...]
[-fx <Exclude_Filter>, ...]
[-dc <Comment>]
[-o]
[-r [1..5] [-a]]
[-at <Timeout>]
[-wer]
[-64]
{
{{[-w] <Process_Name> | <Service_Name> | <PID>} [<Dump_File> | <Dump_Folder>]}
|
{-x <Dump_Folder> <Image_File> [Argument, ...]}
}
安装使用方式语法:
procdump.exe -i [Dump_Folder]
[-mm] [-ma] [-mt] [-mp] [-mc <Mask>] [-md <Callback_DLL>] [-mk]
[-r]
[-at <Timeout>]
[-k]
[-wer]
卸载语法:
procdump.exe -u
Dump类型 | 说明 |
---|---|
-mm | 写入“Mini”转储文件。 (默认值) - 包括直接或间接引用的内存 (堆栈及其) 引用的内容。 - 包括 (进程、线程、模块、句柄、地址空间等) 的所有元数据。 - 由于 MiniDump 文件比较小,因此生成速度比较快,但是不够详细, 可能无法满足高级调试和分析需求。 |
-ma | 写入“Full”转储文件。 - 包括所有内存 (映像、映射和专用) 。 - 包括 (进程、线程、模块、句柄、地址空间等) 的所有元数据。 - 是一种最详细的转储类型,包含了进程的所有信息,包括代码、数据、堆、栈等等。 FullDump 文件非常大,生成速度比较慢,但是可以提供最全面的信息, 适合用于高级调试和分析。 |
-mt | 写入“Triage”转储文件。 - 包括直接引用的内存 (堆栈) 。 - 包括有限的元数据 (进程、线程、模块和句柄) 。 - 尝试删除敏感信息,但不能保证。 - 是一种特殊的转储类型,用于生成进程的三态(triage)转储文件。 三态转储文件包含了进程的核心信息和一些关键的线程和内存信息, 可以用于快速分析进程崩溃和异常问题。由于三态转储文件比 MiniDump 文件稍大, 因此生成速度比 MiniDump 慢,但是比 FullDump 快,适合用于快速诊断问题。 |
-mp | 写入“MiniPlus”转储文件。 - 包括所有专用内存和所有读/写映像或映射内存。 - 包括 (进程、线程、模块、句柄、地址空间等) 的所有元数据。 - 为了最小化大小,将排除超过 512MB 的最大专用内存区域。 内存区域定义为相同大小的内存分配的总和。 转储与完整转储一样详细,但大小为 10%-75%。 - 注意:由于调试限制,CLR 进程将转储为 Full (-ma) 。 - 是一种介于 MiniDump 和 FullDump 之间的转储类型,包含 MiniDump 中的基本信息 以及更多的线程和内存信息。MiniPlusDump 文件比 MiniDump 文件稍大, 但是生成速度比 FullDump 快,适合一些中等大小的进程。 |
-mc | 写入“Custom”转储文件。 - 包括由指定的 MINIDUMP_TYPE 掩码 (十六进制) 定义的内存和元数据。 |
-md | 写入“Callback”转储文件。 - 包括由指定DLL的名为MiniDumpCallbackRoutine的MiniDumpWriteDump 回调例程定义的内存。 - 包括 (进程、线程、模块、句柄、地址空间等) 的所有元数据。 |
-mk | 此外,还要编写“Kernel”转储文件。 - 包括进程中线程的内核堆栈。 - 当使用克隆(-r)时,操作系统不支持内核转储(-mk)。 - 当使用多个转储大小时,每个转储大小都会有一个内核转储。 |
procdump 的 Conditions 参数可以用来设置进程崩溃时触发 Dump 文件生成的条件。
通过设置 Conditions 参数,我们可以根据进程的状态、性能指标等信息来触发 Dump 文件的生成,进而更好地定位程序崩溃的原因。
Conditions 参数可以设置的条件包括:
- CPU 占用率:当进程的 CPU 占用率超过指定的阈值时,生成 Dump 文件。
- 内存占用率:当进程的内存占用率超过指定的阈值时,生成 Dump 文件。
- I/O 操作:当进程的 I/O 操作数超过指定的阈值时,生成 Dump 文件。
- 异常:当进程发生指定类型的异常时,生成 Dump 文件。
通过设置 Conditions 参数,我们可以针对具体的场景精确触发 Dump 文件的生成,从而更好地定位程序崩溃的原因。
例如,当进程的 CPU 占用率突然飙升时,可以使用 Conditions 参数来自动触发 Dump 文件的生成,以便分析占用 CPU 的代码片段。
条件 | 说明 |
---|---|
-a | 避免中断。 需要 -r 。 如果触发器会导致目标由于超出并发转储限制而长时间挂起,则将跳过该触发器。 |
-at | 避免在超时时中断。在N秒时取消触发器的收集。 |
-b | 将调试断点视为异常(否则忽略它们)。 |
-c | CPU阈值,超过该阈值可创建进程的转储。 |
-cl | CPU阈值,低于该阈值可创建进程的转储。 |
-dc | 将指定的字符串添加到生成的转储注释中。 |
-e | 当进程遇到未处理的异常时,写入一个转储文件。 如果要在发生第一次机会异常时创建转储文件,请添加 1 。添加 -ld 以在加载 DLL(模块)时创建转储文件(过滤器适用)。添加 -ud 以在卸载 DLL(模块)时创建转储文件(过滤器适用)。添加 -ct 以在创建线程时创建转储文件。添加 -et 以在线程退出时创建转储文件。 |
-f | 在异常内容、调试日志和 DLL 加载/卸载的文件名上进行过滤(include)。支持通配符(*)。 |
-fx | 在异常内容、调试日志和 DLL 加载/卸载的文件名上进行过滤(exclude)。支持通配符(*)。 |
-g | 在托管进程中作为本地调试器运行(无互操作)。 |
-h | 如果进程有一个挂起的窗口(至少 5 秒钟未响应窗口消息),则写入转储文件。 |
-k | 在克隆(-r )之后或转储收集结束时终止进程。 |
-l | 显示进程的调试日志记录。 |
-m | 用于创建转储的内存提交阈值(MB)。 |
-ml | 当内存提交低于指定的MB值时触发。 |
-n | 退出前要写入的转储数。 |
-o | 覆盖现有转储文件。 |
-p | 当性能计数器达到或超过指定的阈值时触发。某些计数器和/或实例名称可能区分大小写。 |
-pl | 当性能计数器低于指定阈值时触发。 |
-r | 使用克隆进行转储。并发限制是可选的(默认为 1,最大为 5)。 使用克隆( -r )时,操作系统不支持内核转储(-mk )。警告:高并发值可能会影响系统性能。Windows 7:使用 Reflection。操作系统不支持 -e 。Windows 8.0:使用 Reflection。操作系统不支持 -e 。Windows 8.1+:使用 PSS。支持所有触发器类型。 |
-s | 写入转储之前的连续秒数(默认值为10)。 |
-t | 进程终止时写入转储。 |
-u | 相对于单个核心处理 CPU使用率(与-c 一起使用)。 |
-v | 仅调试: 详细输出。 |
-w | 如果指定的进程没有运行,请等待它启动(未运行程序之前使用procdump)。 |
-wer | 将(largest)转储加入到 Windows 错误报告队列中。 |
-x | 使用可选参数启动指定的映像。如果它是一个 Store 应用或包, 则 ProcDump 只会在下一次激活时启动(仅限)。 |
-y | HIDDEN:商店应用程序激活。 |
-64 | 默认情况下,当在64位Windows上运行时,ProcDump将捕获32位进程的32位转储。 此选项将覆盖以创建64位转储。仅用于WOW64子系统调试。 |
Procdump是一款由Sysinternals开发的免费工具,其使用许可协议如下:
- 授权范围:免费授权给任何个人或组织使用。
- 限制条件:
- 未经授权不得以任何形式修改或重编译Procdump。
- Procdump只能用于个人或组织内部使用,不得用于商业目的或向第三方提供。
- Procdump不得用于违反任何法律法规的活动。
- Sysinternals不承担因使用Procdump而产生的任何责任。
- 所有权:Procdump版权归Sysinternals所有。
- 终止:Sysinternals保留随时终止授权的权利。
- 其他条款:本许可协议不得被解释为Sysinternals与用户之间的任何形式的合同、伙伴关系或代理关系。本协议受美国法律管辖。任何争议均应提交美国华盛顿州法院解决。
-accepteula
参数是用于在启动Procdump时自动接受最终用户许可协议(EULA)的选项。-accepteula
参数可以在不需要手动接受EULA的情况下启动Procdump,从而方便自动化部署和集成。语法:
-cancel <Target Process PID>
当使用procdump监视一个程序时,像停止监视,有两种解决办法;
在使用procdump时不指定生成dump文件名时默认生成的dump文件名为: PROCESSNAME_YYMMDD_HHMMSS.dmp
;
支持以下替换:
替换 | 说明 |
---|---|
PROCESSNAME | 可执行程序名 |
PID | 进程 ID |
EXCEPTIONCODE | 异常代码 |
YYMMDD | 年/月/日 |
HHMMSS | 小时/分钟/秒 |
在命令行中使用对应的字符串替换就可以,例如:
使用procdump时只输入部分字符,会根据输入的字符去匹配一个正在运行的,程序名称中包含该字符的程序,并立即生成一个dump文件。(只匹配一个程序)
procdump un
procdump qt
使用PID值来捕获进程的完整转储,如下图所示,捕获PID值为15752的QQ程序的dump,使用了-ma
参数生成的dump文件比没有使用的大几十倍。
procdump 15752
procdump -ma 15752
同时使用-mm
和-ma
参数可以同时生成一个Mini Dump和一个Full Dump。
procdump -mm -ma 15752
使用下列命令匹配一个正在运行的程序名中包含qt字符串的程序,并以5秒间隔创建3个Dump文件。
procdump -n 3 -s 2 qt
使用下列命令可以监测名为ScreenToGif的进程,如果进程的CPU占用率超过10%,并程序5秒则生成Dump,生成3个Dump后退出监测。
procdump -n 3 -s 5 -c 10 ScreenToGif
使用下列命令可以监测名为untitled5.exe的进程,如果该进程超过5秒未响应,则生成一个Dump。
procdump -h untitled5.exe
使用下列命令可以监测名为untitled5.exe的进程,如果该进程超过5秒未响应,则生成一个Mini Dump,一个Full Dump。
procdump -h -mm -ma untitled5.exe
使用下列命令可以监测系统CPU总使用率,如果超过40%,并且持续10(经过测试-s
没生效,只要CPU超过40%则立即生成Dump),则生成进程untitled5的Dump文件;
procdump untitled5 -s 10 -p "\Processor(_Total)\% Processor Time" 40
使用下列命令当 监测进程untitled5 的句柄计数,如果句柄计数超过 1000 时,生成名为“untitled5 ”的进程的Full Dump:
procdump -ma untitled5 -p "\Process(untitled5)\Handle Count" 1000
下列这条命令的意思是:当同时启动了多个(我这里是两个)名为untitled5的进程时,监听第0个(#后面是第几个,从0开始)进程的句柄数,如果句柄数超过1000,则生成PID为15684的进程的Full Dump。
procdump -ma 15684 -p "\Process(untitled5#0)\Handle Count" 1000
注意:多个实例计数器
如果计数器有多个实例,则需要包含名称和/或实例编号,语法如下:
\Processor(NNN)\% Processor Time // 使用实例(运行的程序)编号,从0开始
\Thermal Zone Information(<name>)\Temperature // 使用实例 名称
\Process(<name>[#NNN])\ // 使用实例 名称#编号
旧 OS 要求追加计数器的 PID \Process
。(未验证)
\Process(<name>[_PID])\<counter>
提示: 使用 性能监视器 查看计数器 (区分大小写) 。(未验证)
提示: 对于 \Process(*)
基于的计数器,请使用 PowerShell 将 PID 映射到其 #NNN
。
Get-Counter -Counter "\Process(*)\ID Process"
使用下列命令可以在第二次机会异常(例如C#控制台程序)时生成Full Dump,如果程序不存在第二次异常则在第一次异常时生成(例如C++程序);
procdump -ma -e ConsoleApp1
使用下列命令可以为第一次或第二次机会异常生成Full Dump:
procdump -ma -e 1 ConsoleApp1
为调试字符串消息编写完整转储:(没成功)
procdump -ma -l w3wp.exe
在C#窗口程序中如果发生异常,捕获异常后会弹出一个窗口,点击【继续】后程序不会退出,这时使用下列命令可以在每次发生异常时生成一个Full Dump,当生成3个后procdump退出监测。
procdump -ma -n 3 -e 1 WindowsForms
如下图所示,C#程序发生异常时会显示异常信息,可以使用过滤器-f
过滤掉不需要的异常,只有当过滤器指定的异常出现时才生成Dump;(也可以是其它过滤条件)
procdump -ma -n 3 -e 1 -f DivideByZeroException WindowsForms // 除0异常
如果调试字符串消息包含“NotFound”,则最多可写入10个完整转储:(没成功)
procdump -ma -n 10 -l -f NotFound w3wp.exe
有时候我们想在程序还没有运行的使用启动procdump监测,例如:有时候异常会发生在程序启动时,如果在程序启动后再运行Procdump就根本来不及,所以可以使用-w
参数让procdump运行起来等待目标程序的启动。
procdump -e -w untitled5
使用下列命令可以在procdump开始运行时使用参数-x
启动位于./
路径下的程序untitled5.exe
,并在程序异常时生成Dump;
./
和程序名称untitled5.exe
直接要有空格。procdump -e -x ./ untitled5.exe
注册以启动并尝试激活存储“应用程序”。新的ProcDump实例将在激活时启动:(没尝试)
procdump -e -x c:\dumps Microsoft.BingMaps_8wekyb3d8bbwe!AppexMaps
注册以启动应用商店“程序包”。新的ProcDump实例将在(手动)激活时启动:(没尝试)
procdump -e -x c:\dumps Microsoft.BingMaps_1.2.0.136_x64__8wekyb3d8bbwe
在不写入Dump的情况下显示WindowsForm程序的异常代码/名称:
procdump -e 1 -f "" WindowsForm
Windows 7/8.0版本;使用反射减少5个连续触发的中断:(未尝试)
procdump -r -ma -n 5 -s 15 wmplayer.exe
Windows 8.1+;使用 PSS 减少 5 个并发触发器的中断:(未尝试)
procdump -r 5 -ma -n 5 -s 15 wmplayer.exe
是使用下列命令可以安装ProcDump作为(AeDebug)后期调试程序,将生成的Dump文件全部放到E:\dumps文件夹下;
procdump -ma -i E:\dumps
如果安装procdump时不指定路径则生成的Dump可能会存在于下面两个文件夹中;
procdump -ma -i
卸载ProcDump作为(AeDebug)后期调试程序:
procdump -u
procdump -? -e
procdump [-n Count]
[-s Seconds]
[-c|-cl CPU_Usage]
[-m|-ml Commit_Usage]
[-tc Thread_Threshold]
[-fc FileDescriptor_Threshold]
[-sig Signal_Number]
[-e]
[-f Include_Filter,...]
[-pf Polling_Frequency]
[-o]
[-log]
{
{{[-w] Process_Name | [-pgid] PID} [Dump_File | Dump_Folder]}
}
选项 | 说明 |
---|---|
-n | 退出前要写入的转储数。 |
-s | 写入转储之前的连续秒数(默认值为10)。 |
-c | CPU阈值,超过该阈值可创建进程的转储。 |
-cl | CPU阈值,低于该阈值可创建进程的转储。 |
-m | 用于创建转储的内存提交阈值(MB)。 |
-ml | 当内存提交降至指定的MB值以下时触发。 |
-tc | 线程计数阈值,超过该阈值将创建进程的转储。 |
-fc | 文件描述符计数阈值,超过该阈值可创建进程的转储。 |
-sig | 要拦截的信号,以创建进程的转储。(例如程序段错误会发出SIGSEGV信号) |
-e | [.NET]当进程遇到异常时创建转储。 |
-f | [.NET] 对(逗号分隔)异常名称和异常消息进行筛选(包括)。 |
-pf | 轮询频率。 |
-o | 覆盖现有转储文件。 |
-log | 将扩展的ProcDump跟踪写入系统日志。 |
-w | 如果指定的进程没有运行,请等待它启动。 |
-pgid | “进程ID”指的是进程组ID。 |
信号 | 编号 | 说明 |
---|---|---|
SIGABRT | 6 | 由abort函数发出的信号,表示进程异常终止。 |
SIGFPE | 8 | 由浮点运算异常发出的信号,表示进程执行了一个不合法的浮点运算。 |
SIGILL | 4 | 由非法指令发出的信号,表示进程执行了一个非法指令。 |
SIGINT | 2 | 由CTRL+C发出的信号,表示进程接收到了一个中断信号。 |
SIGSEGV | 11 | 由段错误发出的信号,表示进程访问了一个非法的内存地址。 |
SIGTERM | 15 | 由kill命令发出的信号,表示进程被终止。 |
SIGKILL | 9 | 由kill -9命令发出的信号,表示强制杀死进程。 |
如果想通过PID进行监测,可以使用下列命令查询可执行程序的PID值;
ps aux | grep testCore # testCore是程序名称
使用下列命令立即创建Core文件
sudo procdump testCore # 这里演示使用程序名称
或者
sudo procdump 851017
由下图所示,procdump默认生成的Core都很大
使用下列命令将创建2个核心转储,间隔10秒。
sudo procdump -n 2 851017
使用下列命令将创建2个核心转储,间隔5秒。
sudo procdump -n 2 -s 5 851017
使用下面的命令将在进程每次CPU使用率>= 65%时创建一个核心转储,最多3次,每次转储之间至少间隔10秒。
sudo procdump -c 65 -n 3 1234
以下代码将在进程每次CPU使用率>= 65%时创建一个核心转储,最多3次,每次转储之间至少间隔5秒。
sudo procdump -c 65 -n 3 -s 5 1234
当CPU使用率超出范围[10,65]时,以下代码将创建一个核心转储。
sudo procdump -cl 10 -c 65 1234
当CPU使用率为>= 65%或内存使用率为>= 100 MB时,以下命令将创建一个核心转储。
sudo procdump -c 65 -m 100 1234
下面的操作将立即在~/
目录中创建一个核心转储,如果目录不存在则创建失败。
sudo procdump 871634 ~/
下面的命令将在当前目录中创建一个名为testCore.871634的核心转储。
sudo procdump 871634 testCore
下面的代码将在发生SIGSEGV(段错误)时创建一个核心转储。
-sig
每次只能监测1个信号。sudo procdump testCore -sig 11
当目标【.NET】应用程序抛出System.InvalidOperationException时,以下内容将创建核心转储。
sudo procdump -e -f System.InvalidOperationException 1234
include筛选器支持部分匹配和通配符匹配,因此下面也将为System.InvalidOperationException创建一个核心转储。
sudo procdump -e -f InvalidOperation 1234
或者
sudo procdump -e -f "*Invali*Operation*" 1234
下面将等待一个名为testCore的进程,并在找到它时立即创建一个核心转储。
sudo procdump -w testCore
通过本文的学习,我们了解了procdump的基本概念和使用方法,可以方便地在Linux/Windows系统中对进程进行转储和诊断。
procdump是一款非常实用的工具,可以帮助开发人员快速定位和解决问题。
虽然还有一部分命令功能不明确,但基本可以满足日常开发调试的需求了。