From: Azat Khuzhin Date: Sat, 20 Oct 2018 23:50:04 +0000 (+0300) Subject: Fix an error for debug locking in dns/getaddrinfo_race_gotresolve X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=09c74f71217bb6c614b8597041aacf830160f3a0;p=libevent Fix an error for debug locking in dns/getaddrinfo_race_gotresolve When there is no /etc/services file evdns_getaddrinfo() will fail (with service="ssh") and hence it will go to then "end" label with locked rp.lock which in case of debug locking checks will bail with: [err] ../evthread.c:220: Assertion lock->count == 0 failed in debug_lock_free So add rp.locked flag, and unlock the lock before freeing it if it is in locked state. And here is how you can reproduce the issue: $ docker run -e LD_LIBRARY_PATH=$PWD/lib -e PATH=/usr/bin:/bin:$PWD/bin -v $PWD:$PWD --rm -it debian:testing regress dns/getaddrinfo_race_gotresolve (since debian:testing does not have /etc/services) --- diff --git a/test/regress_dns.c b/test/regress_dns.c index 7bbae123..c09a4ff5 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -2139,6 +2139,8 @@ struct race_param volatile int stopping; void *base; void *dns; + + int locked; }; static void * race_base_run(void *arg) @@ -2231,6 +2233,7 @@ getaddrinfo_race_gotresolve_test(void *arg) } EVLOCK_LOCK(rp.lock, 0); + rp.locked = 1; for (i = 0; i < n_reqs; ++i) { tt_assert(evdns_getaddrinfo(rp.dns, "foof.example.com", "ssh", NULL, race_gai_cb, &rp)); @@ -2256,12 +2259,15 @@ getaddrinfo_race_gotresolve_test(void *arg) tt_assert(EVTHREAD_COND_WAIT_TIMED(rp.bw_threads_exited_cond, rp.lock, &tv) == 0); EVLOCK_UNLOCK(rp.lock, 0); + rp.locked = 0; evdns_base_free(rp.dns, 1 /** fail requests */); tt_int_op(n_replies_left, ==, 0); end: + if (rp.locked) + EVLOCK_UNLOCK(rp.lock, 0); EVTHREAD_FREE_LOCK(rp.lock, 0); EVTHREAD_FREE_COND(rp.reqs_cmpl_cond); EVTHREAD_FREE_COND(rp.bw_threads_exited_cond);