Author: Andrew Lazarev
Date: 2026-09-04T00:49:31-07:00
New Revision: c879c054965d191b5d8df1f5da4c36f6ac6dd37b

URL: 
https://github.com/llvm/llvm-project/commit/c879c054965d191b5d8df1f5da4c36f6ac6dd37b
DIFF: 
https://github.com/llvm/llvm-project/commit/c879c054965d191b5d8df1f5da4c36f6ac6dd37b.diff

LOG: [clang][docs] Document compile-time sanitizer suppressions and options 
(#218793)

Document compile-time default suppressions
(`__<sanitizer>_default_suppressions`) and default options
(`__<sanitizer>_default_options`) across AddressSanitizer,
LeakSanitizer, and ThreadSanitizer. Document all supported suppression
types for ASan and TSan, programmatic leak checking interfaces for LSan,
and explain independent options evaluation when ASan runs with
integrated LSan/UBSan.

Fixes https://github.com/google/sanitizers/issues/1628

**AI tool usage:** An AI assistant was used to help research and draft
the documentation updates.

Added: 
    

Modified: 
    clang/docs/AddressSanitizer.md
    clang/docs/LeakSanitizer.md
    clang/docs/ThreadSanitizer.md

Removed: 
    


################################################################################
diff  --git a/clang/docs/AddressSanitizer.md b/clang/docs/AddressSanitizer.md
index 160c63dce2d97..d61c1d99f31e4 100644
--- a/clang/docs/AddressSanitizer.md
+++ b/clang/docs/AddressSanitizer.md
@@ -177,6 +177,43 @@ For more information on leak detector in AddressSanitizer, 
see
 and can be enabled using `ASAN_OPTIONS=detect_leaks=1` on macOS;
 however, it is not yet supported on other platforms.
 
+## Flags and Options
+
+Runtime flags can be passed to AddressSanitizer via the `ASAN_OPTIONS` 
environment
+variable:
+
+```console
+$ ASAN_OPTIONS="verbosity=1:detect_stack_use_after_return=1" ./a.out
+```
+
+To see the full list of available flags, run an instrumented binary with
+`ASAN_OPTIONS="help=1"`.
+
+Flags passed via the `ASAN_OPTIONS` environment variable take precedence over
+compile-time default options.
+
+### Compile-time Default Options
+
+Default options can be specified at compile/link time by defining
+the `__asan_default_options` function in your source code:
+
+```c++
+#include <sanitizer/asan_interface.h>
+
+extern "C" const char *__asan_default_options() {
+  return "verbosity=1:detect_stack_use_after_return=1";
+}
+```
+
+### Options Evaluation with Integrated Sanitizers
+
+When running AddressSanitizer with integrated {doc}`LeakSanitizer` or 
{doc}`UndefinedBehaviorSanitizer`:
+
+- `__asan_default_options()`, `__lsan_default_options()`, and 
`__ubsan_default_options()` are all evaluated independently by the runtime.
+- The environment variables `ASAN_OPTIONS`, `LSAN_OPTIONS`, and 
`UBSAN_OPTIONS` are also parsed independently.
+
+LSan and UBSan flags should be passed via their own environment variables 
(`LSAN_OPTIONS`, `UBSAN_OPTIONS`) or default option hooks 
(`__lsan_default_options()`, `__ubsan_default_options()`) rather than packed 
into `ASAN_OPTIONS` or `__asan_default_options()`.
+
 ## Issue Suppression
 
 AddressSanitizer is not expected to produce false positives. If you see one,
@@ -199,15 +236,34 @@ path of the file relative to the location of your 
executable.
 ASAN_OPTIONS=suppressions=MyASan.supp
 ```
 
-Use the following format to specify the names of the functions or libraries
-you want to suppress. You can see these in the error report. Remember that
-the narrower the scope of the suppression, the more bugs you will be able to
-catch.
+Each non-empty line of the suppression file represents one suppression of the
+form `suppression_type:suppression_pattern`. Supported types are:
+
+- `interceptor_via_fun`: Suppress errors when the given function is in the 
caller stack trace.
+- `interceptor_via_lib`: Suppress errors when the call originates from the 
given library.
+- `interceptor_name`: Suppress an interceptor by function name directly (e.g., 
`interceptor_name:memcpy`).
+- `odr_violation`: Suppress One Definition Rule violation reports for global 
variables.
+- `alloc_dealloc_mismatch`: Suppress allocation/deallocation mismatch errors 
for specific functions in the stack trace.
 
 ```bash
 interceptor_via_fun:NameOfCFunctionToSuppress
 interceptor_via_fun:-[ClassName objCMethodToSuppress:]
 interceptor_via_lib:NameOfTheLibraryToSuppress
+interceptor_name:memcpy
+odr_violation:my_global_var
+alloc_dealloc_mismatch:my_allocator_fn
+```
+
+Alternatively, you can provide default suppressions at compile time by defining
+the `__asan_default_suppressions` function in your source code:
+
+```c++
+#include <sanitizer/asan_interface.h>
+
+extern "C" const char *__asan_default_suppressions() {
+  return "interceptor_via_lib:NameOfTheLibraryToSuppress\n"
+         "interceptor_name:memcpy\n";
+}
 ```
 
 ### Conditional Compilation with `__has_feature(address_sanitizer)`
@@ -362,18 +418,10 @@ src:bad/init/files/*=init
 
 ### Suppressing memory leaks
 
-Memory leak reports produced by {doc}`LeakSanitizer` (if it is run as a part
-of AddressSanitizer) can be suppressed by a separate file passed as
-
-```bash
-LSAN_OPTIONS=suppressions=MyLSan.supp
-```
-
-which contains lines of the form `leak:<pattern>`. Memory leak will be
-suppressed if pattern matches any function name, source file name, or
-library name in the symbolized stack trace of the leak report. See
-[full 
documentation](https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions)
-for more details.
+Memory leak reports produced by {doc}`LeakSanitizer` (when run as part of
+AddressSanitizer) can be suppressed at runtime via 
`LSAN_OPTIONS=suppressions=...`
+or at compile time via `__lsan_default_suppressions()`. See 
{doc}`LeakSanitizer`
+for full details on suppression rules, default options, and programmatic APIs.
 
 ## Code generation control
 

diff  --git a/clang/docs/LeakSanitizer.md b/clang/docs/LeakSanitizer.md
index 816c976c0e231..32cf0563f1c91 100644
--- a/clang/docs/LeakSanitizer.md
+++ b/clang/docs/LeakSanitizer.md
@@ -40,6 +40,136 @@ To use LeakSanitizer in stand-alone mode, link your program 
with
 link step, so that it would link in proper LeakSanitizer run-time library
 into the final executable.
 
+## Suppressions
+
+LeakSanitizer reports can be suppressed if you encounter leaks in third-party
+libraries or known locations that cannot be fixed immediately.
+
+### Suppression Format
+
+Each suppression rule is specified on its own line in the form:
+
+```text
+leak:<pattern>
+```
+
+A memory leak is suppressed if `<pattern>` matches any function name, source
+file name, or library/module name in the symbolized stack trace of the leak
+report. Wildcards (`*`) are supported, and lines starting with `#` are treated
+as comments.
+
+Example suppression rules:
+
+```text
+# Suppress leak by function name (supports wildcards)
+leak:MyKnownLeakyFunction
+leak:*LeakyNamespace::*
+
+# Suppress leak by source file name
+leak:third_party/leaky_library.cpp
+
+# Suppress leak by shared library / module name
+leak:libcrypto.so
+```
+
+### Runtime Suppressions
+
+To specify a suppressions file at runtime, pass its path via the `suppressions`
+flag in the `LSAN_OPTIONS` environment variable:
+
+```console
+$ LSAN_OPTIONS="suppressions=MyLSan.supp" ./a.out
+```
+
+(When running LeakSanitizer as part of AddressSanitizer, `LSAN_OPTIONS` is 
still
+used to pass LeakSanitizer-specific flags and suppressions.)
+
+### Compile-time Default Suppressions
+
+You can embed default suppressions directly into your executable at 
compile/link
+time by defining the `__lsan_default_suppressions` function in your source 
code:
+
+```c++
+#include <sanitizer/lsan_interface.h>
+
+extern "C" const char *__lsan_default_suppressions() {
+  return "leak:MyKnownLeakyFunction\n"
+         "leak:third_party/leaky_library.cpp\n"
+         "leak:libcrypto.so\n";
+}
+```
+
+Both default suppressions and suppressions passed in the file via
+`LSAN_OPTIONS="suppressions=..."` will be parsed and applied.
+
+### Programmatic Disabling
+
+LeakSanitizer provides fine-grained programmatic control over leak detection
+via `<sanitizer/lsan_interface.h>`:
+
+- **Disable around specific code blocks**: Allocations made between calls to
+  `__lsan_disable()` and `__lsan_enable()` will not be reported as leaks. This
+  disabling is thread-local and only affects allocations made by the calling 
thread.
+  In C++, you can use the RAII wrapper `__lsan::ScopedDisabler`:
+
+  ```c++
+  #include <sanitizer/lsan_interface.h>
+
+  void foo() {
+    __lsan::ScopedDisabler disabler;
+    // Allocations made here will not be reported as leaks.
+    leaky_third_party_init();
+  }
+  ```
+
+- **Ignore specific objects**: `__lsan_ignore_object(const void *p)` marks the
+  heap object pointed to by `p` (and anything reachable from it) as a non-leak.
+
+- **Register custom root regions**: `__lsan_register_root_region(const void 
*p, size_t size)`
+  and `__lsan_unregister_root_region(const void *p, size_t size)` register 
memory
+  areas (such as custom memory pools or mapped regions) to be scanned for live
+  pointers during leak checking.
+
+- **Explicit leak checking**: `__lsan_do_leak_check()` triggers an immediate
+  leak check. If leaks are detected and the `exitcode` flag is non-zero 
(default),
+  the process terminates; otherwise, it returns normally. Calling this function
+  disables subsequent automatic leak checks at process exit.
+  `__lsan_do_recoverable_leak_check()` performs a leak check and returns `0` if
+  no leaks were detected (or if leak detection is disabled), and `1` if leaks
+  were found. It prints a report without terminating the process or disabling
+  the end-of-process check.
+
+- **Disable leak checking entirely**: Define `__lsan_is_turned_off()` to return
+  `1` to disable leak checking for the program.
+
+## Flags and Options
+
+Runtime flags can be passed to LeakSanitizer via the `LSAN_OPTIONS` environment
+variable:
+
+```console
+$ LSAN_OPTIONS="print_suppressions=0:report_objects=1" ./a.out
+```
+
+To see the full list of available flags, run an instrumented binary with
+`LSAN_OPTIONS="help=1"`.
+
+Flags passed via the `LSAN_OPTIONS` environment variable take precedence over
+compile-time default options.
+
+### Compile-time Default Options
+
+Default options can also be specified at compile/link time by defining
+`__lsan_default_options`:
+
+```c++
+#include <sanitizer/lsan_interface.h>
+
+extern "C" const char *__lsan_default_options() {
+  return "print_suppressions=0:report_objects=1";
+}
+```
+
 ## Security Considerations
 
 LeakSanitizer is a bug detection tool and its runtime is not meant to be
@@ -58,4 +188,3 @@ constraints in mind and may compromise the security of the 
resulting executable.
 ## More Information
 
 
[https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer)
-

diff  --git a/clang/docs/ThreadSanitizer.md b/clang/docs/ThreadSanitizer.md
index 244f2ffee0a19..7f48a7470e254 100644
--- a/clang/docs/ThreadSanitizer.md
+++ b/clang/docs/ThreadSanitizer.md
@@ -273,6 +273,20 @@ You can also refer to the source declarations in the LLVM 
repository under
 and `compiler-rt/lib/sanitizer_common/sanitizer_flags.inc` (common sanitizer
 flags).
 
+Flags passed via the `TSAN_OPTIONS` environment variable take precedence over
+compile-time default options.
+
+Default options can also be specified at compile/link time by defining
+`__tsan_default_options`:
+
+```c++
+#include <sanitizer/tsan_interface.h>
+
+extern "C" const char *__tsan_default_options() {
+  return "report_atomic_races=0:halt_on_error=1";
+}
+```
+
 ## Suppressions
 
 If you have a data race or thread leak that you are already aware of but cannot
@@ -286,6 +300,18 @@ Specify the suppressions file path via the `suppressions` 
flag in the
 $ TSAN_OPTIONS="suppressions=/path/to/suppressions.supp" ./myprogram
 ```
 
+Alternatively, you can provide default suppressions at compile time by defining
+the `__tsan_default_suppressions` function in your source code:
+
+```c++
+#include <sanitizer/tsan_interface.h>
+
+extern "C" const char *__tsan_default_suppressions() {
+  return "race:foobar\n"
+         "race:NuclearRocket::Launch\n";
+}
+```
+
 Each non-empty line of the suppressions file represents one suppression of the
 form:
 
@@ -297,8 +323,12 @@ The supported `suppression_type` values are:
 
 - `race`: Suppresses data race reports. The pattern is matched against function
   names, source file names, or global variable names in the stacks of the 
report.
+- `race_top`: Suppresses data race reports only when matching the top frame of 
the stack trace.
+- `mutex`: Suppresses mutex-related invalid operations (double lock, invalid 
unlock, unlock from wrong thread, etc.).
 - `thread`: Suppresses thread leak reports. The pattern is matched against the
   name of the leaked thread.
+- `signal`: Suppresses signal-unsafe handler warnings and errno usage in 
signal handlers.
+- `deadlock`: Suppresses lock inversion / deadlock reports.
 - `called_from_lib`: Suppresses reports if the call originated from a specific
   non-instrumented library.
 
@@ -312,6 +342,8 @@ Example of a suppressions file:
 ```text
 # Suppress data races in a third-party library 'foobar'
 race:foobar
+# Suppress data races matching the top stack frame
+race_top:MyFrame
 # Suppress data races in a specific function
 race:NuclearRocket::Launch
 # Suppress data races in a specific source file
@@ -320,6 +352,12 @@ race:src/surgery/laser_scalpel.cc
 race:global_var
 # Suppress a leaked thread by name
 thread:MonitoringThread
+# Suppress mutex misuse in a specific function
+mutex:bad_mutex_fn
+# Suppress signal-unsafe handler warnings
+signal:signal_handler
+# Suppress lock inversion / deadlock in a function
+deadlock:potential_deadlock_fn
 # Suppress warnings called from an uninstrumented library
 called_from_lib:libzmq.so
 ```


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to