【问题标题】:Why does the debugger's breakpoint condition allow an assignment-statement as bool-condition?为什么调试器的断点条件允许赋值语句作为布尔条件?
【发布时间】:2015-02-06 12:57:03
【问题描述】:

这是非常危险的,所以我想知道为什么允许这样做。由于我经常需要在 VB.NET 和 C# 之间切换,我有时会添加如下断点条件:

foo = "bah"

如果string 变量foo"bah,我想停止,所以正确的方法是使用foo == "bah" 而不是foo = "bah"

但它“有效”。您不会在编译或运行时收到任何警告或错误。但实际上这修改变量foo,即使它有不同的值,它也总是"bah"。由于这是无声地发生的(断点永远不会被击中),因此非常危险。

为什么允许?我的推理错误在哪里(除了混淆 C# 和 VB.NET 语法)?在 C#(相对于 VB.NET)中,assignment statement 返回分配的值,因此在这种情况下不是bool,而是string。但是,如果您选中 “Is True” 框,则断点条件必须是 bool

这是我(德国)IDE 中的一个小示例“程序”和屏幕截图:

static void Main()
{
    string foo = "foo";
    // breakpoint with assignment(foo = "bah") instead of comparison(foo == "bah"):
    Console.WriteLine(foo);  // bah, variable is changed from the breakpoint window
}

断点条件对话框:

包含断点的图像代码:

【问题讨论】:

  • 好问题。这听起来绝对是个错误。
  • @KooKiz:如果您“上线”,请不要忘记删除断点。实际上,我的代码在夜间导入的 Windows 服务中运行。现在我在数据库中有数千条不正确的记录。
  • 在 VS 2013 中尝试这个(我知道你的问题被标记为 2010)得到一个错误,包括“断点条件必须评估为布尔运算” - 所以可能已经修复了。
  • 我确认该错误存在于 VS2012 和 VS2008 中。不幸的是,我在那台计算机上没有 VS2013,但 @Damien_The_Unbeliever 的结论似乎很可能
  • @PatrickHofman:我稍后编辑了我的评论,是的,也许这需要关闭,因为它无法以有用的方式回答。如果有人在 Visual Studio 更新历史记录中找到有关此错误的文档或在“已修复问题”下,那将是一个很好的答案。

标签: c# vb.net visual-studio-2010 debugging breakpoints


【解决方案1】:

这是 C# 语法的自动结果,在花括号语言组中很常见。赋值也是一个表达式,其结果是右侧操作数的值。调试器既不反对具有副作用的表达式,也不会简单地抑制它们。这可能是因为没有检查表达式是否具有 bool 结果,但调试器没有成熟的 C# 语言解析器。多亏了 Roslyn 项目,这很可能在 VS2015 中得到修复。 [注:见底部的附录]。

也是花括号语言需要一个单独的运算符来表示相等的核心原因,== vs =。这本身就必须对价值 10 亿美元的错误负责,每个 C 程序员都至少犯过一次错误。

VB.NET 不同,赋值是一个语句,= 标记对赋值和比较都有效。您可以从调试器中看出,它选择了相等运算符而不修改变量。

请记住,这实际上很有用。它使您可以临时解决错误,强制变量值并允许您继续调试并专注于另一个问题。或者创建一个测试条件。这非常有用。在前世,我编写了一个编译器和调试器并实现了“跟踪点”。偶然发现了相同的场景并将其留在原地。它在严重依赖状态机的主机中运行,在调试时覆盖状态变量非常有用。事故,不,没那么有用:)


关于其他 SO 用户正在观察什么的注释,这取决于您使用的调试引擎。 VS2013中的相关选项是Tools + Options, Debugging, General, "Use Managed Compatibility Mode" 复选框。 VS2012 中存在相同的选项,它的名称略有不同(不记得了)。勾选后,您将获得一个较旧的调试引擎,它仍然与 C++/CLI 兼容。与 VS2010 中使用的相同。

所以这是 VS2013 的解决方法,取消选中让调试器检查表达式是否产生布尔结果的选项。您可以使用新的调试引擎获得更多好处,例如查看方法返回值和对 64 位进程的 Edit+Continue 支持。

【讨论】:

  • "这很可能在 VS2015 中修复" - 根据 cmets,它在 VS2013 中已修复
  • 谢谢。但正如 Damien_The_Unbeliever has pointed out 在他的评论中,这似乎已经在 VS 2013 中修复了,不是吗?
  • 我在VS 2010中没有这个选项,2012年不是新的吗? blogs.msdn.com/b/visualstudioalm/archive/2013/10/16/…
  • 那么你当然会自动拥有旧的调试引擎。
【解决方案2】:

我可以不同意这种行为的错误性质。在我的生活中用于调试目的的几个例子是有用的:
1. 其他线程修改了您代码中的某些内容。
2. db中其他服务更新值
所以我认为对于同步的情况它可能是有用的功能,但我同意它会导致问题

【讨论】:

  • 但是为什么断点条件窗口要负责改变变量呢?它的唯一目的是定义断点条件而不是修改我的程序。您可以使用其他调试器窗口(如快速监视窗口)来修改变量。因此,即使它对您(和 Hans Passant)有帮助,它也是导致无法识别的意外更改危险的重要来源。
  • 同意你的看法。我只是提出了一些我称之为错误用法的东西
【解决方案3】:

在 Visual Studio 2019 中,断点条件中的变量赋值表达式不再起作用。

表达式将被求值,但会丢弃诸如变量赋值之类的副作用。

https://developercommunity.visualstudio.com/content/problem/715716/variables-cannot-be-assigned-in-breakpoint-conditi.html

【讨论】:

    猜你喜欢
    • 2017-03-11
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2012-03-30
    • 2022-10-08
    • 1970-01-01
    • 2021-08-05
    相关资源
    最近更新 更多