FIX: Program Crash when Connecting to Data Source from a DLLID: Q118659
|
A program may crash if it calls a DLL function that creates and opens a CDatabase object. This happens when two applications share the same _USRDLL DLL. It can also happen when two applications are using the _AFXDLL version of the MFC database code MFCD250.DLL or MFCD250D.DLL.
The MFC code uses a global static variable called "henvAllConnections" to store the ODBC environment handle (HENV), which is used by several of the ODBC API functions. The variable is defined in DBCORE.CPP as follows:
HENV CDatabase::henvAllConnections = NULL;
This HENV variable is assigned when the first CDatabase object is created.
All subsequent CDatabase objects use this same variable. This design does
not work because, in the case of a DLL where a CDatabase object is created,
the handle stored in henvAllConnections is used for all CDatabase objects
created by all applications that call the DLL's function. ODBC allocates
the memory associated with an HENV to the task. Therefore, the memory
associated with the henvAllConnections handle belongs to the first
application that called the DLL's function and created the first CDatabase.
When the application goes away, so does the memory associated with the
HENV. All other applications with CDatabases open that were created in the
DLL will most likely crash.
Make sure that only one application is using the DLL or let only one
application at a time call the DLL's function and create a CDatabase
object. In the latter case, if an application calls the DLL's function to
create a CDatabase, it must delete the CDatabase before letting another
application call the DLL's function to create another CDatabase object.
Another approach is to modify the code in the DBCORE.CPP file so that the
code stores and uses an HENV for each task. You can use the Windows API
function GetCurrentTask() to associate a HENV with a specific task handle.
You can modify the code so that every time a CDatabase is created, the code
checks to see whether an HENV has been allocated and associated with the
current task. If no HENV has been allocated, the modified CDatabase object
allocates and associates it. You then need to create additional code that
replaces all references to henvAllConnections with a function call that
retrieves the correct HENV for the current task. Another technique, if it
is important to have all database code in one central location, is to
create an application that acts as a DDE or OLE server. The server can
query the database and return results to your application.
Microsoft has confirmed this to be a bug in the MFC for Windows, version 2.5. This bug was corrected in MFC 2.51, included in Visual C++ version 1.51.
Additional query words: 1.50 2.50 ODBC GPF fault hang
Keywords : kb16bitonly kbDatabase kbMFC kbODBC kbVC
Version : 1.50
Platform : WINDOWS
Issue type :
Last Reviewed: July 29, 1999