Skip to content
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

Enable ASan and TSan on FreeBSD (WIP) #47337

Closed
wants to merge 2 commits into from

Conversation

valpackett
Copy link
Contributor

I managed to get ASan running on my Rust program on FreeBSD, however, this patch is incomplete: seems like Rust's LLVM build is not building these clang_rt.{}-x86_64 libraries. (find doesn't even find them.) I haven't found where to turn them on, can anyone help?

For now, I had to use the OS packaged LLVM's ASan library:

RUSTFLAGS="-L /usr/local/llvm40/lib/clang/4.0.1/lib/freebsd/ -l static=clang_rt.asan-x86_64 -l pthread -Z sanitizer=address" \
  cargo build --example simple --target x86_64-unknown-freebsd

ASAN_OPTIONS=detect_odr_violation=0 ASAN_SYMBOLIZER_PATH=/usr/local/llvm40/bin/llvm-symbolizer \
  ../target/x86_64-unknown-freebsd/debug/examples/simple

And note the pthread, we have to link it when ASan is used. Not exactly sure where to add that. (Wouldn't have noticed this if my program used threads, by the way…)

Also, looks like we have LSan too (at least the library is present in system LLVM packages)…

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @arielb1 (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@kennytm kennytm added the O-freebsd Operating system: FreeBSD label Jan 10, 2018
@kennytm
Copy link
Member

kennytm commented Jan 10, 2018

You can turn them on by adding --enable-sanitizers to RUST_CONFIGURE_ARGS in FreeBSD's Dockerfiles (located in src/ci/docker/*-freebsd/Dockerfile).

It is great if you could turn on LSan too.


cc #39699. r? @alexcrichton.

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 10, 2018
@valpackett
Copy link
Contributor Author

valpackett commented Jan 10, 2018

Ah, right, so it's a config.toml flag. Building now.

LLVM 4's compiler-rt requires a couple patches to work on FreeBSD 12-CURRENT. They've been merged upstream (and released in LLVM 5), and rust-2017-07-20 already includes these changes. But rust does not use that branch?? Is that branch only for the eventual switch to LLVM 5? Because that is the LLVM 5 branch, yeah.

@valpackett
Copy link
Contributor Author

So LSan is incomplete (even though the library is built, it's not listed as supported on their website)

  = note: /tmp/rustc.xZWN2thLlEHU/librustc_lsan-8d532cbe1107932c.rlib(lsan.cc.o): In function `InitializeFlags':
          /usr/ports/lang/rust-nightly/work/rustc-nightly-src/src/libcompiler_builtins/compiler-rt/lib/lsan/lsan.cc:53: undefined reference to `__lsan::lsan_flags'
          /usr/ports/lang/rust-nightly/work/rustc-nightly-src/src/libcompiler_builtins/compiler-rt/lib/lsan/lsan.cc:53: undefined reference to `__lsan::Flags::SetDefaults()'
          /usr/ports/lang/rust-nightly/work/rustc-nightly-src/src/libcompiler_builtins/compiler-rt/lib/lsan/lsan.cc:56: undefined reference to `__lsan::RegisterLsanFlags(__sanitizer::FlagParser*, __lsan::Flags*)'
          /tmp/rustc.xZWN2thLlEHU/librustc_lsan-8d532cbe1107932c.rlib(lsan_allocator.cc.o): In function `RegisterAllocation':
          /usr/ports/lang/rust-nightly/work/rustc-nightly-src/src/libcompiler_builtins/compiler-rt/lib/lsan/lsan_allocator.cc:84: undefined reference to `__lsan::DisabledInThisThread()'
          /usr/ports/lang/rust-nightly/work/rustc-nightly-src/src/libcompiler_builtins/compiler-rt/lib/lsan/lsan_allocator.cc:84: undefined reference to `__lsan::DisabledInThisThread()'

TSan doesn't link for some weird reason:

  = note: /usr/bin/ld: /tmp/rustc.sVX8FQPLRsGg/librustc_tsan-71e962f5002f6539.rlib(tsan_interceptors.cc.o): relocation R_X86_64_TPOFF32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
          /tmp/rustc.sVX8FQPLRsGg/librustc_tsan-71e962f5002f6539.rlib(tsan_interceptors.cc.o): could not read symbols: Bad value

@alexcrichton
Copy link
Member

Thanks @myfreeweb! Is this good to go or are there still linking errors?

@valpackett
Copy link
Contributor Author

no, TSan doesn't link yet, and I should add the pthread flag (just realized, probably the right place for it is librustc_asan's build.rs)

@kennytm kennytm added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 11, 2018
@alexcrichton
Copy link
Member

Ok, feel free to ping the PR when it's good to go!

valpackett added a commit to DankBSD/ports that referenced this pull request Jan 15, 2018
@kennytm kennytm added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 17, 2018
@kennytm kennytm added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 24, 2018
@shepmaster
Copy link
Member

Thanks for the pull request, @myfreeweb ! Since we haven't heard from you in a few weeks, I'm going to close this to keep the queue tidy. If you get over the last bit, please feel free to reopen this PR!

LLVM 4's compiler-rt

Because that is the LLVM 5 branch, yeah.

Who needs LLVM 4 or 5 when you can have LLVM 6 😜

@shepmaster shepmaster closed this Feb 3, 2018
@shepmaster shepmaster added S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 3, 2018
Manishearth added a commit to Manishearth/rust that referenced this pull request Jul 31, 2020
…-obk

Add sanitizer support on FreeBSD

Restarting rust-lang#47337. Everything is better now, no more weird llvm problems, well not everything:

Unfortunately, the sanitizers don't have proper support for versioned symbols (google/sanitizers#628), so `libc`'s usage of `stat@FBSD_1.0` and so on explodes, e.g. in calling `std::fs::metadata`.

Building std (now easy thanks to cargo `-Zbuild-std`) and libc with `freebsd12/13` config via the `LIBC_CI=1` env variable is a good workaround…

```
LIBC_CI=1 RUSTFLAGS="-Z sanitizer=address" cargo +san-test -Zbuild-std run --target x86_64-unknown-freebsd --verbose
```

…*except* std won't build because there's no `st_lspare` in the ino64 version of the struct, so an std patch is required:

```diff
--- i/src/libstd/os/freebsd/fs.rs
+++ w/src/libstd/os/freebsd/fs.rs
@@ -66,8 +66,6 @@ pub trait MetadataExt {
     fn st_flags(&self) -> u32;
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_gen(&self) -> u32;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_lspare(&self) -> u32;
 }

 #[stable(feature = "metadata_ext", since = "1.1.0")]
@@ -136,7 +134,4 @@ impl MetadataExt for Metadata {
     fn st_flags(&self) -> u32 {
         self.as_inner().as_inner().st_flags as u32
     }
-    fn st_lspare(&self) -> u32 {
-        self.as_inner().as_inner().st_lspare as u32
-    }
 }
```

I guess std could like.. detect that `libc` isn't built for the old ABI, and replace the implementation of `st_lspare` with a panic?
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 15, 2020
Add sanitizer support on FreeBSD

Restarting rust-lang#47337. Everything is better now, no more weird llvm problems, well not everything:

Unfortunately, the sanitizers don't have proper support for versioned symbols (google/sanitizers#628), so `libc`'s usage of `stat@FBSD_1.0` and so on explodes, e.g. in calling `std::fs::metadata`.

Building std (now easy thanks to cargo `-Zbuild-std`) and libc with `freebsd12/13` config via the `LIBC_CI=1` env variable is a good workaround…

```
LIBC_CI=1 RUSTFLAGS="-Z sanitizer=address" cargo +san-test -Zbuild-std run --target x86_64-unknown-freebsd --verbose
```

…*except* std won't build because there's no `st_lspare` in the ino64 version of the struct, so an std patch is required:

```diff
--- i/src/libstd/os/freebsd/fs.rs
+++ w/src/libstd/os/freebsd/fs.rs
@@ -66,8 +66,6 @@ pub trait MetadataExt {
     fn st_flags(&self) -> u32;
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_gen(&self) -> u32;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_lspare(&self) -> u32;
 }

 #[stable(feature = "metadata_ext", since = "1.1.0")]
@@ -136,7 +134,4 @@ impl MetadataExt for Metadata {
     fn st_flags(&self) -> u32 {
         self.as_inner().as_inner().st_flags as u32
     }
-    fn st_lspare(&self) -> u32 {
-        self.as_inner().as_inner().st_lspare as u32
-    }
 }
```

I guess std could like.. detect that `libc` isn't built for the old ABI, and replace the implementation of `st_lspare` with a panic?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-freebsd Operating system: FreeBSD S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants