【问题标题】:Visual Studio - How to change the return value of a method in the debugger?Visual Studio - 如何在调试器中更改方法的返回值?
【发布时间】:2010-10-02 04:20:41
【问题描述】:

当我在调试时,我经常不得不处理不使用中间变量来存储返回值的方法:

   private int myMethod_1()
   {
      return 12;
   }

   private int myMethod_2()
   {
      return someCall( someValue );
   }

嗯,为了重现错误,我经常不得不即时更改值。在这里,我想看看myMethode_1 返回零时会发生什么。 myMethod_2 也一样。

有没有办法做到这一点不修改代码?我想做的是在返回行(或右括号)上放置一个断点并输入一个新的返回值。

注意:我使用的是 Visual Studio 2005 和 Visual Studio 2008。

谢谢!

【问题讨论】:

  • 我相信这可以通过隐藏的 VS 调试器变量来实现,例如 $exception 完全没有记录。我是顺便听说的(我想)。如果我能找到更多信息,我会发布一个真实的答案。
  • 我很好奇,我也去搜一下。谢谢。
  • 相关的是调试时修改寄存器值的主题,但这只能在本机代码中完成。 stackoverflow.com/questions/244940/…

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


【解决方案1】:

函数的返回值通常在 EAX 寄存器中返回。

如果您在函数末尾设置断点,那么更改 EAX 可能会更改返回值。您只需在监视窗口中写入名称即可更改和查看 Visual Studio 中的任何寄存器。
如果您对函数进行了优化,或者即使该函数很简单,例如return 12,这可能会失败。如果您返回的东西不适合 32 位寄存器,它也可能不起作用。 至少值得一试。

【讨论】:

  • 事实上,我一直在寻找类似的东西,因为大多数时候,我都在尝试将返回值替换为空值(应该是 0 ?)。好吧,我只是试了一下,但我无法更改 EAX 值(即使在反汇编模式下)。有什么提示吗?也许我的设置?谢谢。
【解决方案2】:

对于那些在 VB.NET 中寻找解决方案的人:

它是如此简单,我不敢相信我没有看到它:查看函数将返回的值:只需将指针放在函数名上。该值将显示在工具提示中。

更改值:只需单击此工具提示,更改值并按 Enter。

Visual Studio 很酷!

注意:我在 Visual Studio Team System 2008 的 VB.NET 中对其进行了测试。刚刚尝试使用 C#,但它不起作用... :-(

【讨论】:

  • 对于那些希望在 VB.NET 中做同样事情的人来说仍然是一个很好的答案。 :)
  • 是吗?它在 2015 年对我不起作用。也许我做错了什么?
  • 它不适用于我在 2015 年使用 C#....返回值确实显示在“本地”窗口中,但与大多数项目不同的是,您不允许编辑该值。
【解决方案3】:

不这么认为。
您需要在被调用者或调用者中有一个临时变量,以便获取值的句柄以在 IDE 调试器/QuickWatch 窗口中修改它。因此,最简单、最快的方法是注释现有代码并临时更改 debug-what-if。

任何一个

private int myMethod_1()
{
  var x = 12;
  return x;
}

或者

private int myMethod_2()
{
  var y = someCall( someValue);
  return y;
}

不认为这样做值得“避免代码更改”。如果我 FUBAR,我会结帐,我们又是金牌了。

【讨论】:

  • 你可能是对的......这是我大部分时间都在做的事情,但很麻烦。想象一下:MyCall(MyCallA(), MyCallB());通常,MyCallA() 只是一系列调用调用的调用......好吧,如果能够即时更改返回值,我会非常高兴。谢谢。
【解决方案4】:

为什么要更改被调用方法中的返回值?您可以在 Calling 方法中轻松地即时更改它。一旦你的函数返回,你就会得到返回的值,你可以在那里改变它。

私有 int myMethod_1() { 返回 12; } //调用会是这样的 int x = myMethod_1(); //这里你可以在上面的行执行后改变值。

即使您没有将返回值存储在变量中,而是直接将其传递给其他方法,即使这样您也可以通过进入该方法并在那里更改参数值来更改值。我在这里遗漏了什么吗?

【讨论】:

  • 你是对的:我们可以经常这样做。困扰我的是这样的调用:APICallIDontHaveTheCode(MyCallB(), MyCallC())(这非常频繁)。我应该在问题中指出这一点。问题 - 如何更改 MyCallC() 的返回值?谢谢。
  • 使用局部变量缓存 MyCallC() 的值,然后再将其传递给 APICAllIDontHaveTheCode
  • 是的,这肯定行得通。如果我们能够即时更改值,它仍然很方便 :o)。谢谢你的回答!
  • 如果您的代码是非托管的,那么您可以选择。将 eax 放在您的监视窗口中,这将始终包含最后返回的值。您可以根据需要更改它。我仍在寻找一种在托管/混合代码中执行此操作的方法:)。
  • @Aamir - 下面的最后一个答案也是关于更改 EAX 的值。听起来很有趣。不过,我目前只使用托管代码:o(
【解决方案5】:

你需要的是模拟。检查模拟框架,如 Rhinomock、Moq 或 Typemock。

对于您描述的那种场景,我将假设您可能没有干净的合同驱动的开发,并且可能需要以虚假的行为/状态返回。在这种情况下,Typemock 可能是您的最佳选择,尽管它是商业的

【讨论】:

  • 非常棒的提示,但不完全符合我的要求。我会尽快测试 Rhinomock、Moq 和 Typemock。坦克为你解答!
  • -1 - 这个想法是在调试器中改变它。这就是调试器的用途。如果您要仅为此更改代码,那么更容易的转换是var result = blah; return result;
【解决方案6】:

我认为您可以在 Visual Studio 中执行此操作,但我觉得这很脏。

我的想法是,您真的应该研究一个单元测试框架并进行模拟,以便您可以将 myMethod_2 的输出伪造为 0 并查看它对您的代码有什么影响。国际海事组织。这样,您可以在单元测试中保留 return 0 检查,以确保丑陋的错误不会再次出现。

【讨论】:

  • 这可以完成我认为的工作。但这有点复杂:当我必须重新创建生产代码中发生的事情时,我 1) 必须快速工作 2) 不应该改变太多事情。我必须对此进行调查。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-14
相关资源
最近更新 更多