In this section:
Overview
Insure++ adopts the following error reporting strategy by default:
- Error messages are coded with an uppercase string, such as READ_OVERFLOW or LEAK_SCOPE, and displayed. See Error Codes for a list of error condition messages.
- Only the first occurrence of a particular (unsuppressed) error at any given source line is shown.
- Error messages are sent to the console (stderr), the Insra GUI, or to a separate report file.
- Each error shows a stack trace of the previous routines, displayed all the way back to your main program.
Report File
Normally, error reports are displayed on the console or sent to the Insra GUI. See Viewing Results on Windows for information about sending output to Insra. If you wish to send both your program’s output and the Insure++ reports to a file, you can use the normal console redirection method.
If you want to keep track of the reports from multiple runs of your code, you can configure Insure++ to automatically generate file names based on a template by setting the report_file
property in the Configuration Options (psrc) file. Define the template by embedding a string of characters with tokens, such as %d
, %p
, or %V
. Each of these is expanded to indicate a certain property of your program.
The following example advanced report configuration option will generate a report named foo-errs.20181221103032
if executed with a program called foo
at 10:30 a.m. on December 21, 2018:
report_file %v-errs.%D
The last two digits in the file name are the seconds.
Customizing the Output Format
By default, Insure++ displays a particular banner for each error report, which contains the filename and line number containing the error, and the error category found. For example:
[foo.c:10] **READ_UNINIT_MEM(copy)**
You can modify this format to meet your needs, such as enabling the editor in your integrated environment to search for the correct file and line number for each error.
You can customize the output by setting the error_format
option in your .psrc file. Use a string of characters to define the format. The string should contain embedded tokens that represent the various pieces of information that you might wish to view. See Filenames for additional information.
The error_format
option only takes effect if the Insure++ errors are being reported to the console or a file. If the errors are being sent to Insra, the error format in Insra will stay the same. For details on how to change where errors are sent, see Viewing Results on Windows.
Displaying Process Information
When using Insure++ with programs that fork into multiple processes, you might wish to display additional process-related information in your error reports.
You could add the following options, for example to generate errors that contains the name of the machine on which the process is running and its process ID:
error_format "%f, line %l: \n\tprocess %p@%h: %c"
The errors would take the following form:
foo.c, line 8: process 1184@gobi: READ_UNINIT_MEM(copy)
Displaying Error Timestamps
You can extend the error reports generated by Insure++ to include timestamps of errors occurrences. Add the %d
and/or %t
characters to the error report format as specified in the advanced configuration options or .psrc file.
For example, the following format includes a timestamp in the generated report:
insure++.error_format "%f:%l, %d %t <%c>"
The error will be in the following format:
foo.c:8, 12-Mar-2007 14:24:03 <READ_NULL>
Displaying Repeated Errors
By default, Insure++ only reports the first error of any given kind at a source line, but you can configure Insure++ to display additional occurrences of the same errors. For Windows, modify the Report Limit field in the Reports tab of the Insure++ Control Panel to specify how many times additional errors are displayed. For Unix systems, use the insure++.report_limit <number>
option to your .psrc file to specify how many times additional errors are displayed.
When set to 1
, Insure++ will only report the first error of each type on any line of code. Set to 0
to only include errors in summary reports and not at runtime. Disable to report all errors. See Report Summaries for more information.
All information is lost by showing only the first (or first few) errors at any source line. If you enable the report summary you will see the total number of each error at each source line.
Searching For Source Code
Normally, Insure++ remembers the directory in which each source file was compiled and looks there when trying to display lines of source code in error messages. Occasionally your source code will no longer exist in this directory, possibly because of some sophisticated “build” or “make” process.
You can use the source_path
option in your advanced configuration or .prsc file to provide Insure++ with an alternative list of directories to search for source code:
source_path .;c:\users\boswell\src;c:\src
The list can contain any number of directories separated by colons.
Insure++’s error messages normally indicate the line of source code responsible for a problem on the second line of an error report, after the >>
mark. If this line is missing from the report, it means that the source code could not be found at runtime.
Suppressing Error Messages
You can completely suppress error messages for types of errors that you do not need to address. Suppressing errors prevents them from being displayed, although the errors will still be counted and displayed in the report summaries. Add the suppress
option to your .psrc file and re-run the program. For example:
insure++.suppress EXPR_NULL, PARM_DANGLING
You can also apply certain wildcards in this context so that, for instance, you can suppress all memory leak messages with the command:
insure++.suppress LEAK_*
You can also suppress all errors, which will only create an error summary:
insure++.suppress *
If the error code has sub-categories, you can disable them explicitly by listing the sub-category codes in parentheses after the name. For example:
insure++.suppress BAD_FORMAT(sign, compatible)
Alternatively, the following option would suppresses all sub-categories of the specified error class:
insure++.suppress BAD_FORMAT
Suppressing Error Messages By Context
You can also suppress and unsuppress error messages by context. For example, enter the following option to suppress READ_NULL
errors occurring in routines with names beginning with the characters sub (Windows):
READ_NULL { sub* * }
For Unix systems, prepend the option with insure++.
:
insure++.suppress READ_NULL { sub* * }
The interpretation of this syntax is as follows:
- The stack context is enclosed by a pair of braces.
- Routine names can either appear in full or can contain the
*
or?
wildcard characters. The former matches any string, while the latter matches any single character. - An entry consisting of a single
*
character matches any number of functions, with any names. - Entries in the stack context are read from left to right with the leftmost entries appearing lowest (or most recently) in the call stack.
With these rules in mind, the previous entry is read as:
- The lowest function in the stack trace (that is, the function generating the error message) must have a name that begins with sub followed by any number of other characters.
- Any number of functions of any name may appear higher in the function call stack.
As an example, consider a case in which we are only interested in errors generated from the routine {{foobar}} or its descendants In this case, we can combine suppress and unsuppress options as follows:
Suppress: *
Unsuppress: * {* foobar * }
Error suppression is only possible for functions that appear in stack traces which list error locations. For example, consider the following error report for READ_DANGLING
:
block committed at: > f2() > f1() >stack trace where memory was decommitted: > f3() > e::g() >stack trace where the error occurred: > g2() > g1()
You may suppress either of the functions g1() or g2() where the error occurred by using one of the following options:
Suppress READ_DANGLING { * g1 * } Suppress READ_DANGLING { * g2 * } Suppress READ_DANGLING { g* * }
In this instance, however, you may not suppress either of the functions in the stack trace where memory was de-committed. Scope names require special handling. Substitute *
for ::
when suppressing functions that have a scope resolution. For example, to suppress READ_DANGLING
in Foo::bar ()
, specify the following:
suppress READ_DANGLING { * Foo*bar * }
As another drastic, but common, action is to suppress any errors generated from within calls to the X Window System libraries. If we assume that these functions have names which begin with either "X" or "_X", we could achieve this goal with the following statements:
insure++.suppress all { * X* * } insure++.suppress all { * _X* * }
This suppresses errors in any function (or its descendants) that begins with either of the two sequences.
Suppressing Other Warning Messages
You can use the suppress_output
option for compile-time warning messages that do not have an associated number. This option takes a string as an argument and will suppress any message with text that matches the string. For example, the following option would suppress the warning from the previous section, as well as any others that included this text string (Windows):
suppress_output wrong arguments passed
Usage for Unix:
insure++.suppress_output wrong arguments passed
Enabling Error Messages
You can enable currently-suppressed error messages by configuring the system default, advanced configuration options or your .psrc file. See Error Codes for more information.
Add the unsuppress
option to your .psrc file. The following example releases RETURN_FAILURE messages:
insure++.unsuppress RETURN_FAILURE
Report Summaries
Normally, you will see error messages for individual errors as your program proceeds. Using the other options described so far, you can enable or disable these errors or control the exact number seen at each source line. This technique is most often used to systematically track down each problem, one by one. However, it is often useful to obtain a summary of the problems remaining in a piece of code in order to track its progress. Insure++ supports the following types of summary reports:
- A bug summary which lists all outstanding bugs according to their error codes.
- A leak summary which lists all memory leaks - that is, places where memory is being permanently lost.
- An outstanding summary which lists all outstanding memory blocks - that is, places where memory is not being freed, but is not leaked because a valid pointer to the block still exists.
- A coverage summary which indicates how much of the application’s code has been executed.
Default Summaries
On Windows, all types except for the coverage summary are shown by default, but none of the options are displayed by default on Unix systems.
Bugs Summary
You can include the this report summary on Windows by enabling the Summarize: Bugs option in the Reports tab of the Insure++ Control Panel and re-running your program. Add the insure++.summarize bugs
option to your .psrc file and re-run your program to add this report summary on Unix systems.
In addition to the normal error reports, you will then also see a summary such as the one shown below:
******************* INSURE SUMMARY *********v7.4***** * Program : hello * Arguments : this is bug summary test * Directory : /home/Insure++/examples/c * Compiled on : Mar 25, 2007 15:22:58 * Run on : Mar 26, 2007 13:16:43 * Elapsed time : 00:00:00 * Malloc HWM : 0 bytes ****************************************************** PROBLEM SUMMARY - by type =============== Problem Reported Suppressed ------------------------------------------------- READ_OVERFLOW 3 0 WRITE_OVERFLOW 2 1 ------------------------------------------------- TOTAL 5 1 ------------------------------------------------- PROBLEM SUMMARY - by location =============== READ_OVERFLOW: Reading overflows memory, 3 unique occurrences 1 at hello.c, 15 1 at hello.c, 16 1 at hello.c, 18 WRITE_OVERFLOW: Writing overflows memory, 2 unique occurrences 2 at hello.c, 15 1 at hello.c, 16
The INSURE SUMMARY section is a header that indicates the following information about the program being executed:
- The name of the program.
- Any command line arguments, if available.
- The directory from which the program was run.
- The time the program was compiled.
- The time the program was executed.
- The length of time needed to execute the program.
This information is provided so that test runs can be compared accurately as to the arguments and directory of test. The time and date information is supplied to correlate with bug tracking software.
The second section gives a summary of problems detected according to the error code and frequency. The first numeric column indicates the number of errors detected but not suppressed. This is the total number of errors, which might differ from the number reported, since, by default, only the first error of any particular type is reported at each source line. The second column indicates the number of bugs which were not displayed at all due to suppress
commands.
The third section gives details of the information presented in the second section, broken down into source files and line numbers.
Leak Summary
You can include the this report summary by enabling the Summarize: Leaks option in the Reports tab of the Insure++ Control Panel and re-running your program. Add the insure++.summarize leaks
option to your .psrc file and re-run your program to add this report summary.
The output indicates the memory (mis)use of the program, as shown below.
********************* INSURE SUMMARY ********* v7.4 ** * Program : leakscop * Arguments : * Directory : /home/Insure++/examples/c * Compiled on : Mar 26, 2007 13:15:27 * Run on : Mar 26, 2007 13:17:54 * Elapsed time : 00:00:00 * Malloc HWM : 10 bytes ****************************************************** PROBLEM SUMMARY - by type =============== Problem Reported Suppressed ------------------------------------------------- LEAK_SCOPE 1 0 ------------------------------------------------- TOTAL 1 0 ------------------------------------------------- PROBLEM SUMMARY - by location =============== LEAK_SCOPE: Memory leaked leaving scope, 1 unique occurrence 1 at leakscop.c, 10 MEMORY LEAK SUMMARY =================== 1 outstanding memory reference for 10 bytes. Leaks detected during execution ------------------------------- 10 bytes 1 chunk allocated at leakscop.c, 9 malloc() (interface) gimme() leakscop.c, 9 main() leakscop.c, 15 **************** INSURE SUMMARY ************** v7.4 ** Program : leak Arguments : Directory : C:\whicken\test Compiled on : Mar 12, 2007 15:09:05 Run on : Mar 12, 2007 15:09:31 Elapsed time : 00:00:02 ****************************************************** MEMORY LEAK SUMMARY =================== 4 outstanding memory references for 45 bytes. Leaks detected during execution ------------------------------- 10 bytes 1 chunk allocated at leak.c, 6 Leaks detected at exit ---------------------- 10 bytes 2 chunk allocated at leak.c, 7 Outstanding allocated memory ---------------------------- 15 bytes 1 chunk allocated at leak.c, 8
The first section summarizes the “memory leaks” which were detected during program execution, while the second lists leaked blocks that were detected at program exit. These are potentially serious errors, in that they typically represent continuously increasing use of system resources. If the program is “leaking” memory, it is likely to eventually exhaust the system resources and will probably crash.
The first number displayed is the total amount of memory lost at the indicated source line, and the second is the number of chunks of memory lost. Note that multiple chunks of different sizes may be lost at the same source line - depending on which options you are using.
To customize the report, there are three options available:
leak_combine
The leak_combine
option controls how Insure++ merges information about multiple blocks. The default behavior is to combine all information about leaks which were allocated from locations with identical stack traces (leak_combine trace
). It may be that you would rather combine all leaks based only on the file and line they were allocated, independent of the stack trace leading to that allocation. In that case, you would use leak_combine location
. Or, you may simply want one entry for each leak (leak_combine none
).
leak_sort
The leak_sort
option controls how the leaks are sorted after having been combined. The options are none
, location
, trace
, size
, and frequency
(size
is the default). Sorting by size lets you look at the biggest sources of leaks, sorting by frequency lets you look at the most often occurring source of leaks, and sorting by location provides an easy way to examine all your leaks.
leak_trace
The leak_trace
option causes a full stack trace of each allocation to be printed, in addition to the actual file and line where the allocation occurred.
The third section shows the blocks which are allocated to the program at its termination and which have valid pointers to them. Since the pointers allow the blocks to still be freed by the program (even though they are not), these blocks are not actually leaked. This section is only displayed if the outstanding keyword is used. Normally, these blocks do not cause problems, since the operating system will reclaim them when the program terminates. However, if your program is intended to run for extended periods, these blocks are potentially more serious.
Coverage Summary
You can include the this report summary on Windows by enabling the Summarize: Coverage option in the Reports tab of the Insure++ Control Panel and re-running your program. Add the insure++.summarize coverage
option to your .psrc file and re-run your program to add this report summary on Unix systems.
In addition to the normal error reports, the summary includes how much of the application's source code has been tested. The exact form of the output is controlled by the coverage_switches
option, which specifies the command line switches passed to the tca
command to create the output.
If this variable is not set, it defaults to the following setting:
coverage_switches tca -dS
(Windows)
insure++.coverage_switches tca -dS
(Unix)
The following example summary shows test coverage:
COVERAGE SUMMARY ================ 0 blocks untested 28 blocks tested 100% covered