rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.04k stars 12.68k forks source link

tests/ui/sanitize/leak.rs fails on Linux with `sanitizers = true` #111073

Open danakj opened 1 year ago

danakj commented 1 year ago

Chromium bug discussion here: https://bugs.chromium.org/p/chromium/issues/detail?id=1441181#c5

We want to build rustc with sanitizers = true in config.toml in order to get sanitizer runtimes. However when we do, the leak.rs test fails with a CHECK failure in LLVM.

error: error pattern ' LeakSanitizer: detected memory leaks' not found!
status: exit status: 23
command: cd "/home/danakj/s/c/src/third_party/rust_src/src/build/x86_64-unknown-linux-gnu/test/ui/sanitize/leak" && RUST_TEST_THREADS="72" "/home/danakj/s/c/src/third_party/rust_src/src/build/x86_64-unknown-linux-gnu/test/ui/sanitize/leak/a"
stdout: none
--- stderr -------------------------------
LeakSanitizer: CHECK failed: lsan_interceptors.cpp:82 "((!lsan_init_is_running)) != (0)" (0x0, 0x0) (tid=309157)
------------------------------------------

Which is failing a check inside the ENSURE_LSAN_INITED macro here: https://github.com/llvm/llvm-project/blob/89a44b0faee0ca6b741e1f0ef31163374887b6ed/compiler-rt/lib/lsan/lsan_interceptors.cpp#L82

We're building against LLVM HEAD-ish, so I tried with upstream rustc and the test fails when compiled with that as well (reduced command line from the actual test invocation):

% rustc --version
rustc 1.71.0-nightly (9ecda8de8 2023-04-30)
% rustc ~/s/c/src/third_party/rust_src/src/tests/ui/sanitize/leak.rs -Zthreads=1 --target=x86_64-unknown-linux-gnu --error-format json --json future-incompat -Ccodegen-units=1 -Zui-testing -o ~/s/c/src/third_party/rust_src/src/build/x86_64-unknown-linux-gnu/test/ui/sanitize/leak/a -A unused -Crpath -Z sanitizer=leak -O
% cd ~/s/c/src/third_party/rust_src/src/build/x86_64-unknown-linux-gnu/test/ui/sanitize/leak && RUST_TEST_THREADS="72" ~/s/c/src/third_party/rust_src/src/build/x86_64-unknown-linux-gnu/test/ui/sanitize/leak/a
LeakSanitizer: CHECK failed: lsan_interceptors.cpp:82 "((!lsan_init_is_running)) != (0)" (0x0, 0x0) (tid=911869)
aaronmondal commented 1 year ago

Been running into this for a while as well. This breaks both the leak sanitizer in rules_ll and prevents turbo-cache from using leak sanitizer.

@danakj Did you find out anything that could be helpful here yet?

danakj commented 1 year ago

Sorry no I have not looked further. For Chromium, we ended up using Clang's sanitizer runtimes and just making empty archive placeholders for the Rust ones (as we can't have both anyway).

nikic commented 1 year ago

Backtrace:

Breakpoint 1, 0x0000555555565dc0 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) ()
(gdb) bt
#0  0x0000555555565dc0 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) ()
#1  0x000055555557ddc5 in __interceptor_free ()
#2  0x00007ffff7c70dfc in dl_error_free (ptr=<optimized out>) at ./dlerror.h:54
#3  dl_action_result_errstring_free (result=<optimized out>) at ./dlerror.h:72
#4  dl_action_result_errstring_free (result=0x7ffff6f00780) at ./dlerror.h:65
#5  _dlerror_run (operate=operate@entry=0x7ffff7c71320 <dlsym_doit>, 
    args=args@entry=0x7fffffffde90) at dlerror.c:183
#6  0x00007ffff7c713c5 in dlsym_implementation (dl_caller=<optimized out>, name=<optimized out>, 
    handle=<optimized out>) at dlsym.c:54
#7  ___dlsym (handle=<optimized out>, name=<optimized out>) at dlsym.c:68
#8  0x0000555555557422 in __interception::InterceptFunction(char const*, unsigned long*, unsigned long, unsigned long) ()
#9  0x000055555557d78d in __lsan::InitializeInterceptors() ()
#10 0x000055555557715b in __lsan_init ()
#11 0x00007ffff7fcce12 in _dl_init (main_map=0x7ffff7ffe2c0, argc=1, argv=0x7fffffffdf88, 
    env=0x7fffffffdf98) at dl-init.c:102
#12 0x00007ffff7fe38e0 in _dl_start_user () from /lib64/ld-linux-x86-64.so.2

We can see that we end up calling __interceptor_free as part of __lsan_init via __dlsym.

Jules-Bertholet commented 6 months ago

@rustbot label A-sanitizers

intgr commented 6 months ago

rustix project also fails to build with LeakSanitizer. Repro:

git clone https://github.com/bytecodealliance/rustix
cd rustix
rustup override set nightly
RUSTFLAGS="-Z sanitizer=leak" cargo build

Output:

[...]
   Compiling rustix v0.38.32 (/home/marti/src/rustix)
   Compiling linux-raw-sys v0.4.13
   Compiling bitflags v2.5.0
error: failed to run custom build command for `rustix v0.38.32 (/home/marti/src/rustix)`

Caused by:
  process didn't exit successfully: `rustix/target/debug/build/rustix-dad2410e95903b2f/build-script-build` (exit status: 23)
  --- stderr
  LeakSanitizer: CHECK failed: lsan_interceptors.cpp:82 "((!lsan_init_is_running)) != (0)" (0x0, 0x0) (tid=75319)
tmiasko commented 5 months ago

When linking a static sanitizer runtime clang also adds --dynamic-list=... or --export-dynamic.

-Clink-args=--export-dynamic or -Zexport-executable-symbols can be used as a workaround in rustc.

tmiasko commented 1 month ago

Should be fixed by llvm/llvm-project#106912.