如何防止WinDbg附加到特定的子进程?

时间:2015-07-17 15:35:48

标签: windows debugging windbg

我正在使用.childdbg 1在WinDbg中调试脚本。 (该脚本以无限循环运行各种软件测试用例。这样我就能捕获罕见的崩溃。)

我不需要附加到特定的子进程(出于性能原因,因为它们是第三方并经常崩溃)。

如果我可以按进程名称指定它们,那将解决我的问题。如果您可以提出其他可以满足我需要的调试器,我将不胜感激。

注意:在这种特定情况下,配置调试器以通过GFlags附加到特定进程不是解决方案。

1 个答案:

答案 0 :(得分:4)

如果您已激活.childdbg 1,则可以使用sxe cpr。使用-c开关,您可以执行命令。像.if (yourcondition) {.detach} .else {g}之类的东西可以提供帮助。

也许cpr:ProcessName选项对您有帮助。它支持通配符过滤器。我直到现在才使用它,请参阅WinDbg帮助中的控制异常和事件

我使用以下.NET程序来执行测试:

static void Main()
{
    Console.WriteLine("Attach and press Enter");
    Console.ReadLine();
    Process.Start("Notepad.exe");
    Process.Start("calc.exe");
    Process.Start("Notepad.exe");
    Process.Start("calc.exe");
    Console.WriteLine("Started 4 processes");
    Console.ReadLine();
}

我在调试器下启动了程序并执行了以下操作:

0:004> .childdbg 1
Processes created by the current process will be debugged
0:004> sxe -c ".detach;g" cpr:calc
0:004> g
...
77da12fb cc              int     3
1:009> |
   0    id: 1fe0    create  name: DebugChildProcesses.exe
.  1    id: f60 child   name: notepad.exe
1:009> g
...
77da12fb cc              int     3
2:011> |
   0    id: 1fe0    create  name: DebugChildProcesses.exe
   1    id: f60 child   name: notepad.exe
.  2    id: 1d68    child   name: notepad.exe
2:011> g

如您所见,调试器仅附加到记事本。

不幸的是,您无法使用多个sxe cpr:process命令。无论何时再次使用它,都会覆盖以前的设置。

在这种情况下,您需要使用通用的CPR处理程序,并在命令中执行其余操作。在我的测试中,!peb当时效果不佳,所以我无法使用它。但是,WinDbg已经切换到该过程,因此|.为我们提供了进程名称以及其他一些信息。要仅提取流程名称,.foreach /pS 6 (token {|.}) { .echo ${token}}为我工作。

有了这个,您可以构建更复杂的命令,如

.foreach /pS 6 (token {|.}) { 
    .if    (0==$scmp("${token}","notepad.exe")) {.echo "It's Notepad!"} 
    .elsif (0==$scmp("${token}","calc.exe"))    {.echo "Do some math!"} 
}

(格式化可读性,删除换行符)

当您尝试将其与sxe结合使用时,会遇到一些令人讨厌的字符串转义问题。用\"替换命令中的所有引号,使其正常工作:

sxe -c"
    .foreach /pS 6 (token {|.}) { 
        .if (0==$scmp(\"${token}\",\"notepad.exe\")) {.echo \"It's Notepad!\"} 
        .elsif (0==$scmp(\"${token}\",\"calc.exe\")) {.echo \"Do some math!\"} 
    }
" cpr

(格式化可读性,删除换行符)

现在你可以做任何你喜欢的事,例如.detach.kill,只需替换上例中的.echo命令即可​​。您可以像往常一样通过分号(;)分隔它们来执行几个命令。

顺便说一句:如果您使用sxe cpr,您可能希望按sxd ibp关闭初始流程断点。