【问题标题】:How to set conditional breakpoin based on parameter value using windbg如何使用windbg根据参数值设置条件断点
【发布时间】:2014-11-04 12:02:47
【问题描述】:

我想根据一个参数的成员设置条件断点, 现在我可以使用命令 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),我们将不胜感激,谢谢!

【问题讨论】:

    标签: windbg conditional-breakpoint


    【解决方案1】:

    在 msvc++2010exp 中使用 cl /Zi /nologo /W4 /analyze %1% /link /RELEASE 编译的片段

     #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() 的条件断点以 当 width == 7 时中断

    条件断点语法说明

    classtest!MyClass::set_val &lt;module!class::method&gt;
    @@c++() 使用 c++ expression evaluator
    @ecx 持有 this pointer 适当类型转换为 MyClass *
    widthmember of MyClass
    我们在此演示中使用6 进行比较
    因为我们正在设置break point prior to execution of set_val() 方法
    (注意 uninitialized garbage 打印时 first time
    gc 在显示 MyClass if width != 7
    .else is implied 后从条件转到 width == 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
    

    【讨论】:

    • 顺便说一句,您能解释一下 0x0000x004 的值是什么,以及如何使用它们吗?提前致谢! classtest!MyClass +0x000 width : 0n0 +0x004 length : 0n5
    • 这些是成员的偏移量宽度在 32 位机器中定义为 int = 32 位,因此 4 字节是宽度的大小,宽度从 0x0 开始,长度跟随在 + 4 处,依此类推,假设您位于说 0x403000 的结构 403000 将保持宽度 403004 将保持长度等等
    • 谢谢!我们可以根据寄存器使用这些偏移量吗,以您的代码为例,ecx?也许像dd whatfunc(@ecx)+offset这样的代码?
    【解决方案2】:

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

    1. 0.2.0.29(推荐版本)

      kd>!pycmd
      dbgee = 模块(“dbgee”)
      bp = setBp(dbgee.test, lambda bpId: getParams()[0].m == 2130567168)
      退出()
      kd>g

    2. 0.3.0.10(开发者版本)

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

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

    【讨论】:

    • 谢谢! BTW,你知道用偏移量来查看 d 命令的值吗?比如dd(somfunc(@esp+4) + offset)等,我不知道...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-08
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多