[bind10-dev] whether/when to use exceptions (Re: 2009-10-08 BIND 10 meeting)

JINMEI Tatuya / 神明達哉 jinmei at isc.org
Thu Oct 8 22:44:53 UTC 2009


At Thu, 8 Oct 2009 16:19:22 -0400,
christos at zoulas.com (Christos Zoulas) wrote:

> | If we take exceptions off the table, I say we write the whole thing in
> | Python or Ruby.  Removing major features of the reason we chose C++
> | would mean we chose poorly.
> 
> Well, the biggest problem I have with exceptions is that they lead to
> resource leaks. Since there are no checked exceptions you cannot know
> if I function that you call is going to throw, so for every OS resource
> you use (fd, shared memory segment, malloced space without smart pointers)
> you must make sure that there is no exception that is going to cause you
> to leak it.

Resource leaks are certainly a common compliant against (C++)
exceptions, and I guess "without smart pointers" is a key here.  Maybe
I'm naive, but in my understanding many of resource leak problems with
exceptions can be smartly avoided using RAII techniques (including the
use of smart pointers).  If we decide to rely on exceptions relatively
heavily, I guess we should equally heavily use RAII.

BTW, I've quickly looked at a couple of other C++ based products that
handle network protocols: power DNS recursor and XORP (there's no
particular reason to pick up them except that I happen to be
relatively familiar with the implementation).  Both seem to use
exceptions in packet/message validation when the parser encounter
malformed data.  Examples:

void MOADNSParser::init(const char *packet, unsigned int len)
{
    ....
  try {
        ....
  }
  catch(out_of_range &re) {
    if(validPacket && d_header.tc) {
        ....
    }
    else {
      throw MOADNSException("Error parsing packet of "+lexical_cast<string>(len)+" bytes (rd="+
			    lexical_cast<string>(d_header.rd)+
			    "), out of bounds: "+string(re.what()));
    }

hmm, pdns recursor even uses an exception for a valid response with
the TC bit on...interesting.

void 
Ospf<A>::receive(const string& interface, const string& vif,
		 A dst, A src, uint8_t* data, uint32_t len)
{
    ...
    Packet *packet;
    try {
	ipv6_checksum_verify<A>(src, dst, data, len, Packet::CHECKSUM_OFFSET,
				_io->get_ip_protocol_number());
	packet = _packet_decoder.decode(data, len);
    } catch(InvalidPacket& e) {
	XLOG_ERROR("%s", cstring(e));
	return;
    }
    ...
}

This is not necessarily to say we should follow them, but existing
usage in real-world products would indicate it's at least worse
considering.

---
JINMEI, Tatuya



More information about the bind10-dev mailing list