How to set conditional breakpoin based on parameter value using windbg
I want to set a conditional breakpoint based on a member of one parameter, Now I can use the dt command to test this parameter, My code looks like this:
void test(const MyClassB &inst, int value)
{
}
Now I can use the dt command to view the first parameter, the result is:
0:000:x86> dt MyClassB @esp+4
dbgee!MyClassB
+0x000 id : (null)
+0x004 m : 0n2130567168
+0x008 myClassA : MyClassA
Now I want to set a conditional breakpoint on this method based on the value of inst.m, can anyone show me how to do this? Thanks a bunch!
And appreciated if anyone could provide some information on how to use offset (e.g. + 0x004 for m), thanks!
source to share
Snippet Compiled with cl /Zi /nologo /W4 /analyze %1% /link /RELEASE
in msvC ++ 2010exp
#include <stdio.h>
class MyClass {
int width,length;
public:
void set_val(int,int);
int area();
};
void MyClass::set_val(int x , int y) {
width = x;
length = y;
}
int MyClass::area() {
return width*length;
}
void main(void) {
MyClass foo;
for (int i = 0; i < 10; i++) {
foo.set_val(i,5);
printf("%d\n",foo.area());
}
}
In windbg, set a conditional breakpoint on set_val () before break at width == 7
Conditional break syntax Explanation
classtest!MyClass::set_val
<module!class::method>
@@c++()
using c++ expression evaluator
@ecx
contains a this pointer
suitable type cast on MyClass *
width
is member of MyClass
we are using 6
for comparison purposes in this demo
how we set the method break point prior to execution of set_val()
(note uninitialized garbage
when printing the first time
gc
transition from the state after displaying MyClass if width != 7
.else is implied
to break whenwidth == 7
the command must be on one line
bp classtest!MyClass::set_val
".if( @@c++((((MyClass *) @ecx )->width)) != 6 ) {dt MyClass @ecx ; gc }"
results
0:000> bp classtest!MyClass::set_val ".if( @@c++((((MyClass *) @ecx )->width)) != 6 ) {dt MyClass @ecx ; gc }"
0:000> bl
0 e 00401000 0001 (0001) 0:**** classtest!MyClass::set_val ".if( @@c++((((MyClass *) @ecx )->width)) != 6 ) {dt MyClass @ecx ; gc }"
0:000> g
ModLoad: 5cb70000 5cb96000 C:\WINDOWS\system32\ShimEng.dll
classtest!MyClass
+0x000 width : 0n4205541
+0x004 length : 0n4208683
classtest!MyClass
+0x000 width : 0n0
+0x004 length : 0n5
classtest!MyClass
+0x000 width : 0n1
+0x004 length : 0n5
classtest!MyClass
+0x000 width : 0n2
+0x004 length : 0n5
classtest!MyClass
+0x000 width : 0n3
+0x004 length : 0n5
classtest!MyClass
+0x000 width : 0n4
+0x004 length : 0n5
classtest!MyClass
+0x000 width : 0n5
+0x004 length : 0n5
eax=00000007 ebx=7ffdf000 ecx=0013ff70 edx=00416680 esi=00000000 edi=0098f6ee
eip=00401000 esp=0013ff60 ebp=0013ff78 iopl=0 nv up ei ng nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000293
classtest!MyClass::set_val:
00401000 55 push ebp
0:000> dd esp l3
0013ff60 0040106c 00000007 00000005
0:000> x @eip
0:000> ?? @eip
unsigned int 0x401000
0:000> lsa . 0,1
> 8: void MyClass::set_val(int x , int y) {
0:000> dv
this = 0xfffffffe
x = 0n7
y = 0n5
source to share
You can use the windbg pykd extension ( pykd.codeplex.com . It is easy to create a status checkpoint with it.
-
0.2.0.29 (recommended version)
S>! Pycmd
dbgee = module ("dbgee")
bp = setBp (dbgee.test, lambda bpId: getParams () [0] .m == 2130567168)
quit smoking ()
kd> g -
0.3.0.10 (developer version)
You can put the code in a file and run it with the command:! py --global bp.py
Version 0.2.x can also run scripts, but it runs it in an isolated environment, and after exiting, all objects (including breakpoints) will be destroyed. So version 0.3.x has the ability to run the script in a "global" environment (all global objects live until pykd is loaded)
source to share