Q: Can I debug libraries or objects I don't have the source for?
A: Yes, the debugging works by linking in an alternative run-time library, so the debugging will cover any linked sources.
Q: What's the performance like?
A: Obviously, there will be a performance impact, though we've tried to keep it to a minimum without affecting the function of the library. For each heap operation, additional checks will be carried out for validity, including a scan of the heap for corruption, so there will be a significant impact when debugging heavily used heaps.
The performance impact can be mitigated in 2 ways:
The debugging can be paused and re-enabled at run time via a function call, allowing you to debug parts of your application at once, or to avoid the overhead in critical sections which you are satisfied are ok.
The debugging library by default writes to an output file on each heap operation, which can be very time intensive. Buffering this output means that less I/O calls are performed, saving the set-up and transfer time for the I/O operation.
Q: What if I don't want a report file?
A: Report file generation can be turned off using adi_heap_debug_disable(_HEAP_HPL_GEN). stderr reporting can be enabled in its place via adi_heap_debug_enable(_HEAP_STDERR_DIAG).
Q: Can I find out the current state of the heap?
A: A function, adi_heap_debug_dump_heap(filename, heapindex), is provided which will print a dump of the current state of the specified heap to the specified text file.
*Note: The dump doesn't include memory used by the heap debugging or run-time libraries.
Q: Can I find out if the heap is currently corrupt?
A: A function, adi_verify_heap(heapindex) will return true if the heap is currently valid, false otherwise.
Q: I've turned on heap debugging and now get unexpected values in my data, what's happened?
A: The debugging library pre-fills heap data which shouldn't be read with a known bit pattern: 0xBD for free/unused heap space, 0xDD for allocated space that has been uninitialized, and 0xED for guard regions around allocated blocks.
0xBD in your data would indicate reading from de-allocated memory,
0xDD in your data would indicate reading from allocated memory that hasn't been initialized yet,
0xED in your data would indicate reading beyond the scope of the allocated block (buffer underflow or overflow).
These patterns are deliberately misaligned so as to trigger a misaligned data exception on Blackfin, if used as a pointer.
Q: What are realloc_free and realloc_alloc operations?
A: The debugging library splits a call to realloc() into 2 components; the allocation and the free, reporting each separately. Even if there is space to re-use the block, the debug realloc will always allocate new memory, copy the data over and then de-allocate the memory, to catch the case where reads from the old pointer happen to work when the block is re-used.
x = malloc(12);
*x = 1;
y = realloc(x, 4);
z = *x;
if x is re-used then z==1, otherwise it is uninitialized. With debugging on, z==0xBDBDBDBD.
The intended code would be:
z = *y;
Q: What is the 512 bytes allocated from flushwritebuf for?
A: Those 512 bytes are allocated as buffer for the stdout I/O stream.
Q: Why isn't the I/O buffer de-allocated?
A: For performance/code size reasons the I/O buffers are never de-allocated, even at program termination, because there is no behavioural benefit in doing so.
Q: Why doesn't the leaked I/O buffer generate an error?
A: The library checks for and ignores any unfreed I/O buffers, as they do not represent a problem.
Q: What are the "addressable units" mentioned in the report?
A: The addressable units in the report refer to the native memory word size of the architecture. For Blackfin this is 8-bit units, whereas on SHARC this is 32-bit units.