In order to combat the “creative user” problem, there is a type of program which will take source code or object files and produce a version that analyzes itself for bugs as it runs.

The first thing I did with Insure++ was to get out a Sunsite archive CD and start compiling programs. This proved to be an excellent way to learn how to use the product. All the programs I tried proved to be easy to compile. In each case, I simply overrode the appropriate variables on the make command line to cause the program to be built with the insure compiler and the -g debug flag. For example, this command works with many X11 programs:

make CC=insure CDEBUGOPTS=-g

When make invokes the first insure compiler, the compiler starts up the Insra GUI to display any problems Insure++ detects at compile time. All future invocations of the compiler talk to the existing Insra process so you don't have a new window popping up for each compiler process that runs.

After the program is built, you just run it as you always have. When it starts up, it sends messages about any bugs it finds to Insra. Insra will display the source code in which the error occurred and the stack trace when it occurred. If you click on an element in the stack trace, Insra will start up your editor in the appropriate file so you can fix the problem.

One thing you notice when running programs compiled with insure is that they run much slower. I wrote a few test programs to try to quantify this phenomenon. If a program sits in a tight loop, makes no function calls and does not access any arrays, it does not slow down at all. If a program spends most of its time calling functions or accessing arrays, it slows down by about a factor of 80. Most programs do call functions and access arrays, so you can expect to see a significant slowdown. A good rule of thumb is every second of user time the program usually takes is going to translate to a minute of user time with Insure++.

I had a few minor problems with Insure++, such as Insra not being able to find source code when that code was spread out in multiple directories. I was always able to resolve these problems quickly by referring to the manual, which is well-indexed and well written. In fact, it is written well enough that it is fun to read even if you are not trying to solve a problem.

At one point I thought I had found a bug in Insure++. I had written the following test program:

int main()
        char *x = malloc(30);
        char z = x[1];
        char y = x[31];
        int zz;
        x[0] = 0;
        z += 3;
        zz = x[0];
        return z*z;

Insure++ detected that I had accessed past the end of the x[]array when I initialized y and that I had used x[] after I had freed its memory. However, it did not detect that I had initialized z with an uninitialized member of x[] (i.e., x[1] had not been initialized). I was excited because this omission gave me a chance to try out Parasoft's technical support. I put the test program on one of my web pages so I could show it to the people at Parasoft. I then called up the salesperson who had provided my license key and told him I had found a bug. He transferred me to one of their programmers. I gave the programmer the URL where the code was, and he took a look at it while I was on the phone with him. He told me that by default Insure++ does not check to see if variables less than 4 bytes long are uninitialized. He then told me what to put in my .psrc file to change this. Then he gave me his e-mail address and telephone extension so I could contact him if I had any other problems.

I had three separate interactions with three different people at Parasoft, and each interaction was very positive. I figured that people doing reviews for magazines got VIP treatment, but I wondered how other people would be treated. I found someone at work who had used Insure++ at a prior job, and I asked him what he thought about Parasoft's technical support. He told me that he also thought it had been excellent—so much for my special treatment.

Advanced Debugging

After I had gotten familiar with the basics of using Insure++, I decided to try some of the more advanced features. The first one I investigated was the interaction between gdb and programs compiled with insure. Insure does a good job of hiding the modifications it makes to the source code from the debugger. For the most part, you can't tell that anything is different. One thing that is different is that the program will call the function _Insure_trap_error whenever it detects a problem in your code. By setting a debugger breakpoint in this function, you can get the program to stop each time Insure++ finds a problem. Then you can use the debugger to examine your program's variables and find out why the problem occurred. I tried this on a few programs and found it to be a very useful feature. There are also other functions you can call from the debugger to get information about which location in the program memory was allocated for a variable and how much memory is currently allocated.

Another feature I classified as advanced has to do with programs that use their own memory managers. Insure++ knows about malloc, calloc, free, new, delete and other standard memory management functions. This allows it to do in-depth error checking when you use these functions. It is fairly common for programs to have their own memory managers which allocate large blocks of memory and dole it out themselves. In order to get detailed error checking for these programs, it is necessary to teach Insure++ about your memory manager. I did not do this myself, but the people evaluating Insure++ at work did, and they indicated it was a fairly straightforward task. It is even possible to teach Insure++ about functions that have nothing to do with memory management and have it verify arbitrary things about the state of your program each time the function is called.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.


mujinchao's picture