Most of the checks performed by sanitizers operate at a global level, which means they can detect issues even when they span across language boundaries. This applies notably to:
An interesting case that highlights the benefit of global sanitization is a buffer overflow caused by a mismatch in language bindings. Consider the following C function, which allocates an array of 4 characters:
char *get_str (void) { char *str = malloc (4 * sizeof (char)); }
This function is then bound to Ada code, which incorrectly assumes the buffer is of size 5:
type Buffer is array (1 .. 5) of Character; function Get_Str return access Buffer with Import => True, Convention => C, External_Name => "get_str"; Str : access Buffer := Get_Str; Ch : Character := S (S'Last); -- Detected by AddressSanitizer as erroneous
On the Ada side, accessing Str (5)
appears valid because the array type
declares five elements. However, the actual memory allocated in C only holds
four. This mismatch is not detectable by Ada run-time checks, because Ada has
no visibility into how the memory was allocated.
However, the AddressSanitizer will detect the heap buffer overflow at runtime, halting execution and providing a clear diagnostic:
... SUMMARY: AddressSanitizer: heap-buffer-overflow buffer_overflow.adb:20 in _ada_buffer_overflow ...