FIX: Program Crash when Connecting to Data Source from a DLL

ID: Q118659


The information in this article applies to:


SYMPTOMS

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.


CAUSE

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.


RESOLUTION

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.


STATUS

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