Search

ParaSoft

HOME
PRODUCTS
SUPPORT
ABOUT
WHAT'S NEW
EVENTS


Insure++

Quick facts

Add-on Modules:
   -INUSE
   -TCA

Comparisons

Technical Papers

Support & Manuals

FAQs

Recent Reviews

User Testimonials

Press Releases


Insure tool to debug c++





Insure++ User's Guide - Code Insertions

Part I



Code Insertions

Most programmers write code that makes assumptions about various things that can happen. These assumptions can vary from the very simple, such as "I'm never going to pass a NULL pointer to this routine", to more subtle, such as "a and b are going to be positive".

Whether this is done consciously or not, the problems that occur when these assumptions are violated are often the most difficult to track down. In many cases, the program will run to completion with no indication of error, except that the final answer is incorrect.

Debugging the hard way

The simple case just described, the NULL pointer, will probably be tracked down pretty easily, since Insure++ will pinpoint the error immediately. A few minutes of work should eliminate this problem.

The second case is much harder.

One option is to add large chunks of debugging code to your application to check for the various cases that you don't expect to show up. Of course, you normally have an idea of where the problem is, so you start by putting checks there. You then run the code and sort through the mass of output, trying to see where things started to go awry. If you guessed wrong, you insert more checks in other places of the code and repeat the entire process.

If you are lucky, the code you insert to catch the problem won't add bugs of its own.

Once you've found the problem, you can either remove the debugging code (introducing the possibility of deleting the wrong things and bringing in new bugs) or comment it out for use next time (cluttering the source code).

An easier solution

A second option is to have Insure++ add the checking code to your application automatically and invisibly.

The basic idea is that you tell Insure++ what you'd like to check by providing an "Insure++ interface module". This can be kept separate from your main application and added and removed at compile time. Furthermore, Insure++ automatically inserts it in every place that you use a particular piece of code so you only have to go through this process once. Finally, errors that are detected are diagnosed in the same way as all other Insure++ errors. You get a complete report of the source file, line number, and function call stack together with any other information that you think is useful.

An example

Assume that you have a routine in your program called cruncher which takes three double precision arguments and returns one. For some reason, possibly connected with the details of your application, you expect the following rules to be true when calls are made to this routine

  • The sum of the three parameters is less than 10.
  • The first parameter is always greater than zero.
  • The return value is never zero.

To enforce these rules with Insure++, you create a file containing the following "code".

  
	1:  /*
  	2:   * crun_iic.c
  	3:   */
  	4:  (double a, double b, double c)
  	5:  {
  	6:       double ret;
  	7:
  	8:       if(a+b+c >= 10.) {
  	9:           iic_error(USER_ERROR,
  	10:                "Sum exceeds 10: %f+%f+%f\n",
  	11:                a, b, c);
  	12:      }
  	13:      if(a <= 0) {
  	14:      iic_error(USER_ERROR,
  	15:           "a is negative: %f\n", a);
  	16:      }
  	17:      ret = cruncher(a, b, c);
  	18:      if(ret == 0) {
  	19:           iic_error(USER_ERROR,
  	20:                "Return zero: %f,%f,%f => %f\n",
  	21:                a, b, c, ret);
  	22:      }
  	24:      return ret;
  	25:  }

Note that this looks just like normal C code with the rather strange exception that the routine cruncher calls itself at line 17!

This is not normal C code - it's an Insure++ interface description, and it behaves rather like a complicated macro insertion. Wherever your original source code contains calls to the function cruncher, they will be replaced by this set of error checks, and the indicated call to the routine cruncher.

The net effect will be as though you had added all this complex error checking and printing code manually, except that Insure++ does it automatically for you. Another advantage is the use of the iic_error routine rather than a conventional call to printf or fprintf. The iic_error routine performs the same task - printing data and strings, but also includes in its output information about the source file and line number at which the call is being made and a full stack trace.

Using the interface

Once you've written this interface description, using it is trivial. First, you compile it with the special Insure++ interface compiler, iic. If you put the code in a file called crun_iic.c, for example, you would type the command

	iic crun_iic.c

This creates a file called crun_iic.tqs, which is an "Insure++ interface module".

You can use this module in one of two ways.

If you plan to use this interface check on a regular basis during the development of your project, you should insert the line

	insure++.interface_library crun_iic.tqs

in the .psrc file in either your current working or $HOME directory. All future invocations of .psrc will then insert this interface check.

If you wish to use the interface check intermittently on some of your compiles, you can add the name of the interface module to the Insure command line when you compile and link your source code. For example the command

	insure -c myfile1.c

would become

	insure crun_iic.tqs -c myfile1.c

Note that you can specify more than one interface in any interface file or include multiple interface modules on the interface_library line in your .psrc file or on the insure command line.

Conclusions

This section has shown how you can add your own error checking either to extend or replace that done automatically by Insure++ by defining "interface modules". These are actually a very powerful way of extending the capabilities of Insure++, and are described more fully in "Interfaces". The current discussion, however, has shown their simplest use.


For more information, call (888) 305-0041 or send email to: insure@parasoft.com

< Signals > Interfaces ^ Insure++ User's Guide TOC
Tools to debug c++ and java
(888) 305-0041 info@parasoft.com Copyright © 1996-2001 ParaSoft