In this section:
Error messages generated by Insure++ identify most programming problems, but it will sometimes be useful to have direct access to the information known to Insure++. This can be useful in the following situations:
- You are running your program from a debugger and would like to cause a breakpoint whenever Insure++ discovers a problem.
- You are tracing an error using the debugger and would like to monitor what Insure++ knows about your code.
- You wish to add calls to your program to periodically check the status of some data.
Insure++ is a debugger program and requires symbol table information. Always use debug builds instead of release builds during compiling and linking. Otherwise, applications will be compiled without the /Zi flag and linked without the /DEBUG flag, which results in unreported errors.
Whenever Insure++ detects an error, it prints a diagnostic message and then calls the routine
_Insure_trap_error. This is a good place to insert a breakpoint if you are working with a debugger.
The following functions show the current status of memory and can be called either from your program or the debugger. Remember to add prototypes for the functions you use, particularly if you are calling these C functions from C++ code.
void _Insure_mem_info(void *pmem);
Displays information that is known about the block of memory at address
pmem. Returns zero.
void _Insure_ptr_info(void **pptr);
Displays information about the pointer at the indicated address. Returns zero.
The following function lists all currently allocated memory blocks, including the line number at which they were allocated. It can be called directly from your program or from the debugger.
size_t _Insure_list_allocated_memory(unsigned int mode);
Use the following options to select a mode:
0- Just the total allocation
1- “Newly-Allocated” or reallocated blocks
See also void _Insure_new_leak_summary().
Example Debugging Session (Unix)
The instructions in this example assume that the debugger you are using is similar to gdb. If you are using another debugger, similar commands should be available.
This example uses the following code:
Begin by compiling this code with Insure++ using the
-Zi option and start the debugger in the normal manner.
In general, adding a breakpoint in
_Insure_trap_error is useful because it enables you to take control of the program whenever an error occurs. In this case, we run the program to the error location with the following result:
Setting a breakpoint per this example may not work if you have linked against the shared Insure++ libraries (the default). If you cannot set a breakpoint as shown above, it is because the shared libraries are not loaded by the debugger until the program begins to run. You can avoid this problem by setting a breakpoint on
main and running the program until that breakpoint is hit, then setting the breakpoint on
The program is attempting to free a block of memory by passing a pointer that doesn’t indicate the start of an allocated block. The error message shown by Insure++ identifies the location at which the block was allocated and also shows us that the variable
p has been changed to point to the middle of the block, but it doesn’t tell us where the value of
We can use the Insure++ functions from the debugger to help track this down. Since the program is already in the debugger, we can simply add a breakpoint back in
main and restart it.
To see what is currently known about the pointers
q, we can use the
_Insure_ptr_info function. This function expect the address of the pointer to be passed, not the pointer, itself. To see the contents of the memory indicated by the pointers, use the
Both pointers are currently uninitialized, as would be expected. To see something more interesting, we can continue to line 13 and repeat the previous steps.
p now points to a block of allocated memory. You can check on all allocated memory by calling
Finally, we check on the second pointer
Everything seems OK at this point, so we can continue to the point at which the memory is freed and check again.
The critical information here is that the pointer now points to an offset 7 bytes from the beginning of the allocated block. Executing the next statement,
free(p), will now cause the previously shown error. This is because the pointer doesn’t point to the beginning of the allocated block anymore. Everything was correct at line 12 but is broken at line 15, so it is simple to find the problem in line 13, where pointer
p is incremented while looping over