Debugging a foreach loop in C#: what iteration is this? - c#

Other than setting a debug variable and incrementing it every time you start the foreach, when you break in with the Visual Studio debugger connected, is there a way to tell that this is the Xth time through the loop?
I guess this would be a feature of Visual Studio if anything, not something that would be added to the compiled code.

Set a breakpoint inside the loop, then right click on the breakpoint to set the conditions. You can also right click to see the hit count while debugging and reset it if you want. You can set a boolean expression that is evaluated when the breakpoint hits to conditionally break (or just pass over).

You can also use Visual Studio's Immediate Window, which allows you to write C# expressions against any variables in scope while debugging. Use the List.IndexOf() method, like so:

Expanding on Garo Yeriazarian's answer...
A quick and dirty way without recompiling. Example code:
var ints = new[] {5, 6, 0, 1};
foreach (var i in ints)
{
Debug.WriteLine(100 / i);
}
Add one breakpoint before the loop and one inside it. When the first is hit and you want to start counting, set a Hit Count condition:
Set some large hit count condition and reset the counter and continue. Then when the exception or whatever fires, you can check the "Current hit count" again.

Heres a previous Stack Overflow question that seems to be what your looking for:
get-index-of-current-foreach-iteration
Answer quoted from that link:
Foreach is for iterating over collections that implement IEnumerable.
It does this by calling GetEnumerator on the collection, which will
return an Enumerator.
This Enumerator has a method and a property:
MoveNext()
Current
Current returns the object that Enumerator is currently on, MoveNext
updates Current to the next object.
Obviously, the concept of an index is foreign to the concept of
enumeration, and cannot be done.
Because of that, most collections are able to be traversed using an
indexer and the for loop construct.
I greatly prefer using a for loop in this situation compared to
tracking the index with a local variable.

May be you can use breakpoint hit count. Not exactly what you want, but may be helpful.
Also is there any serious reason why you don't want to use for loop in this case.

Update Feb 2017, six years later - the extension mentioned below is now called OzCode. The feature is now called Foresee, but is only supported in VS2013.
I also felt that this could be a very useful feature, so I created it as part of a commercial extension I made for the Visual Studio debugging experience called BugAid.
The extension shows you exactly which iteration you are whenever you are inside a foreach loop:
When you click the "Iteration x of y" button, you'll see a new window, showing the complete list of items, with the your current location in the loop highlighted (this list is only shown if evaluating the collection in the debugger does not cause any side effects).
Once you open ths Foreach Visualization window, you can even right click any of the upcoming items and choose "Skip to Item", to run forward until you hit that item (this can save you from manually setting-up and messing with hit-count breakpoint):

Let's say your code is
foreach (String line in lines){
Console.WriteLine(line);//breakpoint here
}
Put a breakpoint inside foreach loop, launch "Immediate window" and execute following code Array.IndexOf(lines, line);

Here's how I do it [in VS 2017] :
Set a break point inside the foreach loop
Right click the break point and select 'Actions'
In the text box, enter the following: $FUNCTION {list.Items.IndexOf(item)} where 'list' is the name of your list and 'item' is the current item
Continue running the code and watch the output window

Hit count in Visual Studio 2017:
Set the breakpoint anywhere inside the foreach loop.
Right-click your breakpoint and click "Conditions...".
Check "Conditions" box, switch dropdown to "Hit Count" and edit your Hit Count settings.
On halt, hover the breakpoint to see your settings and the Hit Count reached so far.
Don't forget that your hit count is not automatically reset to zero when you enter the loop for the 2nd time in the same session. ;-) But you can reset it manually:

Have you tried using assertion in debugging? The debugger will be launched at that exact point in your code:
For example: System.Diagnostics.Debug.Assert (myValue >=0)

If whatever you are iterating supports the IndexOf() method, you don't have to set a debug variable.
Like in this example:
foreach (var i in myList)
{
reportprogress(myList, i);
//Do stuff
}
private void reportprogress<T>(List<T> l, T i)
{
progressBar1.Value = ((l.IndexOf(i)) * 100) / l.Count;
Application.DoEvents();
}

Related

Can I jump to the ith iteration of a loop while debugging in VS?

I am debugging a C# program in Visual Studio. Consider the following snippet.
var List<string> cars = {"honda","bmw","ferrari","ford","jaguar"};
foreach (string car in cars){
purchaseCar(car);
}
I wish to debug the purchaseCar() function when it is called for car="ford". However, while debugging in Visual Studio, I will have to step over(F10) the purchaseCar() function for previous three cars until I can finally step into(F11) it. This would be really tedious if there were a larger number of previous elements.
I wish to know if there is anyway I can directly jump to the ith iteration of a loop while debugging in Visual Studio.
Rather than thinking of it as "jumping to a particular iteration" I would suggest using a conditional break point.
Add the break-point in Visual Studio, e.g. on the purchaseCar(car) line, then right click on it and select "Conditions...". You can then set a condition, which in this case would be car == "ford". Let the debugger run, and it will only break when the condition is true.

Debug statement execution counter

Is there a way to get statements execution counter in Visual Studio in C#?
So that when I encounter a bug after long digging into code with debugger, with many loops, and I want to step into function that caused the problem and I already went past it with debugger. So I could put this line before the problematic function:
if (Global_execution_counter == 5484984)
int d = 0; // put debug breakpoint here
execute_problematic_function (); // wanna step into this function
Yes you can and without any global variable counter.
The solution is using a hit count breakpoint.
Set a breakpoint at execute_problematic_function ();; right click it to bring up the context menu:
Then click "Conditions", select "Hit count" and set it to whatever value you want.
If you still don't know what's the hit count that you need to set the breakpoint to, you can take advantage of the breakpoints window, which will tell you the current value of the breakpoint:

Solutions or workaound for Visual Studio conditional breakpoint slowness

I'm using a conditional breakpoint to determine when a C# DateTime variable is greater than a certain time. This breakpoint will be checked approximately 50,000 times in a run.
my conditional breakpoint looks like:
quote.Time > new DateTime(2014,2,4,3,59,0)
Without this conditional break point my test run takes about 15 seconds. With the conditional breakpoint it takes 45 minutes.
Is there anything I can do to help speed this without modifying the code I'm debugging to add an assert or conditional?
Is there anyway to make it calculate the DateTime variable only once? Or is this more of an architectural issue with how conditional breakpoints are implemented in the IDE?
why don't you stop using a conditional break point and change the code until you have debugged it. so the code would become something like:
int dummyx = 0;
if (quote.Time > new DateTime (2014,2,4,3,59,0 )
{
dummyx++; // put normal break point here!
}
This will run much faster.
Just for debugging purposes I'd say create a new if-statement and a dummy variable (like int i = 0;) and set the breakpoint on that line. Then just step into / step through the rest of the code.. Just for testing, you can always just remove those 1-2 lines of code after testing.
The if-statement (logically) containing:
if (quote.Time > new DateTime(2014,2,4,3,59,0)) { int i=0; }
Evidently conditional break points being very slow is a known issue. See: http://www.bing.com/search?setmkt=en-US&q=visual+studio+conditional+breakpoint+slow
Since I know how many times my function will be called, deterministic simulation, I ended up using visual studio's Hit Count breakpoint feature.
This allowed me to not have to hack up the code with an if statement and iterate faster if my break condition changed.

Return from a function using a breakpoint

Is it possible to automatically return from a function using a Breakpoint/Tracepoint?
I don't want to drag the execution point or set it with CTRL+SHIFT+F10 every time the breakpoint is hit.
I tried "printing" the following "messages" When Hit, but the executions continue without change.
{return;}
{return null;}
Note that I need to return from the function without actually changing code.
To clarify what a Tracepoint is: "A tracepoint is a breakpoint with a custom action associated with it. When a tracepoint is hit, the debugger performs the specified tracepoint action instead of, or in addition to, breaking program execution." From MSDN.
If you don't know what I mean with "printing messages", you might want to read this AltDevBlogADay post about Tracepoints. It's good.
In Visual Studio you could just drag the arrow, that indicates the current code line while debugging, to the end of the function.
Okay, after a bit of digging around you can do this - but it's not going to work in all cases.
Beware, this uses macros and can't be guaranteed to work with inline delegates; or with methods that actually need to return something. It automates the process described by #juergen d and #Erno when a breakpoint is hit; using very simple heuristics to find where the end of the current function is.
You first need to add this macro to your macros environment (open with ALT+F11 in VS). This code is probably not as good as it could be as I've just rushed it out :)
Sub ExitStack()
'get the last-hit breakpoint
Dim breakPoint As EnvDTE.Breakpoint
breakPoint = DTE.Debugger.BreakpointLastHit()
'if the currently open file is the same as where the breakpoint is set
'(could search and open it, but the debugger *should* already have done that)
If (DTE.ActiveDocument.FullName = breakPoint.File) Then
Dim selection As EnvDTE.TextSelection = DTE.ActiveDocument.Selection
Dim editPoint As EnvDTE.EditPoint
'move the cursor to where the breakpoint is actually defined
selection.MoveToLineAndOffset(breakPoint.FileLine, breakPoint.FileColumn)
Dim codeElement As EnvDTE.CodeElement
codeElement = DTE.ActiveDocument.ProjectItem.FileCodeModel.CodeElementFromPoint(selection.ActivePoint, vsCMElement.vsCMElementFunction)
'if a function is found, move the cursor to the last character of it
If Not (codeElement Is Nothing) Then
Dim lastLine As EnvDTE.TextPoint
lastLine = codeElement.GetEndPoint()
selection.MoveToPoint(lastLine)
selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText)
'execute the SetNextStatement command.
'Has to be done via ExecuteCommand
DTE.ExecuteCommand("Debug.SetNextStatement")
End If
End If
End Sub
With that in place, now you can set your breakpoint - right click on it and hit the When hit... menu option (this only works in VS2010 I believe). ScottGu describes this in this blog post.
From the dialog, find the ExitStack macro that you've just pasted in.
Run the code with the debugger attached and when the breakpoint is hit the rest of the function's code should be skipped. This should obey other debugger tricks - like conditions etc.
Note - I used this SO to solve a problem I was having; originally I was invoking the debugger's SetNextStatement method directly and it didn't work
I have no idea how methods that should return will behave - in theory they should return whatever the return value local is at the time, but in some cases the fact is this simply won't work!
Equally if the breakpoint is in a try/catch block then it won't work - because the try/catch has to be exited before you can set the next statement to somewhere outside of it.
Two options:
If you want the function to complete its execution and break after returning to the caller. Press "Step Out" (Shift-F11)
If you want to skip the execution of several lines, drag the yellow marker to the next line you want to execute. Remember, dragging the marker to a location might cause an order of execution that can never happen when running without interfering so the result might be completely wrong.
Yes, you can do this directly using a tracepoint.
Find the address of the return statement at the bottom of the function by breaking on it once, and then looking at the EIP register either in the Registers window or add a Watch for "#eip".
Add a tracepoint to the line you want to jump from. Remember that the jump will occur before anything on the line is executed. The content of the tracepoint should be {#eip = address} using the address from step 1.
Profit!
See also https://stackoverflow.com/a/14695736/301729

How do i check the value of Array[x,y] quickly when debugging?

When a breakpoint is hit, I could easily hover over a variable to see its current value. But when an array is present this becomes tricky (at least for me)
dsInfo.Tables[0].Rows[0]["IsApproved"]
There are few things that I could actually do in this scenario to quickly check the value.
Debug.WriteLine()
MessageBox (lame!)
Breakpoint -> When Hit -> Print a Message
Swim through the array to the find the position.
Are there any better methods to check the value of Array[x,y] quickly using Visual Studio?
You can copy expression you want to check (dsInfo.Tables[0].Rows[0]["IsApproved"]) and paste into 'Watch' window when debugging.
Hope this helps
You can type in the variable name/expression dsInfo.Tables[0].Rows[0]["IsApproved"]
into the Immediate window (Ctrl+I) while debugging.

Categories