我的跨平台C ++应用程序的最新版本(使用Juce)可能是一个僵局,或者可能是一个无限循环在Windows但不是Mac,不幸的是我们目前没有Windows开发人员所以这取决于我
我可以在Visual Studio 2010下运行程序遇到问题,然后当我遇到“失去活力”时:-D我使用“Break all”命令,这似乎暂停了我的所有线程。很好,很好,大多数堆栈是完全合理的。不幸的是,有几个线程,包括我怀疑处于死锁的两个线程,没有可用的调用堆栈。
我完全理解我的堆栈的“顶部”不会存在,因为我没有调试信息,例如ntdll.dll中。但我似乎只是从堆栈的中间中得到了一点点。
我包含了一个糟糕的堆栈和一个好的堆栈供你细读。您可以看到好的堆栈一直追溯到线程的调用函数,但坏堆栈只有一个有效的框架。
那个框架是合法的,但我不知道为什么我看不到其他框架,这让我的工作非常困难。
任何想法都会受到赞赏 - 希望你的一天比我的更有成效! :-D
编辑:很抱歉,当我指出我知道微软的符号丢失了,但我不在乎时,我以为我非常清楚。问题是堆栈跟踪缺少我的代码中的所有框架,我确信我有调试符号。
我实际上已经解决了我的僵局,所以现在这不是一个问题,但它让效果更令人费解,因为我现在知道我没有以某种方式搞砸了电话堆栈。
现在,我确实有一些关于“下一个人”的更多信息 - 我从一个线程调用顶层窗口上的函数是不是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的地方。
答案 0 :(得分:2)
听起来你只缺少符号(并非所有符号都有),但是,微软会在符号服务器上分发大部分符号,而不是所有符号。
注意:我从来没有这样做过。无论如何,请查看Microsoft的符号服务器,以了解如何在此处执行此操作:http://support.microsoft.com/kb/311503。
答案 1 :(得分:1)
您需要系统.dll的调试符号才能正确地遍历堆栈。即使您恰好在callstack中获得看似正确的条目,如果堆栈本身具有过时的数据(例如,旧的返回指针),您仍然可能有错误的callstack。
由于您使用的是VS 2010,因此您应该能够右键单击callstack中的任何系统.dll并直接从Microsoft Symbol Server加载符号。你也可以进入工具 - &gt;选项 - &gt;调试 - &gt;让调试器自动执行此操作的符号。
你应该尽可能使用系统.dll符号。
答案 2 :(得分:0)
2件事:
1)“清理”解决方案,然后再次构建并以调试模式运行(确保选择开始调试(F5)而不是“无需调试启动”(即CTRL + F5)< / p>
2)那些是Windows API函数 - 您是否确定是否需要在该级别进行调试? “坏堆栈”进入user32.dll,这是Windows的GUI端。我不认为你需要调试这些堆栈,但我不能确定。
答案 3 :(得分:0)
对于回复来说这有点晚了但是我有一个类似的问题,我花了一段时间来追踪并且喜欢OP我在SO或谷歌上找不到任何解决问题的东西。我在这里回答是因为这个问题的场景与我的非常相似,所以谷歌可能会为其他人找到问题。
在我的问题中,我们有一台PC具有完整的堆栈跟踪,另一台具有不完整的堆栈跟踪。我找到解决方案的方法是使用Visual Studio模块窗口(调试菜单| Windows |模块)。此窗口告诉您加载了哪些模块,重要的是哪些模块加载了符号。在我的情况下,两台机器都为不完整堆栈的DLL加载了符号,但是关键的是一台机器有一个运行时DLL而没有加载符号,而另一台机器加载了。对我来说,它是Visual C ++运行时文件Msvr110.dll。一旦跟踪了此DLL的正确符号文件,就会正确报告完整的堆栈跟踪。
在模块窗口中,您可以右键单击符号状态为找不到或打开PDB文件的模块文件,然后选择符号加载信息... 到查看符号加载失败的原因,包括尝试的所有搜索路径以及符号不匹配,如果符号与您在内存中加载的DLL版本不匹配,则会发生符号不匹配。从这里开始,只需从工作PC获取PDB文件并确保其正确部署即可。
我希望这能节省一些时间。