Visual Studio 调试 C++ 中的错误

发布于 2024-07-13 01:29:33 字数 486 浏览 7 评论 0原文

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

ClassNameFromDll blah;

当它到达这里时,我得到这个异常:

Unhandled exception at 0x78a3f623 (mfc90ud.dll) in MTGO SO Bot.exe: 0xC0000005:读取位置 0xf78e4568 时发生访问冲突。

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

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

For some reason the integrated debugger is causing an error as soon as I make reference to a third party vendor's dll class. This same code runs when it is built and ran as a release, stand alone. The two properties for debug and release should be the same as I have not really altered them. I added the lib file to the path for both builds. I simply have:

ClassNameFromDll blah;

When it gets to here, I get this exception:

Unhandled exception at 0x78a3f623 (mfc90ud.dll) in MTGO SO Bot.exe:
0xC0000005: Access violation reading location 0xf78e4568.

It occurs in: afxtls.cpp, line 252.

This is an MFC app, but I am not really using any MFC other than a very simple gui which fires off an event that is all win32. I am using Visual Studio 2008 Express.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泪之魂 2024-07-20 01:29:33

进行心理调试

事实上,它在发布模式下运行良好,在调试模式下崩溃,这让我相信您已经以​​某种方式成功地引用了该 DLL (mfc90u.dll) 的发布版本,而不是引用库本身并允许链接器决定导入哪个版本。

您可能不会在该应用程序中使用 MFC 进行任何操作,但如果将其构建为 MFC 应用程序,则无论您是否需要,您都将获得所有 MFC 内容(这意味着您还必须解决 MFC 依赖问题并交付MFC DLL 与您的应用程序)。

engaging psychic debugging

The fact that it runs in release mode fine and crashes in debug mode leads me to believe that you've somehow managed to reference, specifically, the release version of that DLL (mfc90u.dll), rather than referencing the library itself and allowing the linker to decide which version to import.

You may not be using MFC for anything in this app, but if it's building as an MFC application, you will get all of the MFC stuff whether you want it or not (which means you also have to solve the MFC dependency problem and ship the MFC DLLs with your app).

淡淡的优雅 2024-07-20 01:29:33

查看我的 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 插槽的初始化是您的责任还是第 3 方 DLL 的责任。

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

Looking at the atltls.cpp file from my VC9 install, the crash is occurring here:

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
    // ...
}

So the reason the crash doesn't occur in release build is because the ASSERT() is a no-op in that build. I'm not familiar with ATL's use of thread local storage, but this assertion indicates that something is asking for a value in a slot where nothing has been stored yet.

Whether the initialization of that TLS slot is your responsibility or the 3rd party DLL's responsibility, I don't know.

It looks like GetThreadValue() has some additional protections such that it'll return a NULL pointer in the release build for an uninitialized slot (though I'm not sure that this would be guaranteed) - I'd bet that the 3rd party DLL relies on that behavior (ie., it checks for a NULL return) so no crash occurs in release builds. Note that the vendor might be using the CThreadSlotData class indirectly (the stack trace would give a clue about this), so they might not be aware of its expectations.

↙厌世 2024-07-20 01:29:33

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

如果第 3 方 DLL 仍然受到供应商的积极支持,那么您应该做的第一件事就是看看是否可以使用一个非常简单的程序出现相同的问题,您可以将其发送给供应商并要求他们修复它。

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

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

即使您没有第 3 方 DLL 的源代码,我认为最好的做法是跟踪 ClassNameFromDll 的构造函数,以尝试找出问题所在。 它可能有助于比较调试版本与发布版本中的指令路径。

MFC 源代码与 MSVC 一起分发(可能不是 Express 版本,但我认为与所有其他版本一起),因此当您进入 MFC DLL 的代码时,您可能会发现该源代码对于帮助弄清楚发生了什么非常有用。

Do you have a stack trace you can post? It might have some helpful information.

If the 3rd party DLL is still actively supported by the vendor, then the first thing you should do is see if you can have the same problem occur with a very simple program that you can send to the vendor and ask them to fix it.

If the vendor is not available or responsive enough:

If you have source of the 3rd party DLL and can easily build your own version, you have probably the best way to debug this (short of getting the vendor to support you). Even if you cannot easily build a source-debuggable DLL, you can trace into the constructor's assembly instructions and use the source as a map to help you understand what's going on.

Even if you don't have source for the 3rd party DLL then I think the best course of action is to trace through the constructor for ClassNameFromDll to try to figure out whats going wrong. It might help to compare the instructions path in the Debug build vs. the Release build.

MFC source is distributed with MSVC (probably not with the Express version, but I think with all other versions) so when you get in to the MFC DLL's code you might find the source to be useful in helping to figure out what's going on.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文