[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: crash in libldap_r with multithreading (ITS#2150)
It appears you are not providing proper serialization of
ldap(3) calls as required by -lldap_r. Please see mailing
list archives for discussions in this area.
Kurt
At 01:03 AM 2002-10-23, peter.vreman@cmg.com wrote:
>Full_Name: Peter Vreman
>Version: 2.0.21 and 2.0.27
>OS: Linux
>URL:
>Submission from: (NULL) (212.136.56.8)
>
>
>Hello,
>
>The following program gives a SIGSEGV, becuase the memory is corrupted
>(malloc/free gives the SIGSEGV). It looks like a racecondition, because the time
>
>before it crashes is different everytime. Running the program in valgrind or
>using any other memory debugger does not help. Also it does not matter it the
>number that is searched is in the LDAP database or not.
>
>Kind regards,
>Peter
>
>
>#include <stdlib.h>
>#include <stdio.h>
>#include <time.h>
>#include <pthread.h>
>#include <ldap.h>
>#include <ldap_features.h>
>
>// #define DEBUG
>
>#define msleep(x) \
> { \
> struct timespec r_ts; \
> r_ts.tv_sec=x/1000; \
> r_ts.tv_nsec=(x%1000)*1000000; \
> nanosleep(&r_ts,NULL); \
> }
>
>static char* m_pc_addr[] = {
> "0651515151",
> "0567000038",
> "0567000037",
> "0651515153",
> "0651515152",
> "0567000039",
> NULL
>};
>
>static void* ld_ldapthread(void* pv_arg);
>
>
>
>void ld_connect(LDAP **po_a_handler)
>{
> int l_stat, l_msg_id;
> LDAPMessage *a_result;
>
> *po_a_handler = ldap_init("127.0.0.1", LDAP_PORT);
> if (*po_a_handler==NULL)
> {
> return;
> }
>
> if((l_msg_id = ldap_simple_bind(*po_a_handler, "cn=root,o=eircom.ie",
>"secret")) == -1)
> {
> printf("Bind LDAP error\n");
> ldap_unbind_s( *po_a_handler );
> *po_a_handler=NULL;
> return;
> }
> l_stat = ldap_result(*po_a_handler,
> l_msg_id,
> 0,
> NULL, /* indefinite wait */
> &a_result);
> if(l_stat != LDAP_RES_BIND)
> {
> printf("LDAP connection refused\n");
> }
> l_stat = ldap_result2error(*po_a_handler, a_result, 0);
>
> if( ldap_msgfree(a_result) == -1)
> {
> *po_a_handler=NULL;
> }
> if(l_stat != LDAP_SUCCESS)
> {
> *po_a_handler=NULL;
> }
>}
>
>
>void ld_response(LDAP* a_ldap_handler)
>{
> int l_stat;
> int l_msgid;
> int l_msgtype;
> LDAPMessage *a_result;
> LDAPMessage *a_msg;
> BerElement *a_ber;
> char **a_values;
> char *a_attr;
>
> l_stat = ldap_result(a_ldap_handler, /* ldap session handler */
> LDAP_RES_ANY, /* Extract any result */
> 1, /* The complete message */
> NULL, /* indefinite wait */
> &a_result); /* Where to save the result */
> l_msgid = ldap_msgid(a_result);
>
> l_stat = ldap_result2error(a_ldap_handler, a_result, 0);
>#ifdef DEBUG
> printf("Parsing LDAP result msgid %d: %s\n",
> l_msgid,
> ldap_err2string(l_stat));
>#endif
>
> if (l_stat != LDAP_SUCCESS)
> {
> /* Error, message is already traced above */
> ldap_msgfree(a_result); /* Free the memory allocated by the
>result */
> return ; /* Send the response back */
> }
>
> l_msgtype = ldap_msgtype(a_result);
> switch(l_msgtype)
> {
> case LDAP_RES_SEARCH_RESULT:
> printf("No entry found for %d\n", l_msgid);
> break;
>
> case LDAP_RES_SEARCH_ENTRY:
> a_msg = ldap_first_entry(a_ldap_handler, a_result);
> if (a_msg == NULL)
> {
> printf("No empty search result\n");
> ldap_msgfree(a_result); /* Free the memory allocated by the
>result */
> return ; /* Send the response back */
> }
> /* Scroll trought attributes to extract the needed ones */
> for ( a_attr = ldap_first_attribute(a_ldap_handler, a_result, &a_ber );
> a_attr != NULL;
> a_attr = ldap_next_attribute(a_ldap_handler, a_result, a_ber))
> {
> a_values = ldap_get_values(a_ldap_handler, a_msg, a_attr);
> if(a_values)
> {
> ldap_value_free(a_values);
> }
> ldap_memfree( a_attr );
> }
> ber_free(a_ber, 0);
> break;
>
> default:
> printf("Unhandled LDAP result %d\n",l_msgtype);
> break;
> }
> ldap_msgfree(a_result);
>
> return;
>}
>
>
>void* ld_sessthread(void* pv_arg)
>{
> char t_filter[100];
> char t_base[100];
> char s_nr[20];
> int l_msgid;
> LDAP *a_ldap_handler;
> pthread_t l_thrd_id;
> pthread_attr_t m_r_pthread_attr;
> int i_addr = 0;
>
> printf("session thread started\n");
>
> ld_connect(&a_ldap_handler);
> if (!a_ldap_handler)
> {
> return NULL;
> }
>
> pthread_attr_init( &m_r_pthread_attr );
> pthread_attr_setdetachstate( &m_r_pthread_attr, PTHREAD_CREATE_DETACHED );
> pthread_create(&l_thrd_id,
> &m_r_pthread_attr,
> &ld_ldapthread,
> a_ldap_handler);
>
> while (1)
> {
>#ifdef DEBUG
> printf("Sending request\n");
>#endif
>
> strcpy(s_nr,m_pc_addr[i_addr]);
>
> i_addr++;
> if (m_pc_addr[i_addr]==NULL)
> {
> i_addr=0;
> }
>
> sprintf(t_base,
> "number=%s,ou=subscribers,o=myorg",
> s_nr);
>
> sprintf(t_filter, "number=*"); /* in this case we should expect only one
>result */
> /* Use syncronious search for one subscriber, it is there or not, should
>be the fastest response from LDAP */
> l_msgid = ldap_search(a_ldap_handler, /* LDAP session
>handle */
> t_base, /* container to
>search */
> LDAP_SCOPE_BASE, /* search entire
>subtree */
> t_filter, /* search filter
>*/
> NULL, /* return all
>attributes */
> 0); /* return both
>attributes and values */
>
> msleep(1);
> }
>
> return NULL;
>}
>
>
>static void* ld_ldapthread(void* pv_arg)
>{
> LDAP* a_ldap_handler = (LDAP*)pv_arg;
>
> printf("ldap thread started\n");
>
> while (1)
> {
> ld_response(a_ldap_handler);
> }
>
> return NULL;
>}
>
>
>int main()
>{
> pthread_t l_thrd_id;
> pthread_attr_t m_r_pthread_attr;
> int i;
>
> for (i=0;i<10;i++)
> {
> pthread_attr_init( &m_r_pthread_attr );
> pthread_attr_setdetachstate( &m_r_pthread_attr, PTHREAD_CREATE_DETACHED
>);
> pthread_create(&l_thrd_id,
> &m_r_pthread_attr,
> &ld_sessthread,
> NULL);
> }
>
>
> while (1)
> {
> msleep(1000000);
> }
>
> return 0;
>}