“全部打破”之后在 Visual Studio 2010 中,一些线程我的 C++ 中大部分都缺少调用堆栈程序
我的跨平台 C++ 应用程序的最新版本(使用 Juce)在 Windows 中可能出现死锁或可能出现无限循环,但在 Mac 中则不然,不幸的是,我们目前没有 Windows 开发人员,所以这取决于我。
我可以在 Visual Studio 2010 下运行该程序,但出现问题,然后当我遇到“活性丧失”时:-DI 使用“全部中断”命令,这似乎会挂起我的所有线程。很好,而且大部分筹码都非常合理。不幸的是,几个线程,包括我怀疑陷入死锁的两个线程,没有可用的调用堆栈。
我完全明白我的堆栈的“顶部”不会在那里,因为我没有 ntdll.dll 等的调试信息。但我似乎只是从堆栈的中间得到了一点点。
我将其中一份不好的堆栈和一份好的堆栈供您细读。您可以看到,好的堆栈一直跟踪到线程的调用函数,但坏的堆栈只有一个有效帧。
该框架是合法的,但我不知道为什么我看不到其他框架,这使我的工作非常困难。
任何想法将不胜感激 - 希望你的一天比我的更有成效! :-D
编辑: 抱歉,当我指出我知道 Microsoft 符号丢失时,我以为我在上面说得很清楚,但不在乎。问题是堆栈跟踪丢失了我的代码中的所有帧,我确信我有调试符号。
我实际上已经克服了僵局,所以现在这不是问题,但它使效果更加令人费解,因为我现在知道我没有以某种方式搞砸调用堆栈。
现在,我确实有一些关于“下一个人”的更多信息 - 这是我从一个线程调用顶级窗口上的函数,而不是 Windows 线程。 (这是一个跨平台的应用程序,在Mac上它并不关心你从哪个线程调用这些线程。)这就是导致“死锁”的原因(实际上,我不认为这不是真正的死锁,但还有其他一些“活性丧失”),我想知道是否正是这个问题导致 Visual Studio 2010 拒绝正确显示堆栈。
-- 堆栈错误 --
ntdll.dll!7c90e514()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
user32.dll!7e4299ff()
SlowGold 8(调试版本).exe!juce::Win32ComponentPeer::setPosition(int x, int y) 第 513 行 C++ SlowGold 8(调试版本).exe!008005f9()
编辑: 是的,我看到“没有为 ntdll.dll 加载符号”这一事实,但这不是问题:问题是只有堆栈中的一帧。请参阅下一个堆栈,了解来自同一程序中不同线程的“良好堆栈”的示例。
-- 良好的堆栈--
ntdll.dll!7c90e514()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c90df5a()
kernel32.dll!7c8025db()
kernel32.dll!7c802542()
SlowGold 8 (debug build).exe!juce::WaitableEvent::wait(const int timeOutMillisecs) Line 103 + 0x10 bytes C++
SlowGold 8 (debug build).exe!juce::Thread::wait(const int timeOutMilliseconds) Line 304 C++
SlowGold 8 (debug build).exe!rec::util::thread::Looper<int (__cdecl*)(rec::slow::Instance *),rec::slow::Instance *>::run() Line 24 C++
SlowGold 8 (debug build).exe!juce::Thread::threadEntryPoint() Line 145 C++
SlowGold 8 (debug build).exe!juce::juce_threadEntryPoint(void * userData) Line 156 C++
SlowGold 8 (debug build).exe!juce::threadEntryProc(void * userData) Line 126 + 0x9 bytes C++
SlowGold 8 (debug build).exe!_callthreadstartex() Line 314 + 0xf bytes C
SlowGold 8 (debug build).exe!_threadstartex(void * ptd) Line 297 C
kernel32.dll!7c80b729()
编辑: 你可以在这里看到,即使我没有完整的堆栈,我也有很多来自我自己的代码的帧 - 你可以看到我们从哪里进入线程的顶部,也是我们调用 Microsoft DLL 的地方。
The latest revision of my cross-platform C++ application (using Juce) has what's probably a deadlock or conceivably an unbounded loop in Windows but not Mac and unfortunately we don't have a Windows developer at this time so it's up to me.
I can run the program under Visual Studio 2010 with problems, and then when I hit the "loss of liveness" :-D I use the "Break all" command, which seems to suspend all my threads. Fine and good, and most of the stacks are perfectly reasonable. Unfortunately, several of the threads, including the two I suspect of being in deadlock, don't have usable call stacks.
I perfectly well understand that the "tops" of my stacks won't be there, because I don't have debugging info for e.g. ntdll.dll. But I just seem to get a tiny bit from the middle of the stack.
I'm including one of the bad stacks and one of the good stacks for your perusal. You can see that the good stack traces all the way back to the calling function of the thread, but the bad stack only has a single valid frame.
That frame is legitimate, but I don't know why I can't see the other frames, and it's making my work very difficult.
Any ideas would be appreciated - hope your day has been more productive than mine! :-D
EDIT: Sorry, thought I was very clear above when I pointed out that I knew that the Microsoft symbols were missing, but don't care. The issue is that the stack trace is missing all the frames within my code where I am sure I have debugging symbols.
I actually got past my deadlock, so this isn't a problem right now, but it makes the effect even more puzzling, as I now know that I hadn't e.g. screwed up the call stack somehow.
Now, I do have some more information for "the next guy" - it's that I was calling a function on a top-level Window from a thread was that NOT the windows thread. (This is a cross-platform app, and on the Mac it doesn't care what thread you call these from.) This was what was causing the "deadlock" (actually, I don't think it wasn't really a deadlock, but some other "loss of liveness"), and I wonder if it was this issue that also made Visual Studio 2010 refuse to display the stack correctly.
-- bad stack --
ntdll.dll!7c90e514()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
user32.dll!7e4299ff()
SlowGold 8 (debug build).exe!juce::Win32ComponentPeer::setPosition(int x, int y) Line 513 C++
SlowGold 8 (debug build).exe!008005f9()
EDIT: Yes, I saw the fact that "no symbols were loaded for ntdll.dll" but that's not the issue: the issue is that there's only ONE frame in the stack. See the next stack for an example of a "good stack" from a different thread in the same program.
-- good stack --
ntdll.dll!7c90e514()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c90df5a()
kernel32.dll!7c8025db()
kernel32.dll!7c802542()
SlowGold 8 (debug build).exe!juce::WaitableEvent::wait(const int timeOutMillisecs) Line 103 + 0x10 bytes C++
SlowGold 8 (debug build).exe!juce::Thread::wait(const int timeOutMilliseconds) Line 304 C++
SlowGold 8 (debug build).exe!rec::util::thread::Looper<int (__cdecl*)(rec::slow::Instance *),rec::slow::Instance *>::run() Line 24 C++
SlowGold 8 (debug build).exe!juce::Thread::threadEntryPoint() Line 145 C++
SlowGold 8 (debug build).exe!juce::juce_threadEntryPoint(void * userData) Line 156 C++
SlowGold 8 (debug build).exe!juce::threadEntryProc(void * userData) Line 126 + 0x9 bytes C++
SlowGold 8 (debug build).exe!_callthreadstartex() Line 314 + 0xf bytes C
SlowGold 8 (debug build).exe!_threadstartex(void * ptd) Line 297 C
kernel32.dll!7c80b729()
EDIT: you can see here that even though I don't have the full stack, I have plenty of frames from my own code - you can see where we enter from the top of the thread, and where we call into the Microsoft DLLs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
听起来好像您缺少符号(因为并未给出所有符号),但是,Microsoft 在其符号服务器上分发了大多数符号(并非所有符号)。
注意:我从来没有这样做过。无论如何,请查看 Microsoft 的符号服务器以了解如何执行此操作:http://support .microsoft.com/kb/311503。
It just sounds like you have missing symbols (as not all are given), however, Microsoft distribute most, of not all symbols, on their symbol server.
Note: I have never had to do this. In any case, have a look at Microsoft's symbol server to figure out how to do this here: http://support.microsoft.com/kb/311503.
您需要系统 .dll 的调试符号才能正确遍历堆栈。即使您碰巧在调用堆栈中获得了看似正确的条目,但如果堆栈本身具有过时的数据(例如旧的返回指针),您仍然可能会出现错误的调用堆栈。
由于您使用的是 VS 2010,因此您应该能够右键单击调用堆栈中的任何系统 .dll,并直接从 Microsoft 符号服务器加载符号。您也可以进入工具->选项->调试->让调试器自动执行此操作的符号。
您应该尽可能使用系统 .dll 符号。
You need debug symbols for system .dlls to properly walk the stack. Even if you happen to get seemingly correct entries in the callstack, you still can have erroneous callstacks if the stack itself has stale data (e.g., old return pointers).
Since you are using VS 2010, you should be able to right click on any system .dll in the callstack and load the symbols directly from the Microsoft Symbol Server. You can also go into Tools -> Options -> Debugging -> Symbols to have the debugger do this automatically.
You should always use the system .dll symbols when you can.
2 件事:
1)“清理”解决方案,然后再次构建并在调试模式下运行(确保选择“开始调试” (F5),而不是“开始而不调试”(即 CTRL+F5)
2 )好吧,这些是 Windows API 函数 - 您确定是否存在需要在该级别进行调试的错误堆栈? “坏堆栈”进入 user32.dll,这是 Windows 的 GUI 端。我认为您不需要调试这些堆栈,但我不能确定。
2 things:
1) "Clean" the solution, then build and run in debug mode again (making sure to choose Start Debugging (F5) not "Start Without Debugging" (which is CTRL+F5)
2) Well, those are Windows API functions - are you sure for bad stack that you need to debug at that level? The "bad stack" goes into user32.dll, which is the GUI side of Windows. I don't think you need to debug those stacks, but I can't be sure.
回复有点晚了,但我也遇到了类似的问题,花了我一段时间才找到,就像OP一样,我在SO或Google上找不到任何可以解决问题的内容。我在这里回答是因为这个问题中的场景与我的非常相似,所以谷歌很可能会为其他人找到这个问题。
对于我的问题,我们有一台具有完整堆栈跟踪的 PC,另一台具有不完整的堆栈跟踪。我找到解决方案的方法是使用 Visual Studio 模块窗口(调试菜单 | Windows | 模块)。该窗口告诉您哪些模块已加载,重要的是哪些模块加载了符号。在我的例子中,两台机器都为具有不完整堆栈的 DLL 加载了符号,但关键的是一台机器有一个运行时 DLL,但没有像另一台机器那样加载符号。对我来说,它是 Visual C++ 运行时文件 Msvr110.dll。一旦找到该 DLL 的正确符号文件,就会正确报告完整的堆栈跟踪。
在模块窗口中,您可以右键单击符号状态为无法找到或打开 PDB 文件的模块文件,然后选择符号加载信息...来查看原因符号加载失败的原因,包括尝试的所有搜索路径以及符号与内存中加载的 DLL 版本不匹配时是否会发生符号不匹配。从这里开始,只需从工作 PC 获取 PDB 文件并确保其部署正确即可。
我希望这可以节省其他人一些时间。
This is a bit late for a response but I had a similar issue that took me a while to track down and like the OP I couldn't find anything on SO or Google in general that fixed the problem. I'm answering here because the scenario in this question is very similar to mine so Google is likely to find the question for others.
With my issue we had one PC with the complete stack trace and one with an incomplete stack trace. The way I found the solution was to use the Visual Studio Modules window (Debug menu | Windows | Modules). This window tells you which modules are loaded and importantly which modules have symbols loaded. In my case both machines had symbols loaded for the DLL with the incomplete stack, but critically one machine had a runtime DLL without the symbols loaded where as the other did. For me it was the Visual C++ runtime file Msvr110.dll. Once the correct symbol file was tracked down for this DLL, the full stack trace was reported correctly.
In the Module Window you can right click on a module file with a Symbol status of Cannot find or open the PDB file and select Symbol Load Information... to see the cause of the symbol load failure, including all search paths attempted and if there was a symbol mismatch that would occur if the symbols do not match the version of the DLL you have loaded in memory. From here it's just a matter of getting the PDB file from the working PC and making sure it's deployed correctly.
I hope this saves others some time.