在应用程序的多个实例的第一次机会异常时生成转储

时间:2016-01-25 13:33:41

标签: debugging windbg first-chance-exception gflags procdump

我想为特定应用程序生成第一次机会异常的转储,该应用程序每天多次以随机间隔启动,在任何时候都运行多个实例。

我尝试过什么

Procdump

要使用procdump,我必须知道PID或等待进程启动。随着多个实例的启动,这将无法开始监视所有已启动的实例

GFLAGS

使用gflags我可以附加调试器,但我不想手动继续每个进程,我不知道如何自动化该过程。我尝试在gflags中使用procdump作为调试器,但我不知道如何将进程传递给procdump。

2 个答案:

答案 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 + ProcDump

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会自动传递应用程序名称和参数,这可能是此处奇数顺序的原因。

GFlags settings

GFlags + WinDbg

对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)。