.net 暂停时调试和“无法评估表达式”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3626815/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Debugging whilst paused and 'cannot evaluate expression'
提问by wal
Using Visual Studio, after attaching to a Process and pressing Pause (Break-All), you switch to the desired thread and use the Quick Watch window to check out some data, say
使用 Visual Studio,在附加到进程并按暂停(Break-All)后,切换到所需的线程并使用 Quick Watch 窗口查看一些数据,例如
MySingletonClass.Instance.Data
Sometimes I either get this:
有时我要么得到这个:
Cannot evaluate expression because the current thread is in a sleep, wait, or join
无法计算表达式,因为当前线程处于睡眠、等待或加入状态
or this (when trying to view certain properties of the data):
或者这个(当试图查看数据的某些属性时):
Cannot evaluate expression because a native frame is on top of the call stack.
无法计算表达式,因为本机帧位于调用堆栈的顶部。
Quite frankly, I don't care, I just want to see the data! I know there are various ways to get around this, namely:
坦白说,我不在乎,我只想看看数据!我知道有多种方法可以解决这个问题,即:
- Setting a breakpoint on the thread and waiting till it gets hit (cumbersome, not always possible)
- Taking a dump of the process and loading back into VS (even then I still get the 2nd error)
- windbg
- 在线程上设置断点并等待它被击中(麻烦,并非总是可行)
- 转储进程并重新加载到 VS(即使这样我仍然遇到第二个错误)
- 风袋
Given you couldsee this data if you presumably used windbg why is it we all can't take advantage of the much easier and prettier VS to inspect objects when attaching to a process?
鉴于如果您大概使用了windbg,您可以看到这些数据,为什么我们都不能在附加到进程时利用更容易和更漂亮的VS来检查对象?
采纳答案by Timwi
Why can't we do this?We can't do this because the Visual Studio watch window doesn't just retrieve data from memory and display it. It actually executes managed code(that's what it means by “evaluate the expression”). In particular, it almost always executes the ToString()method to display the user-readable result.
为什么我们不能这样做?我们不能这样做,因为 Visual Studio 监视窗口不只是从内存中检索数据并显示它。它实际上执行托管代码(这就是“评估表达式”的意思)。特别是,它几乎总是执行ToString()方法来显示用户可读的结果。
The crux is that it executes this code within the process/thread you are debugging. This ensures that the expression evaluates the same way it would if it were actually in the code you are debugging. This leaves the downside that it can only be executed in between managed instructions, but not while native code is active, and not in a blocked thread.
关键是它在您正在调试的进程/线程中执行此代码。这可确保表达式的计算方式与它实际在您正在调试的代码中时的计算方式相同。这留下了它只能在托管指令之间执行的缺点,而不能在本机代码处于活动状态时执行,并且不能在阻塞线程中执行。
What can we do about it?If you are actually debugging a managed application, and you are in a native stackframe, just press F10 or Shift+F11 repeatedly until you are back in managed code. Then you can evaluate expressions. However, for fully-native processes, and for threads in a blocked state, I am not aware of any workaround.
我们对于它可以做些什么呢?如果您实际上是在调试托管应用程序,并且您在本机堆栈帧中,只需重复按 F10 或 Shift+F11,直到您返回托管代码。然后您可以评估表达式。但是,对于完全本机进程以及处于阻塞状态的线程,我不知道有任何解决方法。
回答by ja72
Here is a linkto a discussion on this issue. Apparently when function arguments are structs, and the total memory needed on the stack to call the function exceeds some magical number visual studio debugger pukes.
这是有关此问题的讨论的链接。显然,当函数参数是结构体时,堆栈上调用函数所需的总内存超过了 Visual Studio 调试器呕吐的一些神奇数字。
Additional linkfrom OpenTK framework discussion.
来自 OpenTK 框架讨论的附加链接。
回答by Jonathan Rupp
Just hit Shift-F11 until a managed stack frame is on top of the stack and you'll be able to do what you want in VS.
只需按 Shift-F11 直到托管堆栈帧位于堆栈顶部,您就可以在 VS 中执行所需的操作。
It basically comes down to the fact that it's not safe safe to evaluate expressions at certain points during the process execution, or you risk corrupting the runtime. WinDbg doesn't protect the runtime from you. VS does.
它基本上归结为这样一个事实,即在流程执行期间的某些点评估表达式是不安全的,或者您有破坏运行时的风险。WinDbg 不保护您的运行时。VS 确实如此。
回答by Brian Rasmussen
The problem is, that is is not data you want to see, it is the result of running some code. In .Net properties are really just methods in disguise, so in order to get the value of a property, Visual Studio needs to execute application code (this feature is known as FuncEval).
问题是,那不是你想看到的数据,它是运行一些代码的结果。在 .Net 中,属性实际上只是变相的方法,因此为了获取属性的值,Visual Studio 需要执行应用程序代码(此功能称为 FuncEval)。
This code must run on some thread and what VS does is that it uses one of the application threads for this. There is a number of situationswhere VS cannot run the code in order to produce the result, and that is when you seen the error messages you're talking about.
此代码必须在某个线程上运行,而 VS 所做的就是为此使用应用程序线程之一。在许多情况下,VS 无法运行代码以产生结果,这就是当您看到您正在谈论的错误消息时。
回答by leppie
If you step to the next instruction, the debugger might have enough time to evaluate it before timing out.
如果您单步执行下一条指令,调试器可能有足够的时间在超时之前对其进行评估。
Note, this wont always work.
请注意,这并不总是有效。
回答by zigots007
if your project is client server, try to reupload reference MySql.Data.dll
如果您的项目是客户端服务器,请尝试重新上传引用 MySql.Data.dll
回答by Edward Ned Harvey
I know this is a kludge, but I'm happy with the way it works. At the end of my Main() method, which originally starts everything and creates all the other data structures and threads and then terminates, I stick this:
我知道这很麻烦,但我对它的工作方式感到满意。在我的 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);
}
Instead of doing a "Break All" I just stick a breakpoint on the curly brace {. The program breaks. I have a thread available, and a reference to everything, so I can easily browse all the data structures and all the threads, see everything everywhere.
我只是在花括号 { 上贴一个断点,而不是执行“Break All”。程序中断。我有一个可用的线程,以及对所有内容的引用,因此我可以轻松浏览所有数据结构和所有线程,随时随地查看所有内容。

