How can I prevent WinDbg from attaching to specific child processes?

I am debugging a script in WinDbg with .childdbg 1

. (The script runs various test cases of the software in an infinite loop. This is how I find rare crashes.)

I don't need to attach to specific child processes (for performance reasons and because they are third party and often crash).

If I could specify them by process name it would solve my problem. If you can suggest another debugger that can do what I need, I would be grateful.

NOTE. Configuring the debugger to attach to specific processes via GFlags is not a solution in this particular case.

+3


source to share


1 answer


If you have activated .childdbg 1

, you can use sxe cpr

. With the switch, -c

you can execute the command. Perhaps something like .if (yourcondition) {.detach} .else {g}

.

Perhaps the option is cpr:ProcessName

really helpful to you. It supports wildcard filters. I have never used it until now, see "Managing Exceptions and Events" in the WinDbg help.

I used the following .NET program to execute the test:

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();
}

      

I ran the program under a debugger and did the following:

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

      

As you can see, the debugger is only connected to Notepad.

Unfortunately, you cannot use multiple commands sxe cpr:process

. Whenever you use it again, it will overwrite your previous settings.

In this case, you need to use a common CPR handler and do the rest within the command. !peb

Didn't work in my tests at the time, so I couldn't use it. However, WinDbg has already switched to this process, so |.

it gives us the process name along with some other information. To extract just the process name .foreach /pS 6 (token {|.}) { .echo ${token}}

worked for me.



With this, you can create more complex commands like

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

      

(formatted for readability, remove line breaks)

When you try to combine this with sxe

, you run into some nasty string escaping issues. Replace all quotes inside your command with \"

to make it work:

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

      

(formatted for readability, remove line breaks)

Now you can do whatever you want, for example. .detach

or .kill

, just replace the command .echo

in the above example. You can execute multiple commands by separating them with semicolons ( ;

) as usual.

BTW: If you are using sxe cpr

, you might want to disable the starting breakpoint of the process on sxd ibp

.

+4


source







All Articles