3

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

我试过什么

过程转储

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

标志

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

4

2 回答 2

3

编写了一个简单的 powershell 脚本来枚举同一 exe 的多个实例的 pid,并在发生如下异常时将其转储

脚本

$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
于 2016-01-25T23:36:22.050 回答
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 设置

GFlags + WinDbg

对 WinDbg 做同样的工作要多得多。您需要以正确的位数运行 WinDbg 以获得良好的结果,并且捕获所有第一次机会异常并不简单。

"E:\debug\x86\WinDbg.exe"  -G -Q -c $$<e:\debug\dump.dbg 
  • -G应用程序终止时跳过最终断点(最小化用户交互)
  • -Q跳过“保存工作区”问题(最小化用户交互)
  • -c $$<dump.dbg运行脚本

    该脚本将在初始断点处运行,因此不要使用该-g选项(跳过初始断点)。相反,设置当时的东西并继续g。脚本可能看起来像

    sxe -c ".dump /ma /u e:\debug\dotnet.dmp;g" clr
    g
    

    但是,请注意,这仅涵盖 .NET 第一次机会异常,调试器将等待其他异常的输入。如果要完成此操作,则需要为所有类型的异常设置命令,这很不方便(另请参阅此答案)。

于 2016-01-25T22:07:49.587 回答