Re: Help: LIBLDAP.DLL makes GPF in ldap_result/ldap_msgdelete

Eric Rosenquist (rosenqui@strataware.com)
Fri, 9 Feb 1996 10:41:31 -0500

On 9 Feb 96 at 13:24, Nils Andreas Thommesen wrote:

> When I try to read the attributes of an entry, I can read them with no error.
> But my problem arises at the *next* search, or rather waiting for the results
> of the next search! Can anybody help me? Am I missing some call to LIBLDAP?
>
> I have not been able to trace the execution into LIBLDAP.DLL, but I can see
> the call stack contains three calls to ldap_result and the last call is to
> ldap_msgdelete when the General Protection Fault occurs.
>
> These are the calls I do to wait for a result:
>
> do
> {
> res = ldap_result( m_current_ld, searchID, 1 , &timeout , &msg);
> if (res == LDAP_RES_ANY)
> break;
> } while (res == 0);
>
> I have been using both zero time to wait, and up to 1/2 seconds, it doesn't matter.
> When I read the attributes, I do this: (simplified)
>
> ldap_search( );
> LDAPMessage *msg,*entry;
> .... a call to the function above that waits for the result ...
> entry = ldap_first_entry( m_current_ld, msg);
> BerElement *ber;
> char *attr;
> char **values;
> for (attr = ldap_first_attribute( m_current_ld, entry, &ber );
> lstrlen(attr) != 0 ; attr =ldap_next_attribute( m_current_ld,
> entry, ber) )
> {
> values = ldap_get_values( m_current_ld, entry, attr);
> ...save each of the values....
> ldap_value_free(values);
> if (attr)
> free (attr);
> }// end of for-loop over all attributes
> if (msg)
> {
> ldap_msgfree(msg);
> msg = NULL;
> }
> if (entry)
> {
> ldap_msgfree(entry);
> entry = NULL;
> }
> ldap_msgdelete(m_current_ld, SearchID); // I have tried without this one, too.
>
> It doesn't matter what I do *after* listing the attributes, it always gives me a GPF,
> for a new "list attributes"-call, or when waiting for the results of a "browse" or a
> "specific search".

Don't call free() for values allocated by the LIBLDAP.DLL - use
ldap_memfree() instead. If you call free(), the block will get merged
back into your application's heap, instead of going back to LIBLDAP.DLL's
heap where it belongs.

You're calling free(attr) to free the attribute name, which is doubly
wrong. If it needed to be freed, you should use ldap_memfree(), but as
per the ldap_first/next_attribute() man page, "The return value should be
treated as if it is a pointer to a static area (i.e., strdup(3) it if
you want to save it)."

Furthermore, ldap_first/next_attribute return a NULL if an error occurs or
the end of the list is reached, so you shouldn't be checking lstrlen(attr)
in your loop.

Eric
---------------------------------------------------------------------
Eric Rosenquist, Strata Software Limited http://www.strataware.com/
Email: rosenqui@strataware.com Tel: 613-591-1922 Fax: 613-591-3485
Quote: I can't fake an interest in this, and I'm an expert at faking
an interest in your kooky projects.
-- Homer to Marge
---------------------------------------------------------------------