暂停时调试并且“无法评估表达式”

时间:2010-09-02 11:54:09

标签: .net visual-studio debugging

使用Visual Studio,在连接到Process并按Pause(Break-All)后,切换到所需的线程并使用Quick Watch窗口检出一些数据,比如说

MySingletonClass.Instance.Data

有时候我得到这个:

  

无法计算表达式,因为当前线程处于休眠,等待或加入

或者(当试图查看数据的某些属性时):

  

无法计算表达式,因为本机帧位于调用堆栈的顶部。

坦白地说,我不在乎,我只是想看看数据!我知道有各种方法来解决这个问题,即:

  1. 在线程上设置断点并等待它被击中(繁琐,并非总是可能)
  2. 转移进程并加载回VS(即便如此,我仍然得到第二个错误)
  3. WinDBG的
  4. 鉴于你可以看到这些数据,如果你大概使用了windbg为什么我们都无法利用更简单,更漂亮的VS来连接到一个进程时检查对象?

7 个答案:

答案 0 :(得分:22)

为什么我们不能这样做?我们不能这样做,因为Visual Studio监视窗口不只是从内存中检索数据并显示它。它实际上执行托管代码(这就是“评估表达式”的含义)。特别是,它几乎总是执行ToString()方法来显示用户可读的结果。

关键是它在您正在调试的进程/线程中执行此代码 。这可以确保表达式的计算方式与在调试代码中的实际情况相同。这样做的缺点是它只能在托管指令之间执行,但在本机代码处于活动状态时不会执行,而不是在阻塞的线程中执行。

我们可以对此做些什么?如果您实际上正在调试托管应用程序,并且您处于本机堆栈框架中,请反复按F10或Shift + F11,直到您返回托管代码。然后你可以评估表达式。但是,对于完全本机进程以及处于阻塞状态的线程,我不知道有任何解决方法。

答案 1 :(得分:4)

以下是关于此问题的讨论的link。显然,当函数参数是结构体时,堆栈上调用函数所需的总内存超过了一些神奇的数字视觉工作室调试器。

来自OpenTK框架讨论的其他link

答案 2 :(得分:3)

只需按下Shift-F11,直到托管堆栈帧位于堆栈顶部,您就可以在VS中执行所需操作。

它基本上归结为这样一个事实,即在流程执行期间在某些点评估表达式是不安全的,否则您可能会破坏运行时。 WinDbg不保护您的运行时。 VS确实。

答案 3 :(得分:2)

问题是,这不是您想要查看的数据,而是运行某些代码的结果。在.Net属性中实际上只是伪装的方法,因此为了获取属性的值,Visual Studio需要执行应用程序代码(此功能称为FuncEval)。

此代码必须在某个线程上运行,VS所做的是它使用其中一个应用程序线程。有a number of situations,VS无法运行代码以产生结果,就在您看到正在讨论的错误消息时。

答案 4 :(得分:0)

如果您单步执行下一条指令,调试器可能有足够的时间在超时之前对其进行评估。

注意,这不会一直有效。

答案 5 :(得分:0)

如果您的项目是客户端服务器,请尝试重新上载引用MySql.Data.dll

答案 6 :(得分:0)

我知道这是一个kludge,但我对它的工作方式感到满意。在Main()方法的最后,它最初启动所有内容并创建所有其他数据结构和线程然后终止,我坚持这一点:

        while (true)
        {
            // This infinite while loop just gives me a convenient place for a 
            // breakpoint, so I can see everything everywhere during debugging.
            Thread.Sleep(100);
        }

而不是做一个“全部打破”我只是在大括号上贴了一个断点{。该计划中断。我有一个可用的线程,以及对所有内容的引用,因此我可以轻松浏览所有数据结构和所有线程,随处查看所有内容。