The title may be a little confusing so I'll explain. Say you had this call chain...
public DoWork(index) >> private DoWorkHelper(index) >> private CheckIndex(index)
Now if you call DoWork
, it traverses the calls down to CheckIndex
, adding each deeper call to the call stack.
Now if someone calls DoWork
with a bad value for index
, it throws the exception all the way down at CheckIndex
, and currently, that's where the debugger breaks. You then have to walk back up the call stack to see the real offender was that someone passed bad data to DoWork
.
Now back in the VB6 days, you could simply decorate DoWorkHelper
and CheckIndex
with an attribute to say 'If any exception is thrown inside me, don't highlight me, but rather my caller because they were the ones that passed me bad crap!' So in this case, the code would break inside DoWork
with the call to DoWorkHeper
highligh开发者_JAVA技巧ted.
There was also a setting to disable this so for deeper debugging purposes it could still be thrown at CheckIndex
, the level where it actually occurred, but half the time, breaking down there tells you nothing because you don't know how you got there without walking back up the call stack.
Think of it a way to decorate your code to say when you hit an exception, auto-traverse the call stack to the point where the bad value actually tells you something useful.
Note this is similar to 'Break On All Exceptions' except you're handling this via decoration. Plus, you're not setting to break on a specific type of exception (e.g. all null reference exceptions, etc.) but rather a specific method! (or more accurately, the one that called the decorated method.)
So does C# or .NET in general have this?
Update
While I credit Dark Falcon for the answer since he directed me there, I've added a more detailed explanation about what all the attributes mean, and in what context. Check it out below.
Please see the Just My Code option. You need to decorate DoWorkHelper
with DebuggerHiddenAttribute
or DebuggerNonUserCodeAttribute
.
Just adding what I've found to better explain so people don't have to go looking elsewhere...
There are three attributes related to this: DebuggerHidden
, DebuggerStepThrough
, and DebuggerNonUserCode
.
Here are the rules:
When Just My Code
is not checked:
DebuggerNonUserCode
This is basically ignored. Breakpoints, step-into and exceptions all work the same as if this attribute wasn't there.DebuggerStepThrough
This respects breakpoints and will break on exceptions where they occur, but you cannot manually step into blocks marked with this attribute.DebuggerHidden
This doesn't allow you to step in to these blocks, it ignores breakpoints, and any exceptions thrown are handled in the calling method, not where they actually occur.
When Just My Code
is checked
- All three attributes behave the same as if you had used
DebuggerHidden
above.
There's another attribute, DebuggerStepperBoundary
that is pretty cool. Here's the excerpt from MSDN:
Use the DebuggerStepperBoundaryAttribute to escape from stepping through code to running code. For example, in Visual Studio 2005, encountering a DebuggerStepperBoundaryAttribute while stepping through code using the F10 key (or Step Over command) has the same effect as pressing the F5 key or using the Start Debugging command.
Hope this clears things up! Sure did for me!
精彩评论