views:

1416

answers:

3

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.

+1  A: 

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).

DannySmurf
Heh, maybe I should just take all that code and put it back into straight c++ project? All I needed was a simply gui: 1 textarea box, 1 button, 1 event from the button pressed.
Zombies
Might be best. MFC is a fairly heavy thing to import just for one window.
DannySmurf
"psychic debugging" that's a good one..
Naveen
+1 for raymond chen's pyschic debugging!
cbrulak
I figured someone would get that eventually.
DannySmurf
A: 

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.

Michael Burr
The dll in question is tessdll.dll. It works fine when I run the application from a release build.
Zombies
+1  A: 

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.

Michael Burr