Hi ,
We are using Novell NDS and Netscape ldap sdk.
I seem to be having memory leaks in the Netscape's ldap api's. I am
using the ldap_memfree's and ldap_ber_free's properly. I have checked
and rechecked my code. I ran boundschecker and purify on my code and
both show leak in ldap dll. Here's the output from purify:
MLK: Memory leak of 6360 bytes from 13 blocks allocated in ber_init
Distribution of leaked blocks
Allocation location
calloc [msvcrt.dll]
ber_init [NSLDAPSSL32V41.dll]
??? [ip=0x03361e30]
CeDocsCore::get_IeDocsUsers(IeDocsUsers * *)
[eDocsCore.cpp:1082]
CeDocsCore::get_IeDocsUser(WORD *,IeDocsUser * *)
[eDocsCore.cpp:1471]
CeDocsCore::PopulateContentServers(WORD *)
[eDocsCore.cpp:3456]
CeDocsCore::Connect(long,WORD *,WORD *,WORD *)
[eDocsCore.cpp:761]
DispCallFunc [oleaut32.dll]
VarBstrFromDec [oleaut32.dll]
MLK: Memory leak of 440 bytes from 2 blocks allocated in
ldap_x_hostlist_statusfree
Distribution of leaked blocks
Allocation location
malloc [msvcrt.dll]
ldap_x_hostlist_statusfree [NSLDAPSSL32V41.dll]
DispCallFunc [oleaut32.dll]
VarBstrFromDec [oleaut32.dll]
ATL::CComTypeInfoHolder::Invoke(IDispatch *,long,_GUID
const&,DWORD,WORD,tagDISPPARAMS *,tagVARIANT *,tagEXCEPINFO *,UINT *)
[atlcom.h:3276]
There are many such leaks. Everything pointing to either ber_init
(mostly) or ldap_x_hostlist_statusfree.
Any reason why ?
Here is one part of the code that we are using : ( no multithreading)
The wrapper that you see is just there for trying the LDAP reconnect
logic. I turned that off by using the #define (i.e to use the base
API's ) and still got the same leaks. The code does not reach any
exception conditions. ( I know I am missing some memory free's in case
of exceptions, but....) .
Thanks for your help,
Rashed bohra.
STDMETHODIMP CeDocsCoverageGroups::Load()
{
HRESULT hr = S_OK;
char *attrs[3];
attrs[0] = EDOCS_ATTR_FULLNAME;
attrs[1] = NULL;
_EDOCS_TRY
(IDS_ERR_COVERAGEGROUPS_LOAD,IDS_ERR_COVERAGEGROUPS_LOAD_OTHER)
int nRetCode = eDocs_ldap_search_s(pSystemSettings-
>m_pConnectionHandle, pSystemSettings->m_sCoverageGroupsBase.c_str(),
LDAP_SCOPE_ONELEVEL, pSystemSettings->m_sSearchFilter.c_str(), attrs,
0, &pSystemSettings->m_pLdapRes);
if(nRetCode != LDAP_SUCCESS)
{
_EDOCS_THROW(__LINE__ - 3)
}
int iCnt = eDocs_ldap_count_entries(pSystemSettings-
>m_pConnectionHandle, pSystemSettings->m_pLdapRes);
if(iCnt == -1)
{
_EDOCS_THROW(__LINE__ - 3)
}
else
if(iCnt == 0)
{
return hr;
}
CComPtr <IeDocsCoverageGroupConstruct>
spIeDocsCoverageGroupConstruct;
hr = CoGetClassObject
(CLSID_eDocsCoverageGroup,CLSCTX_SERVER,NULL,IID_IeDocsCoverageGroupCons
truct,reinterpret_cast <void **> (&spIeDocsCoverageGroupConstruct));
if ( FAILED (hr) )
{
_EDOCS_COM_THROW(__LINE__ - 3)
}
for (int i=1 ; i <= iCnt; i++ )
{
CComPtr <IeDocsCoverageGroupScript>
spIeDocsCoverageGroupScript;
hr = spIeDocsCoverageGroupConstruct-
>CreateCoverageGroupFromLdap
(IID_IeDocsCoverageGroupScript,reinterpret_cast <IUnknown **>
(&spIeDocsCoverageGroupScript));
if ( FAILED (hr) ) return hr;
CComBSTR Dn;
CComPtr <IeDocsCoverageGroup> pCovGrp;
spIeDocsCoverageGroupScript->get_IeDocsCoverageGroup
(&pCovGrp);
pCovGrp->get_DN(&Dn);
m_cCoverageGroupScripts[Dn] =
spIeDocsCoverageGroupScript;
}
pSystemSettings->m_bFirstEntry = true;
eDocs_ldap_msgfree(pSystemSettings->m_pLdapRes);
pSystemSettings->m_pLdapRes = NULL;
_EDOCS_ALL_CATCH
return hr;
}
STDMETHODIMP CeDocsCoverageGroupCO::CreateCoverageGroupFromLdap(REFIID
a_riid, IUnknown ** ppCovGrpLdap)
{
HRESULT hr = S_OK;
if (ppCovGrpLdap == NULL)
return E_POINTER;
*ppCovGrpLdap = NULL;
_EDOCS_TRY(IDS_ERR_COVERAGEGROUP,IDS_ERR_COVERAGEGROUP_OTHER)
//Get the CoverageGroup entry from LDAP
if(pSystemSettings->m_bFirstEntry)
{
if((pSystemSettings->m_pLdapRes = eDocs_ldap_first_entry
(pSystemSettings->m_pConnectionHandle, pSystemSettings->m_pLdapRes)) ==
NULLMSG)
{
_EDOCS_THROW(__LINE__ - 2)
}
pSystemSettings->m_bFirstEntry = false;
}
else
{
if((pSystemSettings->m_pLdapRes = eDocs_ldap_next_entry
(pSystemSettings->m_pConnectionHandle, pSystemSettings->m_pLdapRes)) ==
NULLMSG)
{
_EDOCS_THROW(__LINE__ - 2)
}
}
hr = CreateInstance (NULL, a_riid, reinterpret_cast <void
**> (ppCovGrpLdap));
if ( FAILED (hr) )
{
_EDOCS_COM_THROW(__LINE__ - 3)
}
CComPtr <IeDocsCoverageGroupInitialize>
spIeDocsCoverageGroupInitialize;
hr = (*ppCovGrpLdap)->QueryInterface
(IID_IeDocsCoverageGroupInitialize,reinterpret_cast <void **>
(&spIeDocsCoverageGroupInitialize));
ATLASSERT (SUCCEEDED (hr));
hr = spIeDocsCoverageGroupInitialize->InitFromLdap ();
_EDOCS_ALL_CATCH
return hr;
}
STDMETHODIMP CeDocsCoverageGroup::InitFromLdap()
{
HRESULT hr = S_OK;
BerElement* BerEl;
char* pcAttr=NULL;
char* pcDn = NULL;
string sConvertedOutPut;
_EDOCS_TRY(IDS_ERR_COVERAGEGROUP,IDS_ERR_COVERAGEGROUP_OTHER)
pcDn = eDocs_ldap_get_dn(pSystemSettings-
>m_pConnectionHandle,pSystemSettings->m_pLdapRes);
if(pcDn == NULL)
{
_EDOCS_THROW(__LINE__ - 3)
}
ConvertFromUTF8(pcDn,sConvertedOutPut);
m_DN = sConvertedOutPut.c_str();
eDocs_ldap_memfree(pcDn);
for(pcAttr = eDocs_ldap_first_attribute(pSystemSettings-
>m_pConnectionHandle,pSystemSettings->m_pLdapRes, &BerEl);
pcAttr != NULL;
pcAttr = eDocs_ldap_next_attribute(pSystemSettings-
>m_pConnectionHandle,pSystemSettings->m_pLdapRes, BerEl))
{
if(!strcmp(pcAttr,EDOCS_ATTR_FULLNAME))
{
char ** ppcVals;
ppcVals = eDocs_ldap_get_values(pSystemSettings-
>m_pConnectionHandle,pSystemSettings->m_pLdapRes, pcAttr);
if(ppcVals != NULL)
{
ConvertFromUTF8(ppcVals
[0],sConvertedOutPut);
m_Name =
sConvertedOutPut.c_str();
}
eDocs_ldap_value_free(ppcVals);
}
eDocs_ldap_memfree(pcAttr);
}
if(BerEl != NULL)
{
// Also tried ber_free here no changes
ldap_ber_free(BerEl, 0);
}
_EDOCS_ALL_CATCH
return S_OK;
}
BOOL CeDocsErrorHandler::TryLdapReconnect()
{
m_ldapRetCode = eDocs_ldap_get_lderrno(pSystemSettings-
>m_pConnectionHandle, NULL, NULL);
if((m_ldapRetCode == LDAP_SERVER_DOWN) || (m_ldapRetCode ==
LDAP_CONNECT_ERROR))
{
if(ldap_simple_bind_s( pSystemSettings-
>m_pConnectionHandle,
pEDocsException->m_pszLoggedOnUserUTF8,
pEDocsException->m_pszPassword) == LDAP_SUCCESS)
return true;
}
return false;
}
char ** LDAP_CALL eDocs_ldap_get_values( LDAP *ld, LDAPMessage
*entry,const char *target )
{
#ifdef LDAP_RECONNECT_ENABLE
char** ppcReturn;
ppcReturn = ldap_get_values( ld,entry,target );
if(ppcReturn == NULL)
{
if(pEDocsException->TryLdapReconnect())
{
return ldap_get_values( ld,entry,target );
}
else
{
return ppcReturn;
}
}
else
{
return ppcReturn;
}
#else
return ldap_get_values( ld,entry,target );
#endif
}
STDMETHODIMP CeDocsCore::Connect(LONG eDocsCoreVersion,BSTR Server,
BSTR UserName, BSTR Password)
{
// TODO: Add your implementation code here
HRESULT hr = S_OK;
int iProtocolVersion = PROTOCOL_VERSION;
_EDOCS_TRY(IDS_ERR_CONNECT,IDS_ERR_CONNECT_OTHER)
// Get eDocsCoreVersion from the Resource
//LoadString(_Module.m_hInst,IDS_ERR_UNHANDLED_LOGFILE,
szErrorString,EDOCS_ERRORBUF_SIZE);
// Set the user Dn for Error Reporting
pEDocsException->m_pszLoggedOnUser = new char[strlen
(_com_util::ConvertBSTRToString(UserName))+1];
strcpy(pEDocsException-
>m_pszLoggedOnUser,_com_util::ConvertBSTRToString(UserName));
string sLoggedUser;
ConvertToUTF8(pEDocsException->m_pszLoggedOnUser,sLoggedUser);
pEDocsException->m_pszLoggedOnUserUTF8 = new char
[sLoggedUser.length()+1];
strcpy(pEDocsException->m_pszLoggedOnUserUTF8,sLoggedUser.c_str
());
pEDocsException->m_pszPassword = new char[strlen
(_com_util::ConvertBSTRToString(Password))+1];
strcpy(pEDocsException-
>m_pszPassword,_com_util::ConvertBSTRToString(Password));
pSystemSettings->m_bFirstEntry = true;
pSystemSettings->m_pConnectionHandle = ldap_init
(_com_util::ConvertBSTRToString(Server), LDAP_PORT);
pSystemSettings->m_peDocsCore = this;
if(pSystemSettings->m_pConnectionHandle == NULL)
{
_EDOCS_THROW(__LINE__ - 4)
}
else
{
#ifdef LDAP_RECONNECT_ENABLE
if(ldap_set_option(NULL, LDAP_OPT_RECONNECT,
LDAP_OPT_ON) != LDAP_SUCCESS)
{
_EDOCS_THROW(__LINE__ - 2)
}
else
{
#endif
if(eDocs_ldap_simple_bind_s( pSystemSettings-
>m_pConnectionHandle,
pEDocsException->m_pszLoggedOnUserUTF8,
pEDocsException->m_pszPassword) != LDAP_SUCCESS)
{
_EDOCS_THROW(__LINE__ - 2)
}
else
{
if(eDocs_ldap_set_option(NULL,
LDAP_OPT_PROTOCOL_VERSION, &iProtocolVersion) != LDAP_SUCCESS)
{
_EDOCS_THROW(__LINE__ - 2)
}
else
{
pSystemSettings->Initialize();
}
}
#ifdef LDAP_RECONNECT_ENABLE
}
#endif
}
PopulateContentServers(UserName);
_EDOCS_ALL_CATCH
return hr;
}
Sent via Deja.com
http://www.deja.com/