5

我想根据一个参数的成员设置一个条件断点,现在我可以使用命令 dt 来检查这个参数,我的代码如下所示:

void test(const MyClassB &inst, int value)
{
}

现在我可以使用dt命令查看第一个参数,结果:

0:000:x86> dt MyClassB @esp+4
dbgee!MyClassB
   +0x000 id               : (null) 
   +0x004 m                : 0n2130567168
   +0x008 myClassA         : MyClassA

现在我想根据 inst.m 的值在这个方法上设置一个条件断点,有人可以告诉我怎么做吗?非常感谢!

如果有人可以提供有关如何使用偏移量的一些信息(例如 +0x004 表示 m),我们将不胜感激,谢谢!

4

2 回答 2

5

cl /Zi /nologo /W4 /analyze %1% /link /RELEASE 在 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());
        }
    }

在 windbg 中,在 set_val() 上设置条件断点以在宽度 == 7 时中断

条件断点语法说明

classtest!MyClass::set_val <module!class::method>
@@c++()usingc++ expression evaluator
@ecx保持this pointer适当的类型转换MyClass *
widthmember of MyClass
我们6在此演示中用于比较目的,
因为我们正在设置break point prior to execution of set_val()方法
(请注意在显示 MyClass 后uninitialized garbage打印go from 条件以中断时first time
gcif width != 7
.else is impliedwidth == 7

命令应该在一行

bp classtest!MyClass::set_val    
".if( @@c++((((MyClass *) @ecx )->width)) != 6 ) {dt MyClass @ecx ; gc }"

结果

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
于 2014-11-05T09:57:21.520 回答
-1

您可以为 windbg 使用 pykd 扩展(pykd.codeplex.com。用它很容易创建条件断点。

  1. 0.2.0.29(推荐版本)

    kd>!pycmd
    dbgee = module("dbgee")
    bp = setBp( dbgee.test, lambda bpId: getParams()[0].m == 2130567168)
    quit()
    kd>g

  2. 0.3.0.10(开发者版本)

您可以将代码放在文件中并使用以下命令运行它:!py --global bp.py

0.2.x 版本也可以运行脚本,但它在一个隔离的环境中运行,退出后所有对象(包括断点)都会被销毁。所以 0.3.x 版本有可能在“全局”环境中运行脚本(所有全局对象在加载 pykd 之前都存在)

于 2014-11-05T06:45:50.927 回答