Visual Studio中的Visual Studio调试错误

时间:2009-02-05 15:40:57

标签: c++ visual-studio winapi debugging unhandled-exception

出于某种原因,只要我引用第三方供应商的dll类,集成调试器就会导致错误。这个代码在构建并作为发行版运行时运行,独立运行。调试和发布的两个属性应该与我没有真正改变它们的相同。我将lib文件添加到两个构建的路径中。我只是:

ClassNameFromDll blah;

当它到达这里时,我得到了这个例外:

MTGO SO Bot.exe中0x78a3f623(mfc90ud.dll)的未处理异常: 0xC0000005:访问冲突读取位置0xf78e4568。

它出现在:afxtls.cpp,第252行。

这是一个MFC应用程序,但我并没有真正使用任何MFC,除了一个非常简单的gui,它会触发一个全部为win32的事件。我正在使用Visual Studio 2008 Express。

3 个答案:

答案 0 :(得分:2)

查看我的VC9安装中的atltls.cpp文件,崩溃发生在这里:

inline void* CThreadSlotData::GetThreadValue(int nSlot)
{
    EnterCriticalSection(&m_sect);
    ASSERT(nSlot != 0 && nSlot < m_nMax);
    ASSERT(m_pSlotData != NULL);
    ASSERT(m_pSlotData[nSlot].dwFlags & SLOT_USED);   // <== crash
    // ...
}

因此,在发布版本中没有发生崩溃的原因是因为ASSERT()在该版本中是无操作的。我不熟悉ATL对线程本地存储的使用,但是这个断言表明某些东西在一个尚未存储任何内容的插槽中要求一个值。

我不知道该TLS插槽的初始化是您的责任还是第三方DLL的责任。

看起来GetThreadValue()有一些额外的保护措施,它会在未初始化的插槽的发布版本中返回一个NULL指针(虽然我不确定这是否可以保证) - 我敢打赌第三方DLL依赖于该行为(即,它检查NULL返回),因此在发布版本中不会发生崩溃。请注意,供应商可能间接使用CThreadSlotData类(堆栈跟踪会给出一个关于此的线索),因此他们可能不会意识到它的期望。

答案 1 :(得分:1)

进行心理调试

它在发布模式下运行良好并且在调试模式下崩溃的事实让我相信你已经设法引用,特别是该DLL的发布版本(mfc90u.dll),而不是引用库本身并允许链接器决定导入哪个版本。

您可能没有在此应用程序中使用MFC,但如果它正在构建为MFC应用程序,您将获得所有MFC的东西,无论您是否需要它(这意味着您还必须解决MFC依赖性问题并使用您的应用程序发送MFC DLL。

答案 2 :(得分:0)

你有可以发布的堆栈跟踪吗?它可能有一些有用的信息。

如果供应商仍然主动支持第三方DLL,那么您应该做的第一件事就是看一个非常简单的程序是否会出现同样的问题,您可以将该程序发送给供应商并要求他们修复它

如果供应商不够用或响应不够:

如果你有第三方DLL的源代码并且可以轻松构建自己的版本,那么你可能有最好的方法来调试它(不是让供应商支持你)。即使您无法轻松构建源代码可调试的DLL,也可以跟踪构造函数的汇编指令并将源代码用作映射,以帮助您了解正在发生的事情。

即使你没有第三方DLL的源代码,我认为最好的做法是跟踪ClassNameFromDll的构造函数,试图弄清楚什么是错误的。它可能有助于比较Debug构建与Release构建中的指令路径。

MFC源是与MSVC一起发布的(可能不是Express版本,但我认为与所有其他版本一起使用)所以当你进入MFC DLL的代码时,你可能会发现源代码有助于弄清楚发生了什么上。