Clang documentation for UBSan.
Summary: Create a separate page describing UBSan tool, move the description of fine-grained checks there, provide extra information about supported platforms, symbolization etc. This text is compiled from four parts: * Existing documentation copied from User's Manual * Layout used in documentation for another sanitizers (ASan, MSan etc.) * Text written from scratch * Small parts taken from Michael Morrison's attempt at creating UBSan page: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20141215/249503.html Reviewers: kcc, rsmith, silvas Subscribers: tberghammer, danalbert, srhines, kcc Differential Revision: http://reviews.llvm.org/D15217 llvm-svn: 254733
This commit is contained in:
parent
e3c0d5996c
commit
778fc728ed
|
@ -0,0 +1,202 @@
|
|||
==========================
|
||||
UndefinedBehaviorSanitizer
|
||||
==========================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
UndefinedBehaviorSanitizer (UBSan) is a fast undefined behavior detector.
|
||||
UBSan modifies the program at compile-time to catch various kinds of undefined
|
||||
behavior during program execution, for example:
|
||||
|
||||
* Using misaligned or null pointer
|
||||
* Signed integer overflow
|
||||
* Conversion to, from, or between floating-point types which would
|
||||
overflow the destination
|
||||
|
||||
See the full list of available :ref:`checks <ubsan-checks>` below.
|
||||
|
||||
UBSan has an optional run-time library which provides better error reporting.
|
||||
The checks have small runtime cost and no impact on address space layout or ABI.
|
||||
|
||||
How to build
|
||||
============
|
||||
|
||||
Build LLVM/Clang with `CMake <http://llvm.org/docs/CMake.html>`_.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Use ``clang++`` to compile and link your program with ``-fsanitize=undefined``
|
||||
flag. Make sure to use ``clang++`` (not ``ld``) as a linker, so that your
|
||||
executable is linked with proper UBSan runtime libraries. You can use ``clang``
|
||||
instead of ``clang++`` if you're compiling/linking C code.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% cat test.cc
|
||||
int main(int argc, char **argv) {
|
||||
int k = 0x7fffffff;
|
||||
k += argc;
|
||||
return 0;
|
||||
}
|
||||
% clang++ -fsanitize=undefined test.cc
|
||||
% ./a.out
|
||||
test.cc:3:5: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
|
||||
|
||||
You can enable only a subset of :ref:`checks <ubsan-checks>` offered by UBSan,
|
||||
and define the desired behavior for each kind of check:
|
||||
|
||||
* print a verbose error report and continue execution (default);
|
||||
* print a verbose error report and exit the program;
|
||||
* execute a trap instruction (doesn't require UBSan run-time support).
|
||||
|
||||
For example if you compile/link your program as:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% clang++ -fsanitize=signed-integer-overflow,null,alignment -fno-sanitize-recover=null -fsanitize-trap=alignment
|
||||
|
||||
the program will continue execution after signed integer overflows, exit after
|
||||
the first invalid use of a null pointer, and trap after the first use of misaligned
|
||||
pointer.
|
||||
|
||||
.. _ubsan-checks:
|
||||
|
||||
Availablle checks
|
||||
=================
|
||||
|
||||
Available checks are:
|
||||
|
||||
- ``-fsanitize=alignment``: Use of a misaligned pointer or creation
|
||||
of a misaligned reference.
|
||||
- ``-fsanitize=bool``: Load of a ``bool`` value which is neither
|
||||
``true`` nor ``false``.
|
||||
- ``-fsanitize=bounds``: Out of bounds array indexing, in cases
|
||||
where the array bound can be statically determined.
|
||||
- ``-fsanitize=enum``: Load of a value of an enumerated type which
|
||||
is not in the range of representable values for that enumerated
|
||||
type.
|
||||
- ``-fsanitize=float-cast-overflow``: Conversion to, from, or
|
||||
between floating-point types which would overflow the
|
||||
destination.
|
||||
- ``-fsanitize=float-divide-by-zero``: Floating point division by
|
||||
zero.
|
||||
- ``-fsanitize=function``: Indirect call of a function through a
|
||||
function pointer of the wrong type (Linux, C++ and x86/x86_64 only).
|
||||
- ``-fsanitize=integer-divide-by-zero``: Integer division by zero.
|
||||
- ``-fsanitize=nonnull-attribute``: Passing null pointer as a function
|
||||
parameter which is declared to never be null.
|
||||
- ``-fsanitize=null``: Use of a null pointer or creation of a null
|
||||
reference.
|
||||
- ``-fsanitize=object-size``: An attempt to use bytes which the
|
||||
optimizer can determine are not part of the object being
|
||||
accessed. The sizes of objects are determined using
|
||||
``__builtin_object_size``, and consequently may be able to detect
|
||||
more problems at higher optimization levels.
|
||||
- ``-fsanitize=return``: In C++, reaching the end of a
|
||||
value-returning function without returning a value.
|
||||
- ``-fsanitize=returns-nonnull-attribute``: Returning null pointer
|
||||
from a function which is declared to never return null.
|
||||
- ``-fsanitize=shift``: Shift operators where the amount shifted is
|
||||
greater or equal to the promoted bit-width of the left hand side
|
||||
or less than zero, or where the left hand side is negative. For a
|
||||
signed left shift, also checks for signed overflow in C, and for
|
||||
unsigned overflow in C++. You can use ``-fsanitize=shift-base`` or
|
||||
``-fsanitize=shift-exponent`` to check only left-hand side or
|
||||
right-hand side of shift operation, respectively.
|
||||
- ``-fsanitize=signed-integer-overflow``: Signed integer overflow,
|
||||
including all the checks added by ``-ftrapv``, and checking for
|
||||
overflow in signed division (``INT_MIN / -1``).
|
||||
- ``-fsanitize=unreachable``: If control flow reaches
|
||||
``__builtin_unreachable``.
|
||||
- ``-fsanitize=unsigned-integer-overflow``: Unsigned integer
|
||||
overflows.
|
||||
- ``-fsanitize=vla-bound``: A variable-length array whose bound
|
||||
does not evaluate to a positive value.
|
||||
- ``-fsanitize=vptr``: Use of an object whose vptr indicates that
|
||||
it is of the wrong dynamic type, or that its lifetime has not
|
||||
begun or has ended. Incompatible with ``-fno-rtti``.
|
||||
|
||||
You can also use the following check groups:
|
||||
- ``-fsanitize=undefined``: All of the checks listed above other than
|
||||
``unsigned-integer-overflow``.
|
||||
- ``-fsanitize=undefined-trap``: Deprecated alias of
|
||||
``-fsanitize=undefined``.
|
||||
- ``-fsanitize=integer``: Checks for undefined or suspicious integer
|
||||
behavior (e.g. unsigned integer overflow).
|
||||
|
||||
Stack traces and report symbolization
|
||||
=====================================
|
||||
If you want UBSan to print symbolized stack trace for each error report, you
|
||||
will need to:
|
||||
|
||||
#. Compile with ``-g`` and ``-fno-omit-frame-pointer`` to get proper debug
|
||||
information in your binary.
|
||||
#. Run your program with environment variable
|
||||
``UBSAN_OPTIONS=print_stacktrace=1``.
|
||||
#. Make sure ``llvm-symbolizer`` binary is in ``PATH``.
|
||||
|
||||
Issue Suppression
|
||||
=================
|
||||
|
||||
UndefinedBehaviorSanitizer is not expected to produce false positives.
|
||||
If you see one, look again; most likely it is a true positive!
|
||||
|
||||
Disabling Instrumentation with ``__attribute__((no_sanitize("undefined")))``
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
You disable UBSan checks for particular functions with
|
||||
``__attribute__((no_sanitize("undefined")))``. You can use all values of
|
||||
``-fsanitize=`` flag in this attribute, e.g. if your function deliberately
|
||||
contains possible signed integer overflow, you can use
|
||||
``__attribute__((no_sanitize("signed-integer-overflow")))``.
|
||||
|
||||
This attribute may not be
|
||||
supported by other compilers, so consider using it together with
|
||||
``#if defined(__clang__)``.
|
||||
|
||||
Suppressing Errors in Recompiled Code (Blacklist)
|
||||
-------------------------------------------------
|
||||
|
||||
UndefinedBehaviorSanitizer supports ``src`` and ``fun`` entity types in
|
||||
:doc:`SanitizerSpecialCaseList`, that can be used to suppress error reports
|
||||
in the specified source files or functions.
|
||||
|
||||
Supported Platforms
|
||||
===================
|
||||
|
||||
UndefinedBehaviorSanitizer is supported on the following OS:
|
||||
|
||||
* Android
|
||||
* Linux
|
||||
* FreeBSD
|
||||
* OS X 10.6 onwards
|
||||
|
||||
and for the following architectures:
|
||||
|
||||
* i386/x86\_64
|
||||
* ARM
|
||||
* AArch64
|
||||
* PowerPC64
|
||||
* MIPS/MIPS64
|
||||
|
||||
Current Status
|
||||
==============
|
||||
|
||||
UndefinedBehaviorSanitizer is available on selected platforms starting from LLVM
|
||||
3.3. The test suite is integrated into the CMake build and can be run with
|
||||
``check-ubsan`` command.
|
||||
|
||||
More Information
|
||||
================
|
||||
|
||||
* From LLVM project blog:
|
||||
`What Every C Programmer Should Know About Undefined Behavior
|
||||
<http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html>`_
|
||||
* From John Regehr's *Embedded in Academia* blog:
|
||||
`A Guide to Undefined Behavior in C and C++
|
||||
<http://blog.regehr.org/archives/213>`_
|
|
@ -952,8 +952,6 @@ are listed below.
|
|||
``-fsanitize=address``:
|
||||
:doc:`AddressSanitizer`, a memory error
|
||||
detector.
|
||||
- ``-fsanitize=integer``: Enables checks for undefined or
|
||||
suspicious integer behavior.
|
||||
- .. _opt_fsanitize_thread:
|
||||
|
||||
``-fsanitize=thread``: :doc:`ThreadSanitizer`, a data race detector.
|
||||
|
@ -964,14 +962,8 @@ are listed below.
|
|||
widespread use.
|
||||
- .. _opt_fsanitize_undefined:
|
||||
|
||||
``-fsanitize=undefined``: Fast and compatible undefined behavior
|
||||
checker. Enables the undefined behavior checks that have small
|
||||
runtime cost and no impact on address space layout or ABI. This
|
||||
includes all of the checks listed below other than
|
||||
``unsigned-integer-overflow``.
|
||||
|
||||
- ``-fsanitize=undefined-trap``: This is a deprecated alias for
|
||||
``-fsanitize=undefined``.
|
||||
``-fsanitize=undefined``: :doc:`UndefinedBehaviorSanitizer`,
|
||||
a fast and compatible undefined behavior checker.
|
||||
|
||||
- ``-fsanitize=dataflow``: :doc:`DataFlowSanitizer`, a general data
|
||||
flow analysis.
|
||||
|
@ -980,14 +972,11 @@ are listed below.
|
|||
- ``-fsanitize=safe-stack``: :doc:`safe stack <SafeStack>`
|
||||
protection against stack-based memory corruption errors.
|
||||
|
||||
The following more fine-grained checks are also available:
|
||||
There are more fine-grained checks available: see
|
||||
the :ref:`list <ubsan-checks>` of specific kinds of
|
||||
undefined behavior that can be detected. Checks for :doc:`ControlFlowIntegrity`
|
||||
are:
|
||||
|
||||
- ``-fsanitize=alignment``: Use of a misaligned pointer or creation
|
||||
of a misaligned reference.
|
||||
- ``-fsanitize=bool``: Load of a ``bool`` value which is neither
|
||||
``true`` nor ``false``.
|
||||
- ``-fsanitize=bounds``: Out of bounds array indexing, in cases
|
||||
where the array bound can be statically determined.
|
||||
- ``-fsanitize=cfi-cast-strict``: Enables :ref:`strict cast checks
|
||||
<cfi-strictness>`.
|
||||
- ``-fsanitize=cfi-derived-cast``: Base-to-derived cast to the wrong
|
||||
|
@ -998,49 +987,6 @@ are listed below.
|
|||
the wrong dynamic type. Requires ``-flto``.
|
||||
- ``-fsanitize=cfi-vcall``: Virtual call via an object whose vptr is of the
|
||||
wrong dynamic type. Requires ``-flto``.
|
||||
- ``-fsanitize=enum``: Load of a value of an enumerated type which
|
||||
is not in the range of representable values for that enumerated
|
||||
type.
|
||||
- ``-fsanitize=float-cast-overflow``: Conversion to, from, or
|
||||
between floating-point types which would overflow the
|
||||
destination.
|
||||
- ``-fsanitize=float-divide-by-zero``: Floating point division by
|
||||
zero.
|
||||
- ``-fsanitize=function``: Indirect call of a function through a
|
||||
function pointer of the wrong type (Linux, C++ and x86/x86_64 only).
|
||||
- ``-fsanitize=integer-divide-by-zero``: Integer division by zero.
|
||||
- ``-fsanitize=nonnull-attribute``: Passing null pointer as a function
|
||||
parameter which is declared to never be null.
|
||||
- ``-fsanitize=null``: Use of a null pointer or creation of a null
|
||||
reference.
|
||||
- ``-fsanitize=object-size``: An attempt to use bytes which the
|
||||
optimizer can determine are not part of the object being
|
||||
accessed. The sizes of objects are determined using
|
||||
``__builtin_object_size``, and consequently may be able to detect
|
||||
more problems at higher optimization levels.
|
||||
- ``-fsanitize=return``: In C++, reaching the end of a
|
||||
value-returning function without returning a value.
|
||||
- ``-fsanitize=returns-nonnull-attribute``: Returning null pointer
|
||||
from a function which is declared to never return null.
|
||||
- ``-fsanitize=shift``: Shift operators where the amount shifted is
|
||||
greater or equal to the promoted bit-width of the left hand side
|
||||
or less than zero, or where the left hand side is negative. For a
|
||||
signed left shift, also checks for signed overflow in C, and for
|
||||
unsigned overflow in C++. You can use ``-fsanitize=shift-base`` or
|
||||
``-fsanitize=shift-exponent`` to check only left-hand side or
|
||||
right-hand side of shift operation, respectively.
|
||||
- ``-fsanitize=signed-integer-overflow``: Signed integer overflow,
|
||||
including all the checks added by ``-ftrapv``, and checking for
|
||||
overflow in signed division (``INT_MIN / -1``).
|
||||
- ``-fsanitize=unreachable``: If control flow reaches
|
||||
``__builtin_unreachable``.
|
||||
- ``-fsanitize=unsigned-integer-overflow``: Unsigned integer
|
||||
overflows.
|
||||
- ``-fsanitize=vla-bound``: A variable-length array whose bound
|
||||
does not evaluate to a positive value.
|
||||
- ``-fsanitize=vptr``: Use of an object whose vptr indicates that
|
||||
it is of the wrong dynamic type, or that its lifetime has not
|
||||
begun or has ended. Incompatible with ``-fno-rtti``.
|
||||
|
||||
You can turn off or modify checks for certain source files, functions
|
||||
or even variables by providing a special file:
|
||||
|
@ -1094,7 +1040,8 @@ are listed below.
|
|||
If the check is fatal, program will halt after the first error
|
||||
of this kind is detected and error report is printed.
|
||||
|
||||
By default, non-fatal checks are those enabled by UndefinedBehaviorSanitizer,
|
||||
By default, non-fatal checks are those enabled by
|
||||
:doc:`UndefinedBehaviorSanitizer`,
|
||||
except for ``-fsanitize=return`` and ``-fsanitize=unreachable``. Some
|
||||
sanitizers may not support recovery (or not support it by default
|
||||
e.g. :doc:`AddressSanitizer`), and always crash the program after the issue
|
||||
|
|
|
@ -24,6 +24,7 @@ Using Clang as a Compiler
|
|||
AddressSanitizer
|
||||
ThreadSanitizer
|
||||
MemorySanitizer
|
||||
UndefinedBehaviorSanitizer
|
||||
DataFlowSanitizer
|
||||
LeakSanitizer
|
||||
SanitizerCoverage
|
||||
|
|
Loading…
Reference in New Issue