Why does the debugger's breakpoint condition a

2019-04-04 03:45发布

问题:

This is very dangerous so I wonder why it's allowed. Since I often need to switch between VB.NET and C# I sometimes add breakpoint-conditions like following:

foo = "bah"

I want to stop if the string variable foo is "bah, so the correct way was to use foo == "bah" instead of foo = "bah".

But it "works". You don't get any warnings or errors at compile- or runtime. But actually this modifies the variable foo, it makes it always "bah" even if it had a different value. Since that happens silently (the breakpoint never gets hit) it is incredibly dangerous.

Why is it allowed? Where is my error in reasoning (apart from confusing the C# and VB.NET syntax)? In C# (as opposed to VB.NET) an assignment statement returns the value that was assigned, so not a bool, but a string in this case. But a breakpoint condition has to be a bool if you check the box "Is True".

Here is a little sample "program" and screenshots from my (german) 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
}

The breakpoint-condition dialog:

The code as image including the breakpoint:

回答1:

It is an automatic consequence of C# syntax, common in the curly-braces language group. An assignment is also an expression, its result is the value of the right-hand side operand. The debugger does not object either to expressions having side-effects, nor would it be simple at all to suppress them. It could be blamed for not checking that the expression has a bool result, the debugger however does not have a full-blown C# language parser. This might well be fixed in VS2015 thanks to the Roslyn project. [Note: see addendum at the bottom].

Also the core reason that the curly-brace languages need a separate operator for equality, == vs =. Which in itself must be responsible for a billion dollar worth of bugs, every C programmer makes that mistake at least once.

VB.NET is different, assignment is a statement and the = token is valid for both assignment and comparison. You can tell from the debugger, it picks the equality operator instead and doesn't modify the variable.

Do keep in mind that this is actually useful. It lets you temporarily work around a bug, forcing the variable value and allowing you to continue debugging and focus on another problem. Or create a test condition. That's pretty useful. In a previous life-time, I wrote a compiler and debugger and implemented "trace points". Discovered the same scenario by accident and left it in place. It ran in a host that relied heavily on state machines, overriding the state variable while debugging was incredibly useful. The accident, no, not so useful :)


A note about what other SO users are observing, it depends on the debugging engine that you use. The relevant option in VS2013 is Tools + Options, Debugging, General, "Use Managed Compatibility Mode" checkbox. Same option exists in VS2012, it had a slightly different name (don't remember). When ticked you get an older debugging engine, one that is still compatible with C++/CLI. Same one as used in VS2010.

So that's a workaround for VS2013, untick the option to get the debugger to check that the expression produces a bool result. You get some more goodies with that new debugging engine, like seeing method return values and Edit+Continue support for 64-bit processes.



回答2:

I can disagree about buggy nature of this behavior. Few examples where for debugging purposes in my life if was useful:
1. Other thread modifies something in your code.
2. Other service updated value in db
So I suppose for cases of synchronization it can be useful feature, but I agree that it can cause problems