【发布时间】:2020-04-25 19:36:21
【问题描述】:
我想中断一个函数,但前提是它不是从特定的其他函数调用的。那是因为大多数调用都需要一两个函数,但我对调试它们不感兴趣。
我注意到断点有一个 Filter 选项:
这是可以用来过滤堆栈跟踪并根据其内容中断的东西吗?
【问题讨论】:
标签: c++ visual-studio visual-studio-2017
我想中断一个函数,但前提是它不是从特定的其他函数调用的。那是因为大多数调用都需要一两个函数,但我对调试它们不感兴趣。
我注意到断点有一个 Filter 选项:
这是可以用来过滤堆栈跟踪并根据其内容中断的东西吗?
【问题讨论】:
标签: c++ visual-studio visual-studio-2017
如果您知道调用函数的代码位置的地址,则可以使断点条件取决于存储在call stack 上的返回地址。
因此,您应该能够将断点设置为值*(DWORD*)ESP(32 位代码)或*(QWORD*)RSP(64 位代码)的条件。不过我还没有测试过。
然而,我上面的例子只有在函数的最开始设置断点时才有效,在被调用的函数将任何值压入堆栈或修改堆栈指针之前。如果将断点放在函数的第一条指令上,我不确定 Visual Studio 在哪里设置断点。因此,您可能必须将反汇编窗口中的断点设置为函数的第一条汇编指令,或者您可能必须对修改了function prolog 中的堆栈指针的函数进行补偿。
或者,如果使用 EBP 寄存器(或 64 位的 RBP)设置了正确的 stack frame,那么您可以使用它。
请注意,入栈的不是CALL指令的地址,而是返回地址,即调用函数的下一条汇编级指令的地址。
我建议你先在你想要的位置设置一个无条件断点,然后使用调试器中的内存查看器检查堆栈,特别是查看 ESP/RSP 和 EBP/RBP 的值指向的位置以及返回地址在哪里存储在堆栈中。
【讨论】:
我认为您不能为此使用过滤器,基于此:Use breakpoints in the Visual Studio debugger 具体来说,断点过滤器适用于并发程序,您可以过滤: MachineName、ProcessId、ProcessName、ThreadId 或 ThreadName。
为了得到你想要的东西,我会提出一个建议,就是在你想要插入的函数中添加一个带有默认值的额外参数。然后在你不想要的地方将该值设置为不同的值进行监视,并在断点中使用“条件表达式”使其仅在默认值上中断。
当然,这需要您对代码进行仅调试更改(然后在完成后恢复它们),因此这是一种非常丑陋的方法。
【讨论】: