根据堆栈跟踪过滤中断

时间:2020-01-08 09:29:51

标签: c++ visual-studio visual-studio-2017

我想插入一个函数,但前提是未从其他特定函数调用它。这是因为大多数调用需要一个或两个函数,但是我对调试它们不感兴趣。

我注意到断点具有 Filter 选项:

Screenshot showing a filter option in dropdown menu

难道可以根据其内容过滤堆栈跟踪和中断吗?

2 个答案:

答案 0 :(得分:3)

基于以下原因,我认为您不能使用过滤器:Use breakpoints in the Visual Studio debugger具体来说,断点过滤器用于并发程序,您可以过滤: MachineName,ProcessId,ProcessName,ThreadId或ThreadName。

我要获得类似您想要的东西的一个建议是,向要插入的函数添加一个带有默认值的额外参数。然后在不需要的地方将值设置为其他内容进行监视,并在断点处使用“条件表达式”以使其仅在默认值上中断。

当然,这需要您对代码进行仅调试的更改(然后在完成后将其还原),所以这是一个非常丑陋的方法。

答案 1 :(得分:1)

如果您知道调用该函数的代码位置的地址,则可以使断点条件取决于存储在call stack上的返回地址。

因此,您应该能够将断点设置为值*(DWORD*)ESP(32位代码)或*(QWORD*)RSP(64位代码)的条件。我还没有测试过。

但是,我上面的示例仅在断点是在函数的开始处设置的情况下才有效,在被调用函数将任何值压入堆栈或修改堆栈指针之前。如果将断点放在函数的第一条指令上,我不确定Visual Studio在哪里设置断点。因此,您可能必须在反汇编窗口中将断点设置为该函数的第一条汇编程序指令,或者可能必须补偿在function prolog中修改了堆栈指针的函数。

或者,如果使用EBP寄存器(或64位RBP)设置了正确的stack frame,则可以改用它。

请注意,不是CALL指令的地址将被放置在堆栈上,而是返回地址,该地址是调用函数的下一个汇编程序级指令的地址。

我建议您首先在所需的位置设置一个无条件断点,然后使用调试器中的内存查看器检查堆栈,特别是查看ESP / RSP和EBP / RBP的值指向何处以及返回地址位于何处存储在堆栈中。