UndefinedBehaviorSanitizer (aka UBSan) modifies the program at compile-time to catch various kinds of undefined behavior during program execution.
Different sanitize options (-fsanitize=alignment,float-cast-overflow,signed-integer-overflow
)
detect the following types of problems:
The -fsanitize=alignment
flag (included also in
-fsanitize=undefined
) enables run-time checks for misaligned memory
accesses, ensuring that objects are accessed at addresses that conform to the
alignment constraints of their declared types. Violations may lead to crashes
or performance penalties on certain architectures.
In the following example:
with Ada.Text_IO; use Ada.Text_IO; with System.Storage_Elements; use System.Storage_Elements; procedure Misaligned_Address is type Aligned_Integer is new Integer with Alignment => 4; -- Ensure 4-byte alignment Reference : Aligned_Integer := 42; -- Properly aligned object -- Create a misaligned object by modifying the address manually Misaligned : Aligned_Integer with Address => Reference'Address + 1; begin -- This causes undefined behavior or an alignment exception on strict architectures Put_Line ("Misaligned Value: " & Aligned_Integer'Image (Misaligned)); end Misaligned_Address;
If the code is built with the -fsanitize=alignment
and -g
options, the following error is shown at execution time.
misaligned_address.adb:15:51: runtime error: load of misaligned address 0xffffd836dd45 for type 'volatile misaligned_address__aligned_integer', which requires 4 byte alignment
Ada performs range checks at runtime in arithmetic operation on signed integers
to ensure the value is within the target type’s bounds. If this check is removed,
the -fsanitize=signed-integer-overflow
flag (included also in
-fsanitize=undefined
) enables run-time checks for signed integer
overflows.
In the following example:
procedure Signed_Integer_Overflow is type Small_Int is range -128 .. 127; X, Y, Z : Small_Int with Export; begin X := 100; Y := 50; -- This addition will exceed 127, causing an overflow Z := X + Y; end Signed_Integer_Overflow;
If the code is built with the -fsanitize=signed-integer-overflow
and
-g
options, the following error is shown at execution time.
signed_integer_overflow.adb:8:11: runtime error: signed integer overflow: 100 + 50 cannot be represented in type 'signed_integer_overflow__small_int'
When converting a floating-point value to an integer type, Ada performs a range check at runtime to ensure the value is within the target type’s bounds. If this check is removed, the sanitizer can detect overflows in conversions from floating point to integer types.
In the following code:
procedure Float_Cast_Overflow is Flt : Float := Float'Last with Export; Int : Integer; begin Int := Integer (Flt); -- Overflow end Float_Cast_Overflow;
If the code is built with the -fsanitize=float-cast-overflow
and
-g
options, the following error is shown at execution time.
float_cast_overflow.adb:5:20: runtime error: 3.40282e+38 is outside the range of representable values of type 'integer'