FIX: Handle Leak Occurs in SQL Server When Service or Application Repeatedly Connects and Disconnects with Shared Memory Network Library (317748)



The information in this article applies to:

  • Microsoft SQL Server 2000 (all editions)

This article was previously published under Q317748

SYMPTOMS

When a service or an application quickly and repeatedly connects to and disconnects from a local Microsoft SQL Server 2000 database, a handle leak may occur in the SQL Server process.

These leaks only occur in the SQL Server 2000 Service Pack 2 (SP2) version of the shared memory network library (Dbmslpcn.dll version 2000.80.534.0).

CAUSE

The handle leaks occur in two locations. The handle leak occurs in the first location because of a missing DeleteCriticalSection function call when a connection is closed. The handle leak occurs in the second location because of event handles that are created repeatedly during the connection process.

RESOLUTION

To resolve this problem, obtain the latest service pack for Microsoft SQL Server 2000. For additional information, click the following article number to view the article in the Microsoft Knowledge Base:

290211 INF: How to Obtain the Latest SQL Server 2000 Service Pack



If you are unable to install the latest service pack, the following fix is available from the Microsoft Download Center:
Q317748.exe


Release Date: OCT-30-2002

For additional information about how to download Microsoft Support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591 How to Obtain Microsoft Support Files from Online Services

Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help to prevent any unauthorized changes to the file.
NOTE: The security patches described in Microsoft Security Bulletins MS02-039, MS02-043, MS02-056 and the original release of the security patch described in MS02-061 (released on October 16, 2002) do not contain the Q317748.exe patch discussed in this knowledge base article. This patch was subsequently discovered to be required to ensure normal operation of SQL Server.

If you have applied any of these security patches and decide to apply the patch from this Knowledge Base article you must answer "no" if prompted to overwrite files to ensure that you do not overwrite files from the security patch.

The re-released security patch for Microsoft Security Bulletin MS02-061 (released on January 26, 2003) includes this fix, and if you have installed this re-released patch, no action is required. The re-released patch is available from the following article in the Microsoft Knowledge Base:

316333 INF: SQL Server 2000 Security Update for Service Pack 2



For more information on the Microsoft Security Bulletins discussed above, please see the following Microsoft Web sites:
Microsoft Security Bulletin MS02-039
Microsoft Security Bulletin MS02-043
Microsoft Security Bulletin MS02-056
Microsoft Security Bulletin MS02-061

WORKAROUND

To work around this problem, use the following methods:
  • Reuse open connections as much as possible instead of opening and closing them frequently.
  • Use a network library other than the shared memory network library.

STATUS

Microsoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article. This problem was first corrected in Microsoft SQL Server 2000 Service Pack 3.

MORE INFORMATION

Steps to Reproduce the Behavior

  1. Copy the following code into a Microsoft Visual C++ console application, and then compile the application:
    #include "stdafx.h"
    
    #import "C:\Program Files\Common Files\System\ado\msado21.tlb" rename("EOF", "adoEOF")
    #include <crtdbg.h>
    
    bool bRunFree = true;
    
    BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType)
    {
        switch (dwCtrlType)
        {
        case CTRL_C_EVENT:
        case CTRL_BREAK_EVENT:
        case CTRL_CLOSE_EVENT:
        case CTRL_LOGOFF_EVENT:
        case CTRL_SHUTDOWN_EVENT:
    		bRunFree = false;
            break;
        default:
            break;
        }
    
        return TRUE;
    }
    
    int main(int argc, char* argv[])
    {
    	_bstr_t sConnectionString = L"Provider=SQLOLEDB;database=Northwind;integrated security=SSPI;server=(local);";
    	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    	COORD coord = { 0, 1 };
    	_bstr_t sEmpty;
    	int nCount = 0;
    
    	printf("Starting, Press CTRL+C to end\n");
    
        if (SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE) == FALSE)
    	{
    		printf("SetConsoleCtrlHandler failed 0x%08X", GetLastError());
    	}
    
    	CoInitialize(NULL);
    
    	while (bRunFree)
    	{
    		ADODB::_ConnectionPtr piConnection;
    		HRESULT hRes = piConnection.CreateInstance(__uuidof(ADODB::Connection));
    
    		if (FAILED(hRes))
    		{
    			printf("CreateInstance failed 0x%08X", hRes);
    		}
    		else
    		{
    			_ASSERTE(piConnection->GetState() == ADODB::adStateClosed);
    			hRes = piConnection->Open(sConnectionString, sEmpty, sEmpty, -1);
    
    			if (FAILED(hRes))
    			{
    				printf("Open failed 0x%08X", hRes);
    				break;
    			}
    
    			_ASSERTE(piConnection->GetState() == ADODB::adStateOpen);
    			piConnection->Close();
    			SetConsoleCursorPosition(hOutput, coord);
    			printf("Connection Opened/Closed %d times\n", ++nCount);
    
    			piConnection = NULL;
    		}
    	}
    
    	CoUninitialize();
    
    	return 0;
    }
    						
  2. Open Task Manager, and then click the Processes tab.
  3. On the View menu, click Select Columns, and then click to select the Handles Count check box to add handles to the columns that are monitored.

    Alternatively, you can use Performance Monitor to record the handle count for the SQL Server process.
  4. Run the code for several minutes. Notice that the count of handles increases steadily.

Modification Type:MinorLast Reviewed:9/27/2005
Keywords:kbHotfixServer kbQFE kbdownload kbSQLServ2000sp3fix kbbug kbfix kbSQLServ2000preSP3fix KB317748 kbAudDeveloper