代码之家  ›  专栏  ›  技术社区  ›  wal

调试暂停且“无法计算表达式”

  •  27
  • wal  · 技术社区  · 15 年前

    使用visualstudio,在附加到进程并按Pause(Break All)之后,您将切换到所需的线程,并使用Quick Watch窗口签出一些数据,例如

    MySingletonClass.Instance.Data
    

    无法计算表达式,因为当前线程处于休眠、等待或联接状态

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

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

    坦白说,我不在乎,我只想看看数据!我知道有很多方法可以解决这个问题,即:

    1. 在线程上设置断点并等待它被命中(很麻烦,不总是可能的)
    2. 将进程转储并加载回VS(即使这样,我仍然会得到第二个错误)
    3. 温伯格

    能够

    7 回复  |  直到 11 年前
        1
  •  22
  •   Timwi    15 年前

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

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

    如果实际调试的是托管应用程序,并且处于本机stackframe中,只需反复按F10或Shift+F11,直到回到托管代码中。然后可以计算表达式。但是,对于完全本机进程和处于阻塞状态的线程,我不知道有什么解决方法。

        2
  •  4
  •   John Alexiou    15 年前

    这是一个 link 对这个问题的讨论。显然,当函数参数是结构时,堆栈上调用函数所需的总内存超过了visualstudio调试器吐出的神奇数字。

    附加 link 来自OpenTK框架讨论。

        3
  •  3
  •   Jonathan Rupp    15 年前

        4
  •  2
  •   Brian Rasmussen    15 年前

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

    此代码必须在某个线程上运行,而VS所做的是使用其中一个应用程序线程来执行此操作。有 a number of situations 其中VS不能运行代码来生成结果,也就是当您看到您正在谈论的错误消息时。

        5
  •  0
  •   leppie    15 年前

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

        6
  •  0
  •   zigots007    13 年前

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

        7
  •  0
  •   Edward Ned Harvey    13 年前

    我知道这是一个混乱,但我很高兴它的工作方式。在我的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);
            }
    

    我只是在花括号{上粘贴一个断点,而不是执行“全部中断”。程序中断。我有一个可用的线程,以及对所有内容的引用,因此我可以轻松地浏览所有数据结构和所有线程,查看所有内容。