c++ - Windbg 条件断点未按预期工作,我的语法是否正确?

标签 c++ debugging conditional-statements windbg break

我试图学习如何在 windbg 中设置条件断点,我的程序名为 ConsoleApplication7,如下所示:

int main()
{
    int r1 = 0;
    r1 += 1;
    r1 = 3;
    return 0;
}

我用VC编译这个程序。然后在 windbg 中,我设置了“符号路径”和“源路径”,在 windbg 中打开 ConsoleApplication7.exe,windbg 运行并打开 .cpp 文件。

在 windbg 中我设置了一个条件断点,我希望程序应该在行“r1=3”时。

bp consoleapplication7!main "j (poi(r1)>2) ''; 'gc'"

但是当我按下“g”时,windbg 并没有说“Hit breakpoint”,而是打印出寄存器信息。运行 "g"3 次后,程序终止,如下所示:

0:000> bp consoleapplication7!main "j (poi(r1)>2) ''; 'gc'"
*** WARNING: Unable to verify checksum for ConsoleApplication7.exe
0:000> bl
 0 e 01251380     0001 (0001)  0:**** ConsoleApplication7!main "j (poi(r1)>2) ''; 'gc'"
0:000> g
eax=00718918 ebx=7efde000 ecx=0071b880 edx=00000001 esi=00000000 edi=00000000
eip=01251380 esp=002afeb4 ebp=002aff00 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
ConsoleApplication7!main:
01251380 55              push    ebp
0:000> g
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=77c02100 edi=77c020c0
eip=77b1fcd2 esp=002afe18 ebp=002afe34 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!NtTerminateProcess+0x12:
77b1fcd2 83c404          add     esp,4
0:000> g
       ^ No runnable debuggees error in 'g'

其他命令如ba、bp在程序中运行良好,只是条件断点不行。

我的条件语句是否正确?为什么它不起作用?

我尝试了 Dono 回答中的建议,但它显示了另一个问题

0:000> bp ConsoleApplication7!main+0x3e "j (poi(r1) > 2) ''; 'gc'"
0:000> bl
 0 e 008e143e     0001 (0001)  0:**** ConsoleApplication7!main+0x3e "j (poi(r1) > 2) ''; 'gc'"
0:000> g
(4458.4840): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=7efde000 ecx=d3392f75 edx=00000001 esi=00000000 edi=00000000
eip=cccccccc esp=0046f82c ebp=cccccccc iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
cccccccc ??              ???

似乎这个条件断点导致异常? 谢谢!

我也尝试了 Blabb 的建议,不幸的是,它没有奏效:

0:000> t "$$>a< c:\\autostep.txt"
Couldn't resolve error at 'r1) == 3 ) { dv } .else { t "$$>a< c:\\autostep.txt" } '
eax=00000001 ebx=7efde000 ecx=00000000 edx=00000001 esi=00000000 edi=001dfcb0
eip=013b13c0 esp=001dfbac ebp=001dfcb0 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
ConsoleApplication7!f:
013b13c0 55              push    ebp

似乎C++风格的命令不起作用,所以我把它改成了MASM风格

j (poi(r1)==3)''; 't "$$>a< c:\\autostep.txt"'

另存为 c:\autostep.txt 然后我重新启动 windbg 以重新加载它。

0:000> t "$$>a< c:\\autostep.txt"
eax=00000000 ebx=00000000 ecx=bc260000 edx=0015dc38 esi=fffffffe edi=00000000
eip=77ba0e15 esp=0042f804 ebp=0042f830 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000244
ntdll!LdrpDoDebuggerBreak+0x2d:
77ba0e15 8975fc          mov     dword ptr [ebp-4],esi ss:002b:0042f82c=00000000
0:000> g
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=77c02100 edi=77c020c0
eip=77b1fcd2 esp=0042fb94 ebp=0042fbb0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!NtTerminateProcess+0x12:
77b1fcd2 83c404          add     esp,4

这一次,当它没有像我预期的那样中断/停止时,它没有语法问题。我错过了什么吗?

谢谢。

最佳答案

首先,您应该意识到您的程序将被优化为仅 xor eax,eax ;回复

除非您在 Debug模式下编译并使用/Od 开关显式禁用优化

(我假设您正在 Debug模式下使用视觉怪物项目来处理这个问题)

其次你应该知道调试器不知道你的 r1 r2 或其他什么,除非存在符号信息和事件然后你应该知道有两个表达式评估器 MASM 和 C++,默认情况下 windbg 使用 MASM

? poi(r1) == MASM evaluation 
?? r1 == c++ evaluation    

否则调试器只理解 cpu 理解的变量,如 BYTE、WORD、DWORD、QWORD ....等和地址

当您设置条件断点时,如 bp xxxxxmodule!yyyyysymbol “条件”条件仅在指定的地址上计算,不在下面 所以你的情况只在 main 上评估过

你应该更进一步,并在每一步都评估你的条件,直到你遇到匹配

编译后的代码和反汇编的 main() 将如下所示

0:000> .dml_flow steptest!main .
                              <No previous node>                    


          STEPTEST!main (013e6aa0):
          e:\test\steptest\steptest.cpp
          2     013e6aa0 push    ebp                                
          2     013e6aa1 mov     ebp,esp                            
          2     013e6aa3 push    ecx                                
          3     013e6aa4 mov     dword ptr [ebp-4],0                
          4     013e6aab mov     eax,dword ptr [ebp-4]              
          4     013e6aae add     eax,1                              
          4     013e6ab1 mov     dword ptr [ebp-4],eax              
          5     013e6ab4 mov     dword ptr [ebp-4],3                
          6     013e6abb xor     eax,eax                            
          7     013e6abd mov     esp,ebp                            
          7     013e6abf pop     ebp                                
          7     013e6ac0 ret                                        


                                <No next node>                      
0:000> lsa .
     1: int main()
     2: {
     3:     int r1 = 0;
>    4:     r1 += 1;
     5:     r1 = 3;
     6:     return 0;
     7: }

所以你的条件只能在第 6 行或地址 013e6abb xor eax, eax 的汇编中为真

您在 013e6aa0 上设置了一个条件 bp 并且仅在该地址评估条件

你需要找到一种方法直到 013e6abb

那是你应该做的

step <evaluate> if match stop else repeat step and evaluate until match occurs 

为此,将以下行放入名为 autostep.txt 的文件中,并将其保存到 c:\

脚本的解释

如果 c++ 表达式 r1 等于 3,则通过再次运行此脚本显示本地 else 步骤并重新评估(因此此脚本将在每个指令序列上执行,直到找到匹配项)

.if ( @@c++(r1) == 3 ) { dv } .else { t "$$>a< c:\\autostep.txt" } 

现在在 windbg 中打开 exe 并执行

bp xxxxmod!main
g
t "$$>a< c:\\autostep.txt"

当 r1 为 3 时,windbg 将崩溃

E:\test\STEPTEST>cdb -c "g steptest!main" STEPTEST.exe

0:000> cdb: Reading initial command 'g steptest!main'

STEPTEST!main:
013e6aa0 55              push    ebp
0:000> t "$$>a< c:\\autostep.txt"
             r1 = 0n3

013e6abb 33c0            xor     eax,eax
0:000> ?? r1
int 0n3
0:000> ? poi(r1)
Evaluate expression: 3 = 00000003
0:000> ? &main ; ? &@eip
Evaluate expression: 20867744 = 013e6aa0
Evaluate expression: 20867771 = 013e6abb
0:000>

可以在cmd.exe中调用脚本

cat c:\autostep.txt
.if ( @@c++(r1) == 3 ) { dv } .else { t "$$>a< c:\\autostep.txt" }

cdb -c "g steptest!main;$$>a< c:\autostep.txt"  STEPTEST.exe

0:000> cdb: Reading initial command 'g steptest!main;$$>a< c:\autostep.txt'

             r1 = 0n3

eax=00000001 ebx=7ffd6000 ecx=a4894de4 edx=00000001 esi=00a2dd04 edi=00a2dd08
eip=009d6abb esp=0019f8d0 ebp=0019f8d4 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
STEPTEST!main+0x1b:
009d6abb 33c0            xor     eax,eax
0:000>

关于c++ - Windbg 条件断点未按预期工作,我的语法是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38650835/

相关文章:

c++ - 如何使用 OLE-DB 访问 COM/C++ ATL 应用程序中的 dbf 文件?

php - 为什么我的 MySQL 查询在 PHP 条件检查之前执行?

mysql - 如何获取排名靠前的记录并在sql中有不同的条件?

c - 如何在c中设计条形图

c++ - 为什么纯虚析构函数的实现必须为空?它应该是内联的吗?

c++ - C++:交换两个不同 vector 的两个元素

javascript - 我如何跟踪 JavaScript 对 DOM 所做的更改?

javascript - 第二个数组的每个元素是否等于第一个数组元素的平方(CODEWARS)

javascript - 如何降低 *ajax* 请求调试的网络性能?

c++ - 向 Waf 配置添加包含路径 (C++)