-
Notifications
You must be signed in to change notification settings - Fork 35
Improve documentation related to unit tests #183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
gilles-peskine-arm
wants to merge
14
commits into
Mbed-TLS:main
Choose a base branch
from
gilles-peskine-arm:unit-test-docs-20250703
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
d6116ba
Update links to headers moved to the framework repository
gilles-peskine-arm f6ade98
Update the names of some helper macros
gilles-peskine-arm 3fe9bf2
Update code style
gilles-peskine-arm bcb4bef
Modernize .function file documentation
gilles-peskine-arm d5f2acf
Recommend using unit tests even for SSL
gilles-peskine-arm 93fd15c
Tips about running a selection of test cases
gilles-peskine-arm 4c244c0
Document mbedtls_test_set_step
gilles-peskine-arm af74960
Section on constant-flow testing
gilles-peskine-arm a657669
Debugging tip: reverse debugging with rr
gilles-peskine-arm f5fab75
Debugging tips: sanitizers, why and how
gilles-peskine-arm eb555f9
Debugging tips: all.sh component with debugging
gilles-peskine-arm dd6c76e
Add a section for presentations
gilles-peskine-arm 5fb3636
Upload presentation about unit tests
gilles-peskine-arm edc03c1
Fix markdown links
gilles-peskine-arm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # Presentations | ||
|
|
||
| ## For contributors | ||
|
|
||
| ### Coding | ||
|
|
||
| [Everything you wanted to know about Mbed TLS unit tests](<Everything you wanted to know about Mbed TLS unit tests.pdf>) | ||
|
|
||
| ### Reviews | ||
|
|
||
| [How to be an effective Mbed TLS reviewer](<../reviews/How to be an effective Mbed TLS reviewer.pdf>) | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,5 +40,6 @@ project/index.md | |
| reviews/index.md | ||
| security-advisories/index.md | ||
| CONTRIBUTING.md | ||
| docs/index.md | ||
| kb/index.md | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| # Tips for debugging Mbed TLS | ||
|
|
||
| This is a collection of tips for debugging TF-PSA-Crypto or Mbed TLS. | ||
| It may also be useful for debugging applications using these projects, but that is not this document's main purpose. | ||
|
|
||
| This document assumes some familiarity with the project, e.g. that you already know how to build and test it. | ||
|
|
||
| This document is written primarily with Linux in mind. Similar platforms such as macOS will require few adaptations. Windows (except WSL) is out of scope. | ||
|
|
||
| ## Reproducing CI builds with debugging | ||
|
|
||
| ### Getting the build products from `all.sh` | ||
|
|
||
| Normally, `all.sh` cleans up after itself. However, it will leave build products around if a compilation or runtime step fails. If you want to see build products from a passing component, add the command `false` after the build steps. | ||
|
|
||
| If you have a wrapper around `all.sh`, note that passing `--keep-going` (`-k`) makes it clean up on errors as well. | ||
|
|
||
| Cancelling `all.sh` with `Ctrl+C` (SIGINT) makes it clean up. But using `Ctrl+\\` (SIGQUIT) bypassing the cleanup. Also, you can use `Ctrl+Z` to inspect an intermediate step. | ||
|
|
||
| ### Editing `all.sh` for debugging | ||
|
|
||
| To reproduce an `all.sh` component locally, but with debugging enabled: | ||
|
|
||
| * For most builds using `make` (without CMake), in particular including all driver builds: add `ASAN_CFLAGS='-Og -g3'` or `ASAN_CFLAGS='-O0 -g3'` before the build step. | ||
| * For builds using CMake: add or change the build type to `Debug` or `ASanDbg`, e.g. `cmake -DCMAKE_BUILD_TYPE=Debug`. | ||
|
|
||
| After changing the source, you'll need to re-run `all.sh`, including its initial cleanup state which is not trivial to bypass. To speed this up, enable [ccache](https://ccache.dev/). In most `all.sh` components, you can enable ccache by setting | ||
| ``` | ||
| CC="ccache ${CC:cc}" ASAN_CC="ccache clang" | ||
| ``` | ||
|
|
||
| ## Sanitizers | ||
|
|
||
| ### Sanitizers used in test scripts | ||
|
|
||
| #### ASan: AddressSanitizer | ||
|
|
||
| * Documentation: https://github.com/google/sanitizers/wiki/addresssanitizer | ||
| * Detects: buffer overflows, use after free, memory leaks | ||
| * Compilers: GCC, Clang | ||
| * Compiler flags: `-fsanitize=address -fno-sanitize-recover=all` (in both `CFLAGS` and `LDFLAGS`) | ||
| * CMake build types: `ASan`, `ASanDbg` | ||
| * Used in: most builds in `all.sh` | ||
|
|
||
| #### MSan: MemorySanitizer | ||
|
|
||
| * Documentation: https://github.com/google/sanitizers/wiki/memorysanitizer | ||
| * Detects: uninitialized memory | ||
| * Compilers: GCC, Clang | ||
| * Compiler flags: `-fsanitize=memory` (in both `CFLAGS` and `LDFLAGS`) | ||
| * CMake build types: `MemSan`, `MemSanDbg` | ||
| * Used in: `component_test_memsan*` | ||
|
|
||
| #### TSan: ThreadSanitizer | ||
|
|
||
| * Documentation: https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual | ||
| * Detects: race conditions | ||
| * Compilers: GCC, Clang | ||
| * Compiler flags: `-fsanitize=thread` (in both `CFLAGS` and `LDFLAGS`) | ||
| * CMake build types: `TSan`, `TSanDbg` | ||
| * Used in: `component_test_tsan*` | ||
|
|
||
| #### UBSan: UndefinedBehaviorSanitizer | ||
|
|
||
| * Documentation: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html | ||
| * Detects: null pointer misuse, bitwise shift amount out of range, signed integer overflow, … | ||
| * Compilers: GCC, Clang | ||
| * Compiler flags: `-fsanitize=undefined` (in both `CFLAGS` and `LDFLAGS`) | ||
| * CMake build types: `ASan`, `ASanDbg` | ||
| * Used in: most builds in `all.sh` | ||
|
|
||
| ### Valgrind | ||
|
|
||
| Valgrind mostly duplicates Asan+Msan, but very occasionally finds something that they don't. | ||
|
|
||
| * Documentation: https://valgrind.org/docs/manual/manual.html | ||
| * Detects: buffer overflows, use after free, memory leaks, uninitialized memory | ||
| * We don't currently use it for race conditions. | ||
| * Compilers: any | ||
| * Compiler flags: N/A — runtime instrumentation only | ||
| * CMake target: `make memcheck` | ||
| * Run with: | ||
| ``` | ||
| valgrind -q --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=50 --log-file=myprogram.MemoryChecker.log myprogram | ||
| grep . myprogram.MemoryChecker.log myprogram | ||
| ``` | ||
| * Used in: `component_release_test_valgrind*` | ||
|
|
||
| ### Getting symbolic backtraces from symbolizers | ||
|
|
||
| By default, ASan/MSan/TSan/UBSan display traces without symbolic information. For traces with symbol names, you need to set environment variables: | ||
|
|
||
| ``` | ||
| export ASAN_OPTIONS=symbolize=1 | ||
| export MSAN_OPTIONS=symbolize=1 | ||
| export TSAN_OPTIONS=symbolize=1 | ||
| export UBSAN_OPTIONS=print_stacktrace=1 | ||
| ``` | ||
|
|
||
| With Clang, depending on how it's installed, you may need to specify the path to the correct version of `llvm-symbolizer` in `ASAN_SYMBOLIZER_PATH`, `MSAN_SYMBOLIZER_PATH` and `TSAN_SYMBOLIZER_PATH`. For example: | ||
|
|
||
| ``` | ||
| if ASAN_SYMBOLIZER_PATH=$(readlink -f "$(command -v clang)") && | ||
| ASAN_SYMBOLIZER_PATH="${ASAN_SYMBOLIZER_PATH%/*}/llvm-symbolizer" | ||
| then | ||
| export ASAN_SYMBOLIZER_PATH | ||
| export MSAN_SYMBOLIZER_PATH="$ASAN_SYMBOLIZER_PATH" | ||
| export TSAN_SYMBOLIZER_PATH="$ASAN_SYMBOLIZER_PATH" | ||
| fi | ||
| ``` | ||
|
|
||
| See [SanitizerCommonFlags](https://github.com/google/sanitizers/wiki/SanitizerCommonFlags) for more flags you can use in `$xxSAN_OPTIONS`. | ||
|
|
||
| ### Sanitizers for constant-time testing | ||
|
|
||
| See “[Mbed TLS test guidelines — Constant-flow testing](../development/test_suites.md#constant-flow-testing)”. | ||
|
|
||
| ## Reverse debugging | ||
|
|
||
| ### What is reverse debugging? | ||
|
|
||
| Also known as back-in-time debugging or time travel debugging. | ||
|
|
||
| Reverse debugging allows you to go backward in time when stepping through a program. For example, a reverse single step after returning from a function goes back to the function's `return` statement. | ||
|
|
||
| ### Tools for reverse debugging | ||
|
|
||
| * Gdb supports reverse debugging, but not out of the box, it requires some complex setup. | ||
| * LLDB does not support reverse debugging as of 2025. | ||
| * Visual Studio (under Windows) supports reverse debugging since 2017. | ||
|
|
||
| Reverse debugging works by taking snapshots of a program and recording its inputs and outputs. It may or may not work when the program interacts with its environment in complex ways, since the environment does not roll back when the program does. | ||
|
|
||
| ### Replay debuggers | ||
|
|
||
| A replay debugger records one execution of the program. It then replays this same execution, simulating all inputs and outputs. | ||
|
|
||
| #### Replay debugging on Linux with rr | ||
|
|
||
| Install the Mozilla Record and Replay framework (rr) from https://rr-project.org/ or e.g. `apt install rr`. | ||
|
|
||
| If needed, give yourself debugging permission: | ||
|
|
||
| ``` | ||
| # The Ubuntu default is 4 which is too paranoid. | ||
| sudo sysctl kernel.perf_event_paranoid=1. | ||
| # Make this persistent across reboots. | ||
| echo 'kernel.perf_event_paranoid = 1' >>/etc/sysctl.d/zz-local.conf | ||
| ``` | ||
|
|
||
| To debug a program, build it with debugging symbols as usual (`-O0 –g3` or `–Og -g3`). Then run it once to save a full trace of the execution: | ||
|
|
||
| ``` | ||
| rr record tests/test_suite_ssl | ||
| ``` | ||
|
|
||
| Then `rr replay` gives you a gdb interface where reverse execution actually works. You can use [`reverse-xxx` commands](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Reverse-Execution.html) such as: | ||
|
|
||
| * `rs` (`reverse-step`) steps into functions. | ||
| * `rn` (`reverse-next`) steps over function calls. | ||
| * `reverse-finish` goes back to where the current function was called. | ||
| * `set exec-direction reverse` changes `step`, `next`, etc. to go backwards. Switch this off with `set exec-direction forward`. | ||
|
|
||
| If you use a frontend, configure it to run `rr replay` instead of `gdb myprogram`. If the frontend uses gdb's machine interface, use `rr replay -i=mi …` instead of `gdb -i=mi …`. | ||
|
|
||
| #### Replay debugging on macOS with warpspeed | ||
|
|
||
| Try [warpspeed](https://github.com/kallsyms/warpspeed). | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mpg FYI