Today I ran into a need to set a breakpoint that would only stop when a certain string was encountered. In the past I have just modified the code to test for the string, and then update my driver, reboot, etc. A very time consuming process. So today I decided that I wanted to figure out how to do it right in the debugger. I knew it was possible from comments, but didn’t know how to implement it.
First of all, since runs a non-trivial set of commands each time the breakpoint is hit, so I placed the commands in a secondary file. There may be a way to get this all on a single line breakpoint command, but I don’t see it. So the breakpoint we create is just going to run the commands from the secondary file. The command to create the breakpoint is something like this:
bp driver!functionName “$$< C:\debugCommands.txt”
Then comes the important part – the actual commands that get executed. We need to evaluate a string against a pattern, which the masm expression evaluator can handle using the “$spat” command. The hard part about that is that at first glance it only appears to work with string literals. So $spat( “Big string”, “*str*” ) will work, while $spat( poi(variableName), “*str*” ) just laughs mockingly at you.
The key here is to assign the string to an alias which will then allow it to be evaluated by the $spat command. So using our example comparison, the commands in the secondary file look like:
as /mu ${/v:MyAlias} poi(variableName);
.if ( $spat( “${MyAlias}”, “*str*” ) != 0 ) { g }
The commands evaluate the string. If a match is not found, the g[o] command is executed, otherwise execution will stop at the point when the pattern is found. Note that there are much more complicated pattern matching expressions available as well.
Exactly what I needed!
Thanks a lot!
Very Very COOOOOOOL ! this info is hidden deep inside windbg docs that it is difficult to find in one go.Thanks a lot for sharing this info.
-Subodh
How do you run this when your string is a pointer within a struct? For example ‘ObjectAttributes->ObjectName->Buffer’
[comment]Edited slightly for language. I haven’t tested this myself, but it looks useful and interesting.[/comment]
0:000> as /ma my_char poi(esp+8)
my_char wtftest
0:000> .if ( $spat( “${my_char}”, “wtftest” ) != 0 ) { .printf “found” } .else {.printf “not found”}
found
Good info