Entrar

CORRECÇÃO: Vazamento de memória no driver ODBC Jet com SQL_NUMERIC ou SQL_C_BINARY dados

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.

273772
Este artigo foi arquivado. É oferecido "como está" e não será mais atualizado.
Sintomas
Quando você chamar a função SQLBindParameter no driver ODBC Jet, e quando você vincula a um tipo de dados SQL do SQL_NUMERIC ou quando você vincula SQL_C_BINARY a SQL_WCHAR, ocorre um vazamento de memória.

Se você usar o Monitor de desempenho (PerfMon) para bytes particulares para o processo de inspeção, você vê uma memória gradual mas estável aumentar e a memória não é liberada quando as instruções ou conexões fechar.
Causa
Buffers são usados no driver ODBC Jet para ajudar a converter os tipos de dados ODBC parâmetro tipos de dados nativo para o mecanismo de banco de dados Jet. Esses buffers são referenciados através de ponteiros mantidos no identificador de instrução, como parte de descritores de parâmetro (IPDs).

Normalmente, o código verifica se o ponteiro já faz referência a um buffer de memória válido e, em seguida, reutiliza o buffer se ele existir. No entanto, ao vincular um tipo de dados SQL_NUMERIC, ou ao ligar SQL_C_BINARY a SQL_WCHAR, nova memória é alocada e atribuída ao ponteiro sem verificação-lo primeiro e o valor anterior será substituído.
Resolução
Esse problema é corrigido no service packs mais recentes para o Windows 2000 e MDAC 2.5.
  • Para resolver esse problema, obtenha o service pack mais recente para o Windows 2000. Para obter informações adicionais, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
    260910Como obter o Service Pack mais recente do Windows 2000
  • Para resolver esse problema, obtenha o service pack mais recente para o Microsoft Data Access Components 2.5. Para obter informações adicionais, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
    293312INFO: Como obter o último MDAC 2.5 Service Pack
A versão em inglês dessa correção deve ter os seguintes atributos de arquivo ou posteriores:
   Date        Version       Size              File name       ---------------------------------------------------------------------   09/13/00    4.0.5708.0    270,608 bytes    Odbcjt32.dll   09/14/00    1.10.101.0    295,696 bytes    Q273772_W2K_SP2_x86_en.EXE				
Observação : esse hotfix requer Microsoft Data Access Components (MDAC) 2.5 Service Pack 1 (SP1) ou posterior, devido às dependências em outros arquivos do introduzido com o MDAC 2.5 SP1. Não há nenhuma correção disponíveis que você pode aplicar diretamente para o MDAC 2.5.

Para instalar esse hotfix em uma plataforma Microsoft Windows 2000, execute o pacote de instalador de hotfix (Q273772_W2K_SP2_x86_en.EXE). Embora o hotfix se não for dependente de plataforma, o hotfix de instalador foi projetado para ser executado somente em plataformas Windows 2000 e não será executado no Microsoft Windows NT 4.0, Microsoft Windows 95 ou plataformas Microsoft Windows 98. MDAC contém arquivos de arquivo protegido do sistema e você só pode substituir esses arquivos, um instalador do hotfix assinadas digitalmente no Windows 2000. O arquivo de hotfix autônomo é fornecido também para que você pode copiar esse arquivo diretamente para plataformas Windows NT 4.0, Windows 95 ou Windows 98.


SOLUÇÃO ALTERNATIVA

Não há nenhuma solução alternativa para esse problema.
Situação
A Microsoft confirmou que este é um problema nos produtos da Microsoft listados no começo deste artigo. Esse problema foi corrigido primeiro no Microsoft Data Access Components 2.5 Service Pack 2 e Microsoft Windows 2000 Service Pack 2.
Mais Informações
Se você examinar a memória para o processo periodicamente enquanto executa o processo, você verá um número crescente de 0 x 100000 (1048576) alocações de byte. Se o processo continuar a executar, o processo eventualmente fica sem memória e pára de responder (trava) ou falha.

Etapas para reproduzir o problema

  1. Copie o código a seguir em um aplicativo de console do Microsoft Visual C++ e, em seguida, compile o código. Por favor, observe que talvez seja necessário alterar o nome de fonte de dados, identificação de usuário e a senha.
    #include <windows.h>#include <sql.h>#include <sqlext.h>#include <tchar.h>#include <stdlib.h>#include <stdio.h>#define LEAK_NUMERIC 1		//Use this to determine NUMERIC or BINARY leakvoid HandleError(SQLHANDLE	hHandle, SQLSMALLINT hType, RETCODE RetCode){	SQLSMALLINT	iRec = 0;	SQLINTEGER	iError;	TCHAR		szMessage[1000];	TCHAR		szState[SQL_SQLSTATE_SIZE];	if (RetCode == SQL_INVALID_HANDLE)	{		fprintf(stderr,"Invalid handle!\n");		return;	}	while (SQLGetDiagRec(hType,			 hHandle,			 ++iRec,			 (SQLCHAR *)szState,			 &iError,			 (SQLCHAR *)szMessage,			 (SQLSMALLINT)(sizeof(szMessage) / sizeof(TCHAR)),			 (SQLSMALLINT *)NULL) == SQL_SUCCESS)	{		fprintf(stderr,TEXT("[%5.5s] %s (%d)\n"),szState,szMessage,iError);	}}char* szConnStringIn = "Driver={Microsoft Access Driver (*.mdb)};DBQ=E:\\JetLeak\\TestDatabase.mdb";char* szDropTable = "DROP TABLE LeakTable";//char* szInsertStatement = "INSERT INTO LeakTable VALUES (?)";char* szSelectStatement = "SELECT * FROM LeakTable WHERE val1 = ?";const int nParamCount = 1; #if LEAK_NUMERICchar* szCreateTable = "CREATE TABLE LeakTable (val1 long)";#elsechar* szCreateTable = "CREATE TABLE LeakTable (val1 varchar(10))";#endifvoid main(int argc, char* argv[]){	SQLHENV henv;	SQLHDBC hdbc;	SQLHSTMT hstmt;	SQLRETURN nstatus;	char szConnStringOut[1024];	SQLSMALLINT cbConnOut;	SQLINTEGER status[nParamCount];#if LEAK_NUMERIC	SQLCHAR szParam[nParamCount][10] = {"12345"};#else	BYTE szParam[nParamCount][10] = {0x31,0x33,0x34,0x39};#endif    	//Not checking the return codes in some cases for clarity.		nstatus = SQLAllocHandle(SQL_HANDLE_ENV,NULL,&henv);	nstatus = SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,(SQLPOINTER) SQL_OV_ODBC3,0);	nstatus = SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc);	nstatus = SQLDriverConnect(hdbc,			NULL,			(SQLCHAR*) szConnStringIn,			SQL_NTS,			(SQLCHAR*) szConnStringOut,			sizeof (szConnStringOut),			&cbConnOut,			SQL_DRIVER_COMPLETE);								if (nstatus != SQL_SUCCESS && nstatus != SQL_SUCCESS_WITH_INFO)	{		HandleError(hdbc,SQL_HANDLE_DBC,nstatus);		return;	}	nstatus = SQLAllocHandle(SQL_HANDLE_STMT,hdbc,&hstmt);		nstatus = SQLExecDirect(hstmt, (SQLCHAR*) szDropTable, SQL_NTS);	nstatus = SQLExecDirect(hstmt, (SQLCHAR*) szCreateTable, SQL_NTS);	if (!SQL_SUCCEEDED(nstatus))	{		HandleError(hstmt,SQL_HANDLE_STMT,nstatus);	}	int i;	//only one parameter in this case	for (i=0; i < nParamCount; i++)	{		status[i] = SQL_NTS;#if LEAK_NUMERIC		nstatus = SQLBindParameter(hstmt,			i+1,			SQL_PARAM_INPUT,			SQL_C_CHAR,				SQL_NUMERIC, 			10, 			0,			szParam[i],			10,			&status[i]);#else		nstatus = SQLBindParameter(hstmt,			i+1,			SQL_PARAM_INPUT,			SQL_C_BINARY,				SQL_WCHAR,			10, 			0,			szParam[i],			10,			&status[i]);#endif			}	nstatus = SQLPrepare(hstmt,(SQLCHAR*) szSelectStatement, SQL_NTS);	if (nstatus != SQL_SUCCESS)	{		HandleError(hstmt,SQL_HANDLE_STMT,nstatus);	}	for (i=0; i < 100000; i++)	{		if (i % 100 == 0)		{			printf("Selected %d times\n", i);			//printf("Inserted %d records\n", i);			Sleep(100);		}		nstatus = SQLExecute(hstmt);		if (nstatus != SQL_SUCCESS)		{			HandleError(hstmt,SQL_HANDLE_STMT,nstatus);		}		SQLFreeStmt(hstmt, SQL_CLOSE);	}	nstatus = SQLExecDirect(hstmt, (SQLCHAR*) "DELETE FROM LeakTable", SQL_NTS);	if (nstatus != SQL_SUCCESS)	{		HandleError(hstmt,SQL_HANDLE_STMT,nstatus);	}	SQLFreeStmt(hstmt, SQL_CLOSE);	SQLDisconnect(hdbc);}						
    Observação : você pode usar a constante LEAK_NUMERIC para demonstrar o SQL_NUMERIC ou SQL_C_BINARY vazamento.
  2. Crie um novo banco de Microsoft Access dados em branco como especificado pela localização sua seqüência de conexão.
  3. Iniciar a execução do código e use desempenho do sistema para observar o contador Private Bytes para o processo.

    Observe que o contador Private Bytes aumenta com firmeza enquanto o código está sendo executado.
Jet odbc driver odbcjt32.dll vazamento sql_numeric sql_c_binary sqlbindparameter parâmetros de memória

Aviso: Este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 273772 - Última Revisão: 01/10/2015 12:49:10 - Revisão: 2.2

  • Driver Microsoft Open Database Connectivity para Access 4.0
  • Microsoft Data Access Components 2.5
  • Microsoft Data Access Components 2.5 Service Pack 1
  • kbnosurvey kbarchive kbmt kbhotfixserver kbqfe kbbug kbfix kbjet kbmdac250sp2fix kbwin2000presp2fix KB273772 KbMtpt
Comentários