• No results found

Pointer Error Detection and Validity Checking

Once you have enabled memory debugging and started debugging, all calls to the allocation and deallocation routines of heap memory will be intercepted and monitored. This allows both for automatic monitoring for errors, and for user driven inspection of pointers.

11.4.1 Library Usage Errors

If the memory debugging library reports an error Allinea DDT will display a window similar to the one shown below. This briefly reports the type of error detected and gives the option of continuing to play the program, or pausing execution.

Fig 69: Memory Error Message

If you choose to pause the program then Allinea DDT will highlight the line of your code that was being executed when the error was reported.

Often this is enough to debug simple memory errors, such as freeing or dereferencing an unallocated variable, iterating past the end of an array and so on – as the local variables and variables on the current line will provide insight into what is happening.

If the cause of the issue is still not clear, then it is possible to examine some of the pointers referenced to see whether they're valid and which line they were allocated on, as we now explain.

11.4.2 View Pointer Details

Any of the variables or expressions in the Evaluate window can be right-clicked on to bring up a menu. If memory debugging is enabled, View Pointer Details will be available. This will display the amount of memory allocated to the pointer and which part of your code originally allocated that memory:

Fig 70: Pointer details

Clicking on any of the stack frames will display the relevant section of your code, so that you can see where the variable was allocated.

Note: Only a single stack frame will be displayed if the Store stack backtraces for memory allocations option is disabled.

This feature can also be used to check the validity of heap allocated memory.

Note: Memory allocated on the heap refers to memory allocated by malloc, ALLOCATE, new and so on. A pointer may also point to a local variable, in which case DDT will tell you it does not point to data on the heap. This can be useful, since a common error is taking a pointer to a local variable that later goes out of scope.

Fig 71: Invalid memory message

This is particularly useful for checking function arguments, and key variables when things seem to be going awry. Of course, just because memory is valid doesn't mean it is the same type as you were expecting, or of the same size, or the same dimensions and so on.

Memory Type/Location

As well as invalid addresses, DDT can often tell you the type/location of the memory being pointed to. The different types are listed below.

Note: DDT may only be able to identify certain memory types with higher levels of memory debugging (see 11.3 Configuration for more information).

• Null pointer.

• Valid heap allocation.

• Fence-post area beyond the end of an allocation. • Freed heap allocation.

• Fence-post area before the beginning of a freed allocation. • Fence-post area beyond the end a freed allocation.

• A valid GPU heap allocation. • An address on the stack.

• The program's code section (or a shared library). • The program's data section (or a shared library).

• The program's bss section or Fortran COMMON block (or a shared library). • The program's executable (or a shared library).

• A memory mapped file.

For more information on fencepost checking, see 11.4.4 Fencepost Checking

11.4.3 Writing Beyond An Allocated Area

Use Heap Overflow /Underflow Detection option to detect read or writes beyond or before an allocated block. Any attempts to read or write to the specified number of pages before or after the block will cause a segmentation violation that stops your program. Add the guard pages after the block to detect heap overflows, or before to detect heap underflows. The default value of 1 page will catch most heap overflow errors but if this doesn’t work a good rule of thumb is to set the number of guard pages according to the size of a row in your largest array. The exact size of a memory page depends on your operating system but a typical size is 4Kb. So if a row of your largest array is 64Kb then set the number of pages to 64/4 = 16.

11.4.4 Fencepost Checking

DDT will also perform 'Fencepost' checking whenever the Heap Debugging setting is not set to Fast. In this mode, an extra portion of memory is allocated at the start and/or end of your allocated block, and a pattern is written into this area. If you attempt to write beyond your data, say by a few elements, then this will be noticed by DDT, however your program will not be stopped at the exact location at which your program wrote beyond the allocated data – it will only stop at the next heap consistency check.

11.4.5 Suppressing an Error

If DDT stops at an error but you wish to ignore the error (for example, it may be in a third party library you cannot fix) then you may check the Suppress memory errors from this line in future. This will open the Suppress Memory Errors window. Here you may select which function you want to suppress errors from.