-
Notifications
You must be signed in to change notification settings - Fork 488
docs: record the environment an ASan build needs #12736
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -608,6 +608,49 @@ Downstream packaging may or may not choose to distribute them, at their | |
| discretion. **We strongly encourage downstream users of Slang to move to the | ||
| new library names as soon as they are able.** | ||
|
|
||
| ## Building with AddressSanitizer | ||
|
|
||
| Configuring with `-DSLANG_ENABLE_ASAN=ON` needs two environment settings that are easy to miss, | ||
| because without them the build fails partway through for reasons that do not mention the sanitizer. | ||
|
|
||
| ```bash | ||
| # 1. The build compiles and then *runs* its own generators (slang-embed, slang-fiddle). Under | ||
| # SLANG_ENABLE_ASAN they are instrumented and link the ASan runtime dynamically, so the runtime | ||
| # must be locatable or they fail to start: | ||
| # slang-embed: error while loading shared libraries: libclang_rt.asan-x86_64.so: | ||
| # cannot open shared object file: No such file or directory | ||
| export LD_LIBRARY_PATH="$(clang -print-runtime-dir):$LD_LIBRARY_PATH" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -euo pipefail
unset LD_LIBRARY_PATH
unsafe="runtime:${LD_LIBRARY_PATH-}"
safe="runtime${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
test "$unsafe" = "runtime:"
test "$safe" = "runtime"Repository: shader-slang/slang Length of output: 156 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- docs/building.md ---'
sed -n '600,655p' docs/building.md
printf '%s\n' '--- relevant loader-path references ---'
rg -n -C 3 'LD_LIBRARY_PATH|clang -print-runtime-dir' docs cmakeRepository: shader-slang/slang Length of output: 6096 🌐 Web query:
💡 Result: In the Linux dynamic linker (ld.so), an empty path element within the LD_LIBRARY_PATH environment variable is interpreted as the current working directory [1][2][3]. According to the official ld.so(8) manual page, LD_LIBRARY_PATH is defined as a list of directories separated by colons or semicolons, and a zero-length directory name (e.g., resulting from a leading colon, trailing colon, or consecutive colons like::) explicitly indicates that the dynamic linker should search the current working directory [1][4][3]. This behavior is a legacy feature consistent with the treatment of the PATH environment variable in POSIX systems [5][6]. Because this behavior can cause the linker to load arbitrary libraries from the current directory—potentially leading to security vulnerabilities if an attacker introduces malicious shared objects into that directory—it is generally recommended to avoid empty elements in LD_LIBRARY_PATH [7]. This variable is also ignored entirely when the program is executed in secure-execution mode (such as for set-user-ID or set-group-ID binaries) to mitigate such risks [1][3]. Citations:
Avoid empty entries in When |
||
|
|
||
| # 2. Those same generators leak, and LeakSanitizer's non-zero exit status fails the build: | ||
| # ERROR: LeakSanitizer: detected memory leaks | ||
| # SUMMARY: AddressSanitizer: 828842 byte(s) leaked in 3661 allocation(s) | ||
| # They are short-lived build tools, so leak detection is not meaningful for them. | ||
| export ASAN_OPTIONS=detect_leaks=0 | ||
|
Comment on lines
+624
to
+628
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Scope The exported variable remains active after Proposed documentation change-export ASAN_OPTIONS=detect_leaks=0
-
-cmake --preset default -DSLANG_ENABLE_ASAN=ON
-cmake --build --preset release
+ASAN_OPTIONS=detect_leaks=0 cmake --preset default -DSLANG_ENABLE_ASAN=ON
+ASAN_OPTIONS=detect_leaks=0 cmake --build --preset release |
||
|
|
||
| cmake --preset default -DSLANG_ENABLE_ASAN=ON | ||
| cmake --build --preset release | ||
| ``` | ||
|
|
||
| When _running_ the resulting binaries, put the build's own `lib/` directory on `LD_LIBRARY_PATH` as | ||
| well. `slang-test` loads its tools (`librender-test-tool.so` and friends) with `dlopen`, and if that | ||
| fails the affected tests are reported as **ignored** rather than failed — so a missing path silently | ||
| removes coverage instead of producing an error. | ||
|
|
||
| This is needed only for sanitizer builds. Normally that `dlopen` resolves through the executable's | ||
| `$ORIGIN/../lib` runpath without any help; under a sanitizer the call is intercepted by the | ||
| sanitizer runtime and issued from _its_ object, which has no runpath, so `$ORIGIN/../lib` is never | ||
| searched. Setting `LD_LIBRARY_PATH` for the runtime alone is therefore not enough — it must also | ||
| name the build's `lib/`: | ||
|
|
||
| ```bash | ||
| export LD_LIBRARY_PATH="$PWD/build/Release/lib:$(clang -print-runtime-dir):$LD_LIBRARY_PATH" | ||
| ``` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Gap: This paragraph tells the reader that the same setup applies to a ThreadSanitizer build enabled via Example: A reader following this line runs Suggested fix: Drop the TSAN paragraph (lines 647–648), or gate it as aspirational (e.g. "if a |
||
|
|
||
| The same applies to `-DSLANG_ENABLE_TSAN=ON`, with `libclang_rt.tsan-x86_64.so` in place of the ASan | ||
| runtime; `ASAN_OPTIONS=detect_leaks=0` is not needed there, as ThreadSanitizer has no leak checker. | ||
|
|
||
| The equivalent settings for CI are in `.github/workflows/ci-slang-sanitizer.yml`. | ||
|
|
||
| ## Notes | ||
|
|
||
| [^1] below 3.25, CMake lacks the ability to mark directories as being | ||
|
|
||
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.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: shader-slang/slang
Length of output: 26757
🏁 Script executed:
Repository: shader-slang/slang
Length of output: 24874
Limit the sanitizer instructions to Linux Clang builds.
The CMake implementation uses
-shared-libsanonly for non-Apple Clang builds. GNU and MSVC use different sanitizer runtime handling, while Apple Clang already uses a dynamic runtime. The TSan example also names the x86_64-specificlibclang_rt.tsan-x86_64.so. Scope these instructions to Linux Clang builds, or document the platform- and architecture-specific equivalents.