跟踪点中允许哪些表达式?

Kur*_*son 17 trace breakpoints visual-studio

在Visual Studio中创建跟踪点时(右键单击断点并选择"When Hit ..."),对话框中包含此文本,强调我的:

您可以通过将变量或其他表达式放在花括号中来包含变量或其他表达式的值...

允许什么表达?

Kur*_*son 17

微软的文档在关于什么是允许的和不允许的确切细节上相当稀少.以下大多数是通过立即窗口中的反复试验找到的.请注意,此列表适用于C++,因为这是我编写的代码.我相信C#,下面的一些禁止项目实际上是允许的.

可以评估大多数基本表达式,包括转换,设置变量和调用函数.

一般限制
  • 只支持C风格的演员阵容; 没有static_cast,dynamic_cast,reinterpret_cast,const_cast
  • 无法声明新变量或创建对象
  • 不能使用重载运算符
  • 三元运算符不起作用
  • 无法使用逗号运算符,因为Visual Studio使用它来格式化表达式的结果 ; 对多个表达式使用多组大括号
函数调用
  • 禁止的电话:
    • Lambdas(无法定义或调用它们)
    • 匿名命名空间中的函数
    • 按值获取对象的函数(因为您无法创建对象)
  • 允许通话:
    • 成员函数,包括常规函数和虚函数
    • 将引用或指针引用到基本类或类类型的函数
    • 传递范围内变量
    • 使用"&"将指针传递给范围内变量
    • 传递文字"真实","虚假",数字
    • 传递字符串文字,只要你不与"无法创建对象"规则相冲突
    • 使用多组大括号,使用一个跟踪点调用多个函数
变量分配
  • 禁止:
    • 对象
    • 字符串文字
  • 允许:
    • 具有基本类型的变量,值来自文字或其他变量
    • 内存地址,在转换后: { *(bool*)(0x1234) = true }
    • 寄存器: { @eip = 0x1234 }

用例

从跟踪点调用函数可能非常强大.您可以通过精心设置的功能和正确的呼叫来解决上面列出的大多数限制.以下是一些更具体的想法.

强迫if

非常简单:设置跟踪点以设置变量并强制if-condition为true或false,具体取决于您需要测试的内容.所有这些都无需添加代码或离开调试会话.

断点"切换"

我已经看过几次这个问题了,"我需要打破一个受到很多打击的地方.我想简单地从另一个断点启用断点,所以我关心的断点只会从某个代码中断我怎么能这样做?" 根据我们上面的知识,虽然你确实需要辅助变量,但它很容易.

  1. 创建一个全局布尔值,设置为false.
  2. 在最终目的地创建一个断点,其条件只有在全局标志为真时才会中断.
  3. 在将全局标志指定为true的关键点中设置跟踪点.

好处是你可以在不离开调试会话的情况下移动跟踪点.如果需要再次运行全局标志,请使用立即窗口或监视窗口重置全局标志.当你完成后,你需要清理的就是全局布尔值.没有其他代码可以删除.

自动跳过代码

EIP寄存器(至少在x86上)是指令指针.如果分配给它,则可以更改程序流程.

  1. 通过打破一次并查看EIP的值,在"寄存器"窗口或"@ eip,x"的"监视"窗口中查找要跳过的行的地址.(请注意,"寄存器"窗口中的值为十六进制,但没有前导"0x".)
  2. 使用表达式(例如,使用步骤1中的地址)在要跳过的行上添加跟踪点{@eip = address}.
  3. EIP分配将执行该行的任何内容之前发生.

虽然这可以很方便,但要小心,因为跳过这样的代码会导致奇怪的行为.