HOME
PRODUCTS
  Insure
  WebKing
  Jtest
  Jcontract
  CodeWizard
  C++Test
SUPPORT
PAPERS
ABOUT
WHAT'S NEW
EVENTS

Parasoft Tools that Debug




Product Review: Insure++

By Ashish Arora

The hidden part of software quality is maintenance, which is estimated to account for 10% of the cost of software. The less noble part of maintenance is late debugging: removing errors that should never have been in the first place.1 Emergency bug fixing (done in haste when a program is not producing expected results or behaves in some catastrophic way) costs more that routine scheduled corrections. "Finding and fixing" a problem at field sites is time consuming, due to the difficulty in reproducibility, problem description, difficulties in customer/vendor communication, and the bug itself.

About Insure++

Insure++ is a unique debugging environment to improve software quality. The three subproducts built around the core product, Insight,are:

  • Insra (Insight Report Analyzer) is a GUI that visualizes the compile and runtime error detection.
  • Inuse is a graphical memory monitor that aids in visualizing and understanding dynamic memory manipulation.
  • TCA (Total Coverage Analysis) is a code-coverage analysis tool that determines interested program blocks.

Installation and Documentation

Installation is basically untarring and running iilecens to add/delete/ modify a license. Documentation is lucid and well partitioned. I recommend reading the Getting Started section and the Insra manual (they take about 10 minutes) before using the tool. Both Inuse and TCA manuals are slim and to the point. The corresponding GUIs are self-descriptive. The reference manual is handy, as it clearly illustrates the error codes with actual problem scenarios and ways to fix them. The section on interfaces in the user's manual is well written and useful.

About Insight

Insight is a source-level automatic runtime debugging tool. It is more than adding that "product name" prefixed to the linker at the link time, which is usually the case with object-level debugging tools tend to be evasive in some scenarios due to link-only criterion. Although, I don't tend to compare products here, I do want to mention the addictive nature of the product in the realm of debugging environments. Object transformation is limited to dynamic memory checking and binary replacement is limited to checks only during functions invocations. Source code instrumentation (SCI) inserts test and analysis functions around each line of source code line of source code and builds comprehensive knowledge of elements being tested. At runtime the database memory usage, pointer usage, data structures, etc. are verified for consistency and correctness. This ensures detection of a wide variety of programming errors and all memory-related errors. Detection of certain categories of errors at compile time got me interested in the product. Compiling the test suite and testing degenerate cases spells out the level of the detection capabilities of Insure++. The error name terminology and error description reported at both compile time and runtime are meaningful and save "error interpretation" time. Some specific errors can have subcategories of error types. For example, a READ_UNINIT_MEM error can have read or copy as error types.

The list of errors is comprehensive. The kinds of errors detected can be broadly classified as follows:

  • all memory corruption-related errors (over-writing/reading past legal bounds of objects)
  • pointer abuse (operations on null, uninitialized, invalid pointers)
  • memory leaks
  • dynamic memory manipulation (dangling pointers-related errors, freeing stack memory, errors related to mallocs and free)
  • uninitialized memory errors
  • unused variables
  • data representation
  • incompatible variable declaration
  • invalid parameter passings
  • system call errors

The examples included with the product illustrate error-detection capabilities for most scenarios. Some of these errors related to C++ programming only. To illustrate some categories of errors, refer to Listing 1.

Listing 1

    char *a

    main()
    {			/* RETURN_INCONSISTENT: compile time */
	free( a );	/*FREE_NULL: runtime */

	char *b;
	free( b );	/FREE_ININT_PTR: runtime */

	char *c =3D ( char * ) malloc( 5 );
	free( c );
	free( c );	/* FREE_DANGLING: runtime */

	char *d =3D new char; 
	free( d );	/* ALLOC_CONFLICT: runtime */

	char e, *f	/*UNUSED_VAR(assigned): compile time */
	f=3D "String";
	e=3D (char) f;	/*BAD_CAST: compile time */

	char *g, *h;	/*UNUSED_VAR(assigned): compile time */
	h=3D g;		/*COPY_UNINIT_PTR: runtime */
			/*READ_UNINIT_MEM: runtime */
	char *p, *q 	/*UNUSED_VAR(assigned): compile time */
	p =3D new char [5];
	q =3D p + 10; 	/*COPY_BAD_RANGE: runtime */
	for( int i; i < 10; i++ ) 
	;		/*DEAD_CODE: compile time */

	char buf,[10]
	sprintf( buf, "%s, %d", 1);=20
			/*BAD_FORMAT: compile time */
			/*WRITE_OVERFLOW: runtime */

    }

As seen from the about example, the errors are self-explanatory. The errors can be reported to stderr, to a file, or to Insra. The insight configuration file governs this process. By adding the line report_file<all>insra, the errors are displayed in the GUI tool. The/*BAD_PARM*/ error has several subcategories, and I was intrigued by it. I elaborate its importance in the next section.

Extensibility

Insight has a powerful mechanism to extend its capability through interfaces. It's powerful facility to add extensive checking in your or third-party libraries. Most problems arise as a result of incorrect invocation of a function/class method. Interfaces can ensure and enforce the correct usage and eliminate memory-related erroneous behavior. It;s a trivial task with tremendous benefit. iiproto and iiwhich are extremely useful utilities that aid in writing interfaces. Upon reading about Insure++'s ability to perform error detection on UNIX system calls, X/Motif libraries, etc. I started to write certain test programs that invoked such calls. On passing invalid parameter to the XDrawRectangle call, the invocation passed undetected (I had anticipated a BAD_PARAM error). I used iiwhich, a nifty utility, to explore the "traps" installed for this call. There were none. To extend the error detection performed during invocation of this call, I quickly wrote the interface in Listing 2 and compiled it with an interface compiler called iic.

Listing 2


    XDrawRectangle( Display *disp, Drawable d, GC gc, int x, int y, 
	  unsigned int width, unsigned height )
    {

	iic_source ( disp, XDisplaySize(disp) );

	if( !IsDrawable(d) )
	iic_error( USER_ERROR, "d not drawable(%lx) in XDrawRectangle", d);
	iic_source( gc, XGCSize(gc));
	if( x < 0 | | y < 0)
	iic_error( USER_ERROR, "Rectangle origin out of bounds %d %d", x, y);

	return XDrawRectangle( disp, d, gc, x, y, width, height);

     }

This generated an XCalls.tqs file that I linked with my original program. On running the program the incorrect call was trapped instantly. Taking the idea further, a set of "in-house" debugging (trapping invalid/incorrect) function/libraries could be developed and linked with the specific programs that require these. These new "user-installed" errors are reported appropriately in the GUI or in the error file generated.

I feel Insra's GUI has scope for improvement.

Inuse

Inuse is a graphical tool for displaying real-time memory usage patterns that can be used to understand memory leaks, memory usage, and memory fragmentation. Inuse can be used independently of the runtime detection by relinking the application with additional flags at link time. It shows not only the memory of the application with additional allocated, but also the overhead and waste due to alignment.

There are four kinds of graphs that Inuse can display. These are usage summary, heap history, heap layout, and block frequency, which are described in detail in the Inuse manual. I found Inuse particularly useful with a debugger. I could clearly see the causes of memory fragmentation by placing appropriate breakpoints.

Inuse should have some kind of mapping to source code. The graphics can be improved upon as well.

TCA

TCA determines the application's file, functions, and blocks of code that have been executed. It gives an accurate picture of the code executed and therefore, "tested" by an application. It's frightening to see, say, 30% of the overall application code tested. This clearly suggests that the remaining code has not been executed at all, which implies that some runtime bugs did not get a chance to be detected. By default when you compile an application with insight, a tca.map file is created. This file is an encoded layout of the application and is referenced by TCA to display the coverage analysis. A log file written at runtime that specifies the blocks of code that are executed (default is tca.log). Subsequent runs of the application are merged to the same file to consolidate the new results. Various options are available in the GUI to display details of files, functions, and blocks of code executed.

Conclusion

I feel Insure++ is a must for all applications written in C/C++. The combination of Insight and TCA can with no doubt lead to superior quality software. Coverage analysis generated by TCA enforces thorough developer- oriented testing independent of quality assurance. Inuse, the dynamic memory manager, is helpful in understanding memory usage patterns. With some kind of source code mapping it could be an indispensable tool as well. Particularly impressive is the ability to enhance and extend debugging to any level using interfaces. Overall, Insure++ is a mature, flexible, thorough, and extendible debugging environment.X

Reference:

1. Meyer, B. Object Oriented Software Construction, Prentice Hall, Englewood Cliffs, NJ, 1988.

(Ashish Arora is a Software Consultant with Bluestone, Inc. specializing in O-O technologies and GUIs applied to mission-critical applications. He may be reached at ashish@bluestone.com)

This review appeared in the June 1996 issue of The X Journal.

Tools to debug c++ and java
(888) 305-0041 info@parasoft.com Copyright © 1996-2001 ParaSoft