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

时间:2013-02-04 21:11:34

标签: visual-studio breakpoints trace

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

  

您可以在消息中包含变量或其他表达式的值,方法是将其置于花括号中...

允许使用哪些表达式?

2 个答案:

答案 0 :(得分:17)

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

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

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

用例

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

强制启用if

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

断点“切换”

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

  1. 创建一个全局布尔值,设置为false。
  2. 在最终目的地创建一个断点,其条件只有在全局标志为真时才会中断。
  3. 在将全局标志分配为true的关键位置设置跟踪点。
  4. 好处是你可以在不离开调试会话的情况下移动跟踪点。如果需要再次运行全局标志,请使用立即窗口或监视窗口重置全局标志。当你完成后,你需要清理的就是全局布尔值。没有其他代码要删除。

    自动跳过代码

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

    1. 在“注册”窗口或“@ eip,x”的“监视”窗口中,通过打破一次并查看EIP的值来查找要跳至的行的地址。 (请注意,“寄存器”窗口中的值为十六进制,但没有前导“0x”。)
    2. 使用第1步中的地址,在跳过的行上添加跟踪点,使用{@eip = address}这样的表达式。
    3. EIP分配将在之前发生行上的任何内容。
    4. 虽然这可以很方便,但要小心,因为跳过这样的代码会导致奇怪的行为。

答案 1 :(得分:2)

正如Kurt Hutchinson所说,在跟踪点中不允许字符串赋值。你可以通过创建一个分配字符串变量的方法来解决这个问题,然后调用它。

public static class Helper
{
    public static void AssignTo(this string value, out string variable)
    {
        variable = value;
    }
}

然后在你的跟踪点消息中:

{"new string value".AssignTo(out stringVariable)}