The Boston Diaries

The ongoing saga of a programmer who doesn't live in Boston, nor does he even like Boston, but yet named his weblog/journal “The Boston Diaries.”

Go figure.

Thursday, January 19, 2012

They're hard problems for a reason …

I quoted this once before, but it bears repeating:

There are only two hard problems in Computer Science: cache invalidation, naming things, and off-by-one errors.

I got hit with one of those issues today, and it wasn't naming a thing, or an off-by-one error. It'a amazing how much time can be wasted by omitting a single command …


99 ways to program a hex, Part 11: C89, const correctness, assertive, GCC extensions

Today's code is identical to part 9 save for one line—it uses a GCC extention to notify the compiler that the do_dump() function accepts NULL pointers, and that it won't throw any exceptions.

/*************************************************************************
*
* Copyright 2012 by Sean Conner.  All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
* Comments, questions and criticisms can be sent to: sean@conman.org
*
*************************************************************************/

/* Style: C89, const correctness, assertive, GCC extensions */

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

#define LINESIZE	  16

static void 	do_dump		(FILE *const,FILE *const) __attribute__((nonnull,nothrow));

/****************************************************************/

int main(const int argc,char *const argv[])
{
  assert(argc    >= 1);
  assert(argv    != NULL);
  assert(argv[0] != NULL);
  
  if (argc == 1)
    do_dump(stdin,stdout);
  else
  {
    int i;
    
    for (i = 1 ; i < argc ; i++)
    {
      FILE *fp;
      
      fp = fopen(argv[i],"rb");
      if (fp == NULL)
      {
        perror(argv[i]);
        continue;
      }

      printf("-----%s-----\n",argv[i]);
      do_dump(fp,stdout);
      fclose(fp);
    }
  }

  return EXIT_SUCCESS;
}

/******************************************************************/

static void do_dump(FILE *const fpin,FILE *const fpout)
{
  unsigned char  buffer[BUFSIZ];
  unsigned char *pbyte;
  size_t         offset;
  size_t         bread;
  size_t         j;
  char           ascii[LINESIZE + 1];
  
  assert(fpin  != NULL);
  assert(fpout != NULL);
  
  offset = 0;

  while((bread = fread(buffer,1,BUFSIZ,fpin)) > 0)
  {
    pbyte = buffer;
    while (bread > 0)
    {
      fprintf(fpout,"%08lX: ",(unsigned long)offset);
      j = 0;
      do
      {
        fprintf(fpout,"%02X ",*pbyte);
        if (isprint(*pbyte))
          ascii [j] = *pbyte;
        else
          ascii [j] = '.';
        pbyte  ++;
        offset ++;
        j      ++;
        bread  --;
      } while ((j < LINESIZE) && (bread > 0));
      ascii [j] = '\0';
      if (j < LINESIZE)
      {
	size_t i;

	for (i = j ; i < LINESIZE ; i++) fprintf(fpout,"   ");
      }
      fprintf(fpout,"%s\n",ascii);      
    }
    
    if (fflush(fpout) == EOF)
    {
      perror("output");
      exit(EXIT_FAILURE);
    }
  }
}

/***************************************************************/

Okay, what failed this time?

I'm running the regression tests for “Project: Wolowizard” and about half way through the tests (around the two hour mark or so) start failing. Sometimes expected results just aren't showing up. I'm freaking about a bit because of all the issues we've had in running these tests, only for it to start failing in yet a different way.

Now, a bit about how this all works—there are four computers involved; one runs the tests, injecting messages towards a mini-cluster of two machines, either of which (depending on which one gets the message) sends a message to the fourth machine, which does a bunch of processing (which may involve interaction with a simulated cell phone on the testing machine), then responds back to the mini-cluster, which then responds back to the testing machine.

Now, I can check the immedate results from the mini-cluster, but the actual data I'm interested in is logged via syslog, so I have that data forwarded to the testing machine and my code grovels through a log file for the actual data I want. And it's that data (or part thereof) that apparently isn't being logged, and thus, the tests are failing.

Now, it just so happens that the part of the test that's failing is the part dealing with the mini-cluster, and it looks like about half the tests are failing (hmm …. ).

I log into each of the two computers comprising the mini-cluster, and check /etc/syslog.conf, in the off chance that changed. Nope. I then explain the problem to Bunny, standing (or rather, sitting) in as my cardboard programmer when it hits me—I should check to see if the program is running.

Rats. It is.

The tests are still failing, and my shoes began to squeak.

Okay, just because syslogd is running doesn't necessarily mean it's running correctly. So I run logger -p local1.info FOO on each machine and yes, one of the machines is failing to foward the logs to the testing machine.

Ahah!

I restart syslogd on that system, and lo! The log entries are getting through now.

You know, I expect there to be issues with the stuff I'm testing; what I don't expect is the stuff that we didn't write is having issues (the Protocol Stack From Hell™ notwithstanding).

Okay, reset everything and start the regression test over again …

Update in the wee-hours of the morning, Friday, January 20th, 2012

A bit over half-way through the regression tests, and the log files rotate. Aaaaaaaaaah! Okay, reset all the data, and start from the last failed test. That's easy, since I can specify which cases to run. That's hard, because I have to specify nearly a 100 cases. That's easy, since I can use the Unix command seq to list them. That's hard, because the test cases aren't just numbers, but things like “1.b.77” and “1.c.18”, and while the shell supports command line expantion from a running program via the backtick (ala for i in `seq 34 77`; do echo 1.b.$i; done) I need to nest two such operations (echo `for i in `seq 34 77`;do echo 1.b.$i; done`) to specify the test cases from the command line, and the command line doesn't support that. Okay, I can create a temporary file that lists the test cases …

Obligatory Picture

An abstract representation of where you're coming from]

Obligatory Contact Info

Obligatory Feeds

Obligatory Links

Obligatory Miscellaneous

Obligatory AI Disclaimer

No AI was used in the making of this site, unless otherwise noted.

You have my permission to link freely to any entry here. Go ahead, I won't bite. I promise.

The dates are the permanent links to that day's entries (or entry, if there is only one entry). The titles are the permanent links to that entry only. The format for the links are simple: Start with the base link for this site: https://boston.conman.org/, then add the date you are interested in, say 2000/08/01, so that would make the final URL:

https://boston.conman.org/2000/08/01

You can also specify the entire month by leaving off the day portion. You can even select an arbitrary portion of time.

You may also note subtle shading of the links and that's intentional: the “closer” the link is (relative to the page) the “brighter” it appears. It's an experiment in using color shading to denote the distance a link is from here. If you don't notice it, don't worry; it's not all that important.

It is assumed that every brand name, slogan, corporate name, symbol, design element, et cetera mentioned in these pages is a protected and/or trademarked entity, the sole property of its owner(s), and acknowledgement of this status is implied.

Copyright © 1999-2024 by Sean Conner. All Rights Reserved.