Can I find out the return value before returning while debugging in Visual Studio?

C#Visual StudioVisual Studio-Debugging

C# Problem Overview


Take the following function:

DataTable go() {
    return someTableAdapter.getSomeData();
}

When I set a breakpoint in this function, is there a possibility to inspect the returned value? go() is directly coupled to a datagrid in an .aspx page.

The only way to inspect the returned datatable is to use a temporary variable. However, that's a bit inconvenient. Isn't there another way?

C# Solutions


Solution 1 - C#

Not that I know of. Note that if you do add a variable, it will get removed by the compiler in release builds anyway...

Update: This functionality has been added to VS2013. You can see the return values in the autos windows or use $ReturnValue in the watch/immediate window.

The value can only be seen directly after returning from the function, thus the easiest way to access it is by putting a breakpoint on the function call and step over (F10) the call.


Update for VS2015: boo! unfortunately, it doesn't appear to be in VS2015 (devenv v14)
Update for VS2017: it's back. (devenv v15)

Solution 2 - C#

This can be done in Visual Studio 2013 with CLR 4.5.1 according to the customer feedback site. It was not available in previous versions for C#.

(Visual Studio 2008 and earlier supported it for VB.NET. It has always been available to C/C++ developers.)

Solution 3 - C#

I agree that this is a very useful thing to have: not only seeing the return value of the method before stepping out of it, but also seeing the return value of methods I just stepped over. I implemented it as part of a commercial extension to Visual Studio called "OzCode".

With it, you can view method return values right on the code editor, as sort of a HUD-display:

Statement Visualization

For more information, please see this video.

Solution 4 - C#

According to Microsoft, there is no way to implement this reliably with managed code. This is a problem they are aware of and are working on: >For those out there who have experience debugging native C++ or VB6 code, you may have used a feature where function return values are provided for you in the Autos window. Unfortunately, this functionality does not exist for managed code. While you can work around this issue by assigning the return values to a local variable, this is not as convenient because it requires modifying your code. In managed code, it’s a lot trickier to determine what the return value of a function you’ve stepped over. We realized that we couldn’t do the right thing consistently here and so we removed the feature rather than give you incorrect results in the debugger. However, we want to bring this back for you and our CLR and Debugger teams are looking at a number potential solutions to this problem. Unfortunately this is will not be part of Visual Studio 11.

https://connect.microsoft.com/VisualStudio/feedback/details/597933/add-a-return-pseudo-variable-to-the-visual-studio-debugger-for-net-code

Solution 5 - C#

Regarding Visual Studio 2015:

According to the currently accepted answer by Marc Gravell:

> This functionality has been added to Visual Studio 2013. You can see the return > values in the autos windows or use $ReturnValue in the watch/immediate > window

That answer also stated that this functionality does not work in Visual Studio 2015. This is not (entirely) true. On Examine return values of method calls there is the following note:

> You must have the legacy expression evaluators turned on for $ReturnValue to be recognized (Tools / Options / Debugging / Use the legacy C# and VB expression evaluators). Otherwise, you can use $ReturnValue1.

I tested this in Visual Studio 2015 Enterprise:

  • With legacy expression evaluators turned off: only $ReturnValue1 works
  • With legacy expression evaluators turned on: both $ReturnValue and $ReturnValue1 work

Solution 6 - C#

If you go to menu ToolsOptions, IntelliTrace, and change the setting to collect events and call information.

You can go back to the previous call event (Ctrl + Shift + F11) and see the temporary value returned from the method call in the autos window as a child of the method name.

This isn't showing you the return value for the method you are in. It just shows you the return value of the last method called in the current method.

So, it's fine for

DataTable go(){return someTableAdapter.getSomeData();}

as it shows you the return value for someTableAdapter.getSomeData().

But not for:

int go(){return 100 * 99;}

Solution 7 - C#

Old trick from the pre .NET days: Open the Registers window and look at the value of the EAX register. This contains the return value of the last function called.

Solution 8 - C#

Step out of the go() method using Shift-F11, and then in the "Autos" debug window it will show the return value of the method call which just popped off the stack (in this case, the go() method which is what you want). This is the behaviour in Visual Studio 2005; I haven't used Visual Studio 2008 so I don't know if this behaves the same way in that version.

Solution 9 - C#

Yes, there is a very nice way. One significant drawback is that you'd have to wait for 5, maybe 6 years. Since I see that you posted in November 2008, I suggest that you waaaaaa...

...aaaait. And voilà! Just for you, MS has released the latest Visual Studio 2013 where it's a default feature accessible from the menus while running in debug mode (menu DebugWindowsAutos).

Solution 10 - C#

There are a lot of workarounds, but none seems satisfactory.

To quote John Skeet below (comment on a now-deleted answer):

> Still looks inconvenient to me - > especially if you don't know which > return value you're going to need > before you start debugging. I really > don't want to have to have a temporary > variable cluttering up my code every > time I ever return anything.t

In theory, the debugger could have a return-variable. After all: it's just a variable on the stack:

unsafe {
  int * sp = stackalloc int[1];
  try {
    return a+b;
  }
  finally {
    Trace.WriteLine("return is " + *(sp+3));
  }
}

So consider this a feature request for Visual Studio.

Solution 11 - C#

I wanted to expand upon PascalK's answer for getting this to work in Visual Studio 2015, because there is a hidden feature which is not documented in Examine return values of method calls.

If you have nested function calls, the pseudo-variables $ResultValueX are automatically created, where the X refers to the function call order. So if you have a call such as Multiply(Five(), Six()), the following pseudo-variables are created:

Five()     | $ResultValue1 = 5
Six()      | $ResultValue2 = 6
Multiply() | $ResultValue3 = 30

Solution 12 - C#

The only way I know is to place a breakpoint on the return line and then call the Quick Watch window and enter the returned expression:

someTableAdapter.getSomeData();

But this only works if the call does not change the state of any object (since there will be a second call to the same method when you will resume the execution).

Solution 13 - C#

Microsoft Visual C++ used to do this, but Visual Studio doesn't AFAIK.. :(

Solution 14 - C#

You can also ask to evaluate the value in the intermediate window as well, if it does not set flags or other variables, but only returns something.

Solution 15 - C#

Opening the Debug → Autos window gets you close. It won't show the actual return value, but it will show what was evaluated in the return statement.

Solution 16 - C#

I think you can determine this by looking at the RAX register in the Registers window (Debug / Windows / Registers). After stepping out (SHIFT + F11) of the function, check the RAX register. I don't know for a fact, but once upon a moon you could check a register (pre .NET days) and see the return value there. It might even be a combination of RAX and RBX, etc.

Solution 17 - C#

Yeah, by switching to VB.NET. ;P (You did just say "Visual Studio". ;)

For as long as I can remember (from Visual Basic through all versions of VB.NET), you can simply query the function name. It "functions" like a local variable that's implicitly declared at the start of the function and its current value is also used as the return value whenever the function exits via non-return statement means (i.e. Exit Function or just falling through) and of course, when the return statement is used.

It is also set to the return statement's expression. Just like a local variable, its value can be inspected at any point of execution inside the function (including after the return statement is executed). C# doesn't have this and should.

That little VB.NET feature (plus the Exit Function statement which it enables - another feature C# doesn't have and should) is very useful in a form of defensive programming I practice where I always initialize the function name to the failure/default value as the first statement. Then, at any failure point (which normally occurs much more often than success points), I can simply call the Exit Function statement (i.e. without having to duplicate the failure / default expression or even a constant/variable name).

Solution 18 - C#

The accepted answer doesn't work properly with Visual Studio 2015, but by placing a break point on the last line of the method and pressing F10, it will put all expressions of the return value into the locals window.

Solution 19 - C#

In VS2019, Just go to Debug->Windows->Autos window. There, you see concat return value as shown below:

enter image description here

Solution 20 - C#

You could try to select "someTableAdapter.getSomeData();", right click on it, and go for Quick Watch.

Solution 21 - C#

Drag and drop the return expression into a watch window.

For example, in the statement

return someTableAdapter.getSomeData();

drag and drop

someTableAdapter.getSomeData()

into a watch window, and you'll see the value.

You can do this for any expression.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondoekmanView Question on Stackoverflow
Solution 1 - C#Marc GravellView Answer on Stackoverflow
Solution 2 - C#Alex AngasView Answer on Stackoverflow
Solution 3 - C#Omer RavivView Answer on Stackoverflow
Solution 4 - C#Dan SolovayView Answer on Stackoverflow
Solution 5 - C#PascalKView Answer on Stackoverflow
Solution 6 - C#Ross BugginsView Answer on Stackoverflow
Solution 7 - C#ColinMView Answer on Stackoverflow
Solution 8 - C#LeopardSkinPillBoxHatView Answer on Stackoverflow
Solution 9 - C#Konrad VilterstenView Answer on Stackoverflow
Solution 10 - C#doekmanView Answer on Stackoverflow
Solution 11 - C#splttingatmsView Answer on Stackoverflow
Solution 12 - C#Sylvain RodrigueView Answer on Stackoverflow
Solution 13 - C#SprintstarView Answer on Stackoverflow
Solution 14 - C#BiriView Answer on Stackoverflow
Solution 15 - C#GeekyMonkeyView Answer on Stackoverflow
Solution 16 - C#Joe RattzView Answer on Stackoverflow
Solution 17 - C#TomView Answer on Stackoverflow
Solution 18 - C#Esben Skov PedersenView Answer on Stackoverflow
Solution 19 - C#BehzadView Answer on Stackoverflow
Solution 20 - C#Yann SemetView Answer on Stackoverflow
Solution 21 - C#Pita.OView Answer on Stackoverflow