[bind10-dev] logging and exception

JINMEI Tatuya / 神明達哉 jinmei at isc.org
Wed Jun 22 18:56:19 UTC 2011


By adding logging, I suspect C++ methods that have been exception free
can now throw.  A simple example is this:

void
Resolver::setTimeouts(int query_timeout, int client_timeout,
                      int lookup_timeout, unsigned retries) {
    LOG_DEBUG(resolver_logger, RESOLVER_DBG_CONFIG, RESOLVER_SETPARAM)
              .arg(query_timeout).arg(client_timeout).arg(lookup_timeout)
              .arg(retries);

    impl_->query_timeout_ = query_timeout;
    impl_->client_timeout_ = client_timeout;
    impl_->lookup_timeout_ = lookup_timeout;
    impl_->retries_ = retries;
}

because producing a logging message would normally involve dynamic
allocation for strings.  Since in some context we rely on an
assumption that a specific method never throws (one common case is
destructors), this could be a potential problem.

What should we do with this?
1. Ensure LOG_xxx never throws by not doing dynamic memory allocation
   or not using throwing new, etc.  I'm afraid this is too costly and
   makes the underlying implementation more complicated.
2. Similar to #1, but simply catch any exception from the logger and
   ignore it:
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE) \
    if (!(LOGGER).isDebugEnabled((LEVEL))) { \
    } else { \
        try { \
          (LOGGER).debug((LEVEL), (MESSAGE)); } \
    } catch (...) {}
   I don't like this either, but in this context it may be a least
   evil and acceptable option.
3. Do not make logs in the context where an exception isn't supposed
   to be thrown.  I don't think this is realistic or too restrictive.
4. Pretend the problem doesn't exist and ignore it because the
   exception in question would normally only happen in rare cases such
   as memory shortage.  This may be acceptable as a compromise, but
   I'd rather prefer #2 than this one.

Or is there a better solution?

---
JINMEI, Tatuya



More information about the bind10-dev mailing list