我想为特定应用程序生成第一次机会异常的转储,该应用程序每天多次以随机间隔启动,在任何时候都运行多个实例。
我尝试过什么
Procdump
要使用procdump,我必须知道PID或等待进程启动。随着多个实例的启动,这将无法开始监视所有已启动的实例
GFLAGS
使用gflags我可以附加调试器,但我不想手动继续每个进程,我不知道如何自动化该过程。我尝试在gflags中使用procdump作为调试器,但我不知道如何将进程传递给procdump。
答案 0 :(得分:3)
编写了一个简单的PowerShell脚本来枚举同一个exe的多个实例的pids,并在发生异常时将其转储,如下所示
脚本
$b=($a= Get-Process fkiss).count
0..($b-1)|%{$c = ("-e 1 -n 10 {0}" -f $a[$_].Id);Start-Process procdump $c}
编译并双击此代码两次
#include <stdio.h>
#include <windows.h>
void main (void){
int i=0,a=2,b=0;
while (i < 20) {
__try {
Sleep(6000);
printf("%d\n",a/b);
}__except(EXCEPTION_EXECUTE_HANDLER) {
b=2;
printf("%d\n",a/b);
Sleep(6000);
}
i++;
b=0;
}
}
在目录
中有20个转储powershell -c (get-childitem *.dmp).count
20
他们确实反映了这两个实例 使用
for %I in (dir *.dmp) do dumpchk %I | grep -i "-e 1 -n "
输出
>dumpchk fkiss.exe_160126_045712.dmp | grep -i "-e 1 -n "
Loading dump file fkiss.exe_160126_045712.dmp
*** "E:\sysint\procdump.exe" -e 1 -n 10 3084
*** "E:\sysint\procdump.exe" -e 1 -n 10 3084
>dumpchk fkiss.exe_160126_045714.dmp | grep -i "-e 1 -n "
Loading dump file fkiss.exe_160126_045714.dmp
*** "E:\sysint\procdump.exe" -e 1 -n 10 3108
*** "E:\sysint\procdump.exe" -e 1 -n 10 3108
>dumpchk fkiss.exe_160126_045724.dmp | grep -i "-e 1 -n "
Loading dump file fkiss.exe_160126_045724.dmp
*** "E:\sysint\procdump.exe" -e 1 -n 10 3084
*** "E:\sysint\procdump.exe" -e 1 -n 10 3084
答案 1 :(得分:2)
在我的评论中,我将AeDebug注册表设置中的%ld
参数与GFlags的参数混合在一起。但是,AeDebug
在这里没有用,因为它只在应用程序崩溃时才起作用,这不是这里的情况。
我使用以下演示应用程序来生成一些第一次机会异常:
using System;
namespace ThrowSomeFirstChance
{
static class Program
{
static void Main(string[] args)
{
Console.WriteLine(args[0]);
try
{
throw new ApplicationException("Exception 1");
}
catch (Exception){}
try
{
throw new ApplicationException("Exception 2");
}
catch (Exception){}
Console.ReadLine();
}
}
}
GFlags设置(影响Image File Execution Options
注册表项)的整个想法是在调试器下运行应用程序,以便从应用程序的开始就真正调试各种事情。因此,如果您使用GFlags设置,则无法传递进程ID,因为此时该进程尚未启动。该过程必须由调试器启动。
使用以下GFlags设置,ProcDump对我来说很好用:
E:\debug\procdump.exe -ma -e 1 -n 4 -x e:\debug\dumps
,其中
-ma
获取完整内存,这对.NET非常有用-e 1
捕获首次机会异常-n 4
指定要生成的最大转储量(某些应用程序可能会生成数百个例外) -x <dump folder> <application> <arguments>
指定要启动的可执行文件
请注意,-x
选项似乎不完整,但是没关系,因为Windows会自动传递应用程序名称和参数,这可能是此处奇数顺序的原因。
对WinDbg做同样的工作要多得多。您需要以正确的位数运行WinDbg以获得良好的结果,并且捕获所有第一次机会异常并非简单。
"E:\debug\x86\WinDbg.exe" -G -Q -c $$<e:\debug\dump.dbg
-G
跳过应用程序终止时的最终断点(最小化用户交互)-Q
跳过&#34;保存工作区&#34;问题(尽量减少用户互动) -c $$<dump.dbg
运行脚本
脚本将在初始断点处运行,因此不要使用-g
选项(跳过初始断点)。相反,在那时设置事物并继续g
。脚本可能看起来像
sxe -c ".dump /ma /u e:\debug\dotnet.dmp;g" clr
g
但是,请注意,这仅涵盖.NET第一次机会异常,调试器将等待其他异常的输入。如果您希望完成此操作,则需要为所有类型的异常设置命令,这远非方便(另请参阅this answer)。