June 8, 2007, 12:45 a.m.

The Deputy C Compiler

websplat is a simple http load tester based on libevent that I wrote a really long time ago. I was using it for some testing today, and I'd occasionally get a warning that suggested I may have overstepped a boundary. I couldn't reproduce it under valgrind (which was under different circumstances on a different machine, but I was hopeful), so I ignored it for the moment.

Later that day, I saw deputy come through today and figured I'd give it a go. It took me a bit to get used to the error messages, but it found some really neat errors. For example:

  /* Prototype of recv_data.
     Note that COUNT(x) tells the compiler that there
     are x bytes available in the char* buf.  In this
     case, that means it's whatever the len parameter
     says it should be */

  int recv_data(struct host_ret conn, struct url u,
    char* COUNT(len) buf, size_t len);

  /* Implementation of recv_data (simplified) */
  int recv_data(...) {
        int size=0;
        size = recv(conn.s, buf, len, 0);
        /* Spot the bug? */
        buf[size]=0x00;
        return size;
  }

The bug is subtle, but likely what I was running into. recv would fill the buffer with up to the length it was told it could, and give me the size. I'd then write a null character at that size. If len was 1, and recv read one character, and then returned one, I'd write something at buffer position 1. For those of you aren't programmers, counts start at 0 which makes an offset of 1 too far for a buffer that can only hold one thing.

There were several bugs like this it found, each of which was easily fixed by adding a -1 in one place or another.

I'm a big fan of anything that can show me bugs in my code. I can't learn anything if I can't figure out what I'm doing wrong.

blog comments powered by Disqus