From: Ondřej Surý Date: Thu, 23 Oct 2025 11:11:45 +0000 (+0200) Subject: Add optional debugging output for fetch context reference counting X-Git-Tag: v9.21.16~27^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e971db1edc79a99f25c4523f40fade8ade6880d;p=thirdparty%2Fbind9.git Add optional debugging output for fetch context reference counting As the fetch context reference counting was converted to userspace RCU reference counting, the ability to debug the reference counting was lost. Restore the debugging by adding the optional compile-time enabled debugging output again. --- diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index c9c19bf6d51..b3a93f5e2a6 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -188,7 +188,7 @@ #endif /* - * A minumum sane timeout value for the whole query to live when e.g. talking to + * A minimum sane timeout value for the whole query to live when e.g. talking to * a backend server and a quick timeout is preferred by the user. * * IMPORTANT: if changing this value, note there is a documented behavior when @@ -650,8 +650,10 @@ static void fctx_shutdown(void *arg); static void fctx_minimize_qname(fetchctx_t *fctx); +#define fctx_destroy(fctx) fctx__destroy(fctx, __func__, __FILE__, __LINE__) static void -fctx_destroy(fetchctx_t *fctx); +fctx__destroy(fetchctx_t *fctx, const char *func, const char *file, + const unsigned int line); static isc_result_t negcache(dns_message_t *message, fetchctx_t *fctx, const dns_name_t *name, isc_stdtime_t now, bool optout, bool secure, dns_rdataset_t *added, @@ -695,22 +697,62 @@ findnoqname(fetchctx_t *fctx, dns_message_t *message, dns_name_t *name, } \ rcu_read_unlock() +#define fetchctx_ref_unless_zero(fctx) \ + fetchctx__ref_unless_zero(fctx, __func__, __FILE__, __LINE__) static bool -fetchctx_ref_unless_zero(fetchctx_t *fctx) { - return urcu_ref_get_unless_zero(&fctx->ref); +fetchctx__ref_unless_zero(fetchctx_t *fctx, const char *func, const char *file, + const unsigned int line) { + bool ref = urcu_ref_get_unless_zero(&fctx->ref); +#if DNS_RESOLVER_TRACE + fprintf(stderr, + "%s:%s:%s:%u:t%" PRItid ":%p->references = %" PRIuFAST32 "\n", + __func__, func, file, line, isc_tid(), &fctx->ref, + fctx->ref.refcount); +#else + UNUSED(file); + UNUSED(line); + UNUSED(func); +#endif + return ref; } +#define fetchctx_attach(source, targetp) \ + fetchctx__attach(source, targetp, __func__, __FILE__, __LINE__) static void -fetchctx_attach(fetchctx_t *fctx, fetchctx_t **fctxp) { +fetchctx__attach(fetchctx_t *fctx, fetchctx_t **fctxp, const char *func, + const char *file, const unsigned int line) { bool ref = fetchctx_ref_unless_zero(fctx); INSIST(ref == true); *fctxp = fctx; +#if DNS_RESOLVER_TRACE + fprintf(stderr, + "%s:%s:%s:%u:t%" PRItid ":%p->references = %" PRIuFAST32 "\n", + __func__, func, file, line, isc_tid(), &fctx->ref, + fctx->ref.refcount); +#else + UNUSED(file); + UNUSED(line); + UNUSED(func); +#endif } -static void -fetchctx_ref(fetchctx_t *fctx) { +#define fetchctx_ref(fctx) fetchctx__ref(fctx, __func__, __FILE__, __LINE__) +static fetchctx_t * +fetchctx__ref(fetchctx_t *fctx, const char *func, const char *file, + const unsigned int line) { bool ref = fetchctx_ref_unless_zero(fctx); INSIST(ref == true); +#if DNS_RESOLVER_TRACE + fprintf(stderr, + "%s:%s:%s:%u:t%" PRItid ":%p->references = %" PRIuFAST32 "\n", + __func__, func, file, line, isc_tid(), &fctx->ref, + fctx->ref.refcount); +#else + UNUSED(file); + UNUSED(line); + UNUSED(func); +#endif + return fctx; } static void @@ -718,18 +760,42 @@ fetchctx_destroy(struct urcu_ref *ref) { fetchctx_t *fctx = caa_container_of(ref, fetchctx_t, ref); fctx_destroy(fctx); } - +#define fetchctx_detach(fctxp) \ + fetchctx__detach(fctxp, __func__, __FILE__, __LINE__) static void -fetchctx_detach(fetchctx_t **fctxp) { +fetchctx__detach(fetchctx_t **fctxp, const char *func, const char *file, + const unsigned int line) { fetchctx_t *fctx = *fctxp; *fctxp = NULL; urcu_ref_put(&fctx->ref, fetchctx_destroy); +#if DNS_RESOLVER_TRACE + fprintf(stderr, + "%s:%s:%s:%u:t%" PRItid ":%p->references = %" PRIuFAST32 "\n", + __func__, func, file, line, isc_tid(), &fctx->ref, + fctx->ref.refcount); +#else + UNUSED(file); + UNUSED(line); + UNUSED(func); +#endif } +#define fetchctx_unref(fctx) fetchctx__unref(fctx, __func__, __FILE__, __LINE__) static void -fetchctx_unref(fetchctx_t *fctx) { +fetchctx__unref(fetchctx_t *fctx, const char *func, const char *file, + const unsigned int line) { urcu_ref_put(&fctx->ref, fetchctx_destroy); +#if DNS_RESOLVER_TRACE + fprintf(stderr, + "%s:%s:%s:%u:t%" PRItid ":%p->references = %" PRIuFAST32 "\n", + __func__, func, file, line, isc_tid(), &fctx->ref, + fctx->ref.refcount); +#else + UNUSED(file); + UNUSED(line); + UNUSED(func); +#endif } static bool @@ -4509,7 +4575,8 @@ fctx_destroy_rcu(struct rcu_head *rcu_head) { } static void -fctx_destroy(fetchctx_t *fctx) { +fctx__destroy(fetchctx_t *fctx, const char *func, const char *file, + const unsigned int line) { dns_resolver_t *res = NULL; REQUIRE(VALID_FCTX(fctx)); @@ -4524,6 +4591,17 @@ fctx_destroy(fetchctx_t *fctx) { FCTXTRACE("destroy"); +#if DNS_RESOLVER_TRACE + fprintf(stderr, + "%s:%s:%s:%u:t%" PRItid ":%p->references = %" PRIuFAST32 "\n", + __func__, func, file, line, isc_tid(), &fctx->ref, + fctx->ref.refcount); +#else + UNUSED(func); + UNUSED(file); + UNUSED(line); +#endif + fctx->magic = 0; res = fctx->res; @@ -4701,12 +4779,18 @@ log_ns_ttl(fetchctx_t *fctx, const char *where) { where, namebuf, domainbuf, fctx->ns_ttl_ok, fctx->ns_ttl); } +#define fctx_create(res, loop, name, type, domain, nameservers, client, \ + options, depth, qc, gqp, fctxp) \ + fctx__create(res, loop, name, type, domain, nameservers, client, \ + options, depth, qc, gqp, fctxp, __func__, __FILE__, \ + __LINE__) static isc_result_t -fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, - dns_rdatatype_t type, const dns_name_t *domain, - dns_rdataset_t *nameservers, const isc_sockaddr_t *client, - unsigned int options, unsigned int depth, isc_counter_t *qc, - isc_counter_t *gqc, fetchctx_t **fctxp) { +fctx__create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, + dns_rdatatype_t type, const dns_name_t *domain, + dns_rdataset_t *nameservers, const isc_sockaddr_t *client, + unsigned int options, unsigned int depth, isc_counter_t *qc, + isc_counter_t *gqc, fetchctx_t **fctxp, const char *func, + const char *file, const unsigned int line) { fetchctx_t *fctx = NULL; isc_result_t result; isc_result_t iresult; @@ -4813,10 +4897,6 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, isc_counter_used(fctx->gqc)); } -#if DNS_RESOLVER_TRACE - fprintf(stderr, "fetchctx__init:%s:%s:%d:%p:%p->references = 1\n", - __func__, __FILE__, __LINE__, fctx, fctx); -#endif urcu_ref_set(&fctx->ref, 1); if (client != NULL) { @@ -4987,6 +5067,17 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, *fctxp = fctx; +#if DNS_RESOLVER_TRACE + fprintf(stderr, + "%s:%s:%s:%u:t%" PRItid ":%p->references = %" PRIuFAST32 "\n", + __func__, func, file, line, isc_tid(), &fctx->ref, + fctx->ref.refcount); +#else + UNUSED(file); + UNUSED(line); + UNUSED(func); +#endif + return ISC_R_SUCCESS; cleanup_adb: