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

LeakSanitizer, ThreadSanitizer, AddressSanitizer and MemorySanitizer support #38699

Merged
merged 8 commits into from
Feb 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ opt codegen-tests 1 "run the src/test/codegen tests"
opt option-checking 1 "complain about unrecognized options in this configure script"
opt ninja 0 "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)"
opt vendor 0 "enable usage of vendored Rust crates"
opt sanitizers 0 "build the sanitizer runtimes (asan, lsan, msan, tsan)"

# Optimization and debugging options. These may be overridden by the release channel, etc.
opt_nosave optimize 1 "build optimized rust code"
Expand Down
44 changes: 44 additions & 0 deletions src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/bootstrap/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,10 @@ pub fn compiletest(build: &Build,
cmd.env("RUSTC_BOOTSTRAP", "1");
build.add_rust_test_threads(&mut cmd);

if build.config.sanitizers {
cmd.env("SANITIZER_SUPPORT", "1");
}

cmd.arg("--adb-path").arg("adb");
cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
if target.contains("android") {
Expand Down
11 changes: 11 additions & 0 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ pub fn std(build: &Build, target: &str, compiler: &Compiler) {
if compiler.stage == 0 && build.local_rebuild && !build.config.use_jemalloc {
features.push_str(" force_alloc_system");
}

if compiler.stage != 0 && build.config.sanitizers {
// This variable is used by the sanitizer runtime crates, e.g.
// rustc_lsan, to build the sanitizer runtime from C code
// When this variable is missing, those crates won't compile the C code,
// so we don't set this variable during stage0 where llvm-config is
// missing
// We also only build the runtimes when --enable-sanitizers (or its
// config.toml equivalent) is used
cargo.env("LLVM_CONFIG", build.llvm_config(target));
}
cargo.arg("--features").arg(features)
.arg("--manifest-path")
.arg(build.src.join("src/rustc/std_shim/Cargo.toml"));
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub struct Config {
pub target_config: HashMap<String, Target>,
pub full_bootstrap: bool,
pub extended: bool,
pub sanitizers: bool,

// llvm codegen options
pub llvm_assertions: bool,
Expand Down Expand Up @@ -148,6 +149,7 @@ struct Build {
python: Option<String>,
full_bootstrap: Option<bool>,
extended: Option<bool>,
sanitizers: Option<bool>,
}

/// TOML representation of various global install decisions.
Expand Down Expand Up @@ -292,6 +294,7 @@ impl Config {
set(&mut config.vendor, build.vendor);
set(&mut config.full_bootstrap, build.full_bootstrap);
set(&mut config.extended, build.extended);
set(&mut config.sanitizers, build.sanitizers);

if let Some(ref install) = toml.install {
config.prefix = install.prefix.clone().map(PathBuf::from);
Expand Down Expand Up @@ -435,6 +438,7 @@ impl Config {
("VENDOR", self.vendor),
("FULL_BOOTSTRAP", self.full_bootstrap),
("EXTENDED", self.extended),
("SANITIZERS", self.sanitizers),
}

match key {
Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@
# disabled by default.
#extended = false

# Build the sanitizer runtimes
#sanitizers = false

# =============================================================================
# General install configuration options
# =============================================================================
Expand Down
3 changes: 2 additions & 1 deletion src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,8 @@ impl Build {
/// Get the space-separated set of activated features for the standard
/// library.
fn std_features(&self) -> String {
let mut features = "panic-unwind".to_string();
let mut features = "panic-unwind asan lsan msan tsan".to_string();

if self.config.debug_jemalloc {
features.push_str(" debug-jemalloc");
}
Expand Down
7 changes: 6 additions & 1 deletion src/ci/docker/dist-x86-linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ RUN ./build-git.sh
COPY build-cmake.sh /tmp/
RUN ./build-cmake.sh

# for sanitizers, we need kernel headers files newer than the ones CentOS ships
# with so we install newer ones here
COPY build-headers.sh /tmp/
RUN ./build-headers.sh

RUN curl -Lo /rustroot/dumb-init \
https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 && \
chmod +x /rustroot/dumb-init
Expand All @@ -76,5 +81,5 @@ RUN curl -L https://api.pub.build.mozilla.org/tooltool/sha512/$SCCACHE_DIGEST |
ENV HOSTS=i686-unknown-linux-gnu
ENV HOSTS=$HOSTS,x86_64-unknown-linux-gnu

ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended
ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended --enable-sanitizers
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
25 changes: 25 additions & 0 deletions src/ci/docker/dist-x86-linux/build-headers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.

set -ex
source shared.sh

curl https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.2.84.tar.xz | unxz | tar x

cd linux-3.2.84
hide_output make mrproper
hide_output make INSTALL_HDR_PATH=dest headers_install

find dest/include \( -name .install -o -name ..install.cmd \) -delete
yes | cp -fr dest/include/* /usr/include

cd ..
rm -rf linux-3.2.84
2 changes: 1 addition & 1 deletion src/ci/docker/x86_64-gnu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
rm dumb-init_*.deb
ENTRYPOINT ["/usr/bin/dumb-init", "--"]

ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --enable-sanitizers
ENV SCRIPT python2.7 ../x.py test && python2.7 ../x.py dist
2 changes: 2 additions & 0 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ pub trait CrateStore<'tcx> {
fn is_allocator(&self, cnum: CrateNum) -> bool;
fn is_panic_runtime(&self, cnum: CrateNum) -> bool;
fn is_compiler_builtins(&self, cnum: CrateNum) -> bool;
fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool;
fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy;
fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate>;
/// The name of the crate as it is referred to in source code of the current
Expand Down Expand Up @@ -390,6 +391,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn is_allocator(&self, cnum: CrateNum) -> bool { bug!("is_allocator") }
fn is_panic_runtime(&self, cnum: CrateNum) -> bool { bug!("is_panic_runtime") }
fn is_compiler_builtins(&self, cnum: CrateNum) -> bool { bug!("is_compiler_builtins") }
fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool { bug!("is_sanitizer_runtime") }
fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
bug!("panic_strategy")
}
Expand Down
25 changes: 24 additions & 1 deletion src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ pub struct Config {
pub uint_type: UintTy,
}

#[derive(Clone)]
pub enum Sanitizer {
Address,
Leak,
Memory,
Thread,
}

#[derive(Clone, Copy, PartialEq, Hash)]
pub enum OptLevel {
No, // -O0
Expand Down Expand Up @@ -626,11 +634,13 @@ macro_rules! options {
Some("a number");
pub const parse_panic_strategy: Option<&'static str> =
Some("either `panic` or `abort`");
pub const parse_sanitizer: Option<&'static str> =
Some("one of: `address`, `leak`, `memory` or `thread`");
}

#[allow(dead_code)]
mod $mod_set {
use super::{$struct_name, Passes, SomePasses, AllPasses};
use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer};
use rustc_back::PanicStrategy;

$(
Expand Down Expand Up @@ -751,6 +761,17 @@ macro_rules! options {
}
true
}

fn parse_sanitizer(slote: &mut Option<Sanitizer>, v: Option<&str>) -> bool {
match v {
Some("address") => *slote = Some(Sanitizer::Address),
Some("leak") => *slote = Some(Sanitizer::Leak),
Some("memory") => *slote = Some(Sanitizer::Memory),
Some("thread") => *slote = Some(Sanitizer::Thread),
_ => return false,
}
true
}
}
) }

Expand Down Expand Up @@ -949,6 +970,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"encode MIR of all functions into the crate metadata"),
osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],
"pass `-install_name @rpath/...` to the OSX linker"),
sanitizer: Option<Sanitizer> = (None, parse_sanitizer, [UNTRACKED],
"Use a sanitizer"),
}

pub fn default_lib_output() -> CrateType {
Expand Down
17 changes: 17 additions & 0 deletions src/librustc_asan/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
authors = ["The Rust Project Developers"]
build = "build.rs"
name = "rustc_asan"
version = "0.0.0"

[lib]
name = "rustc_asan"
path = "lib.rs"

[build-dependencies]
build_helper = { path = "../build_helper" }
cmake = "0.1.18"

[dependencies]
alloc_system = { path = "../liballoc_system" }
core = { path = "../libcore" }
39 changes: 39 additions & 0 deletions src/librustc_asan/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate build_helper;
extern crate cmake;

use std::path::PathBuf;
use std::env;

use cmake::Config;

fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
let dst = Config::new("../compiler-rt")
.define("COMPILER_RT_BUILD_SANITIZERS", "ON")
.define("COMPILER_RT_BUILD_BUILTINS", "OFF")
.define("COMPILER_RT_BUILD_XRAY", "OFF")
.define("LLVM_CONFIG_PATH", llvm_config)
.build_target("asan")
.build();

println!("cargo:rustc-link-search=native={}",
dst.join("build/lib/linux").display());
println!("cargo:rustc-link-lib=static=clang_rt.asan-x86_64");

build_helper::rerun_if_changed_anything_in_dir(&PathBuf::from(env::var("CARGO_MANIFEST_DIR")
.unwrap())
.join("../compiler-rt"));
}

println!("cargo:rerun-if-changed=build.rs");
}
20 changes: 20 additions & 0 deletions src/librustc_asan/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(not(stage0), feature(sanitizer_runtime))]
#![cfg_attr(not(stage0), sanitizer_runtime)]
#![feature(alloc_system)]
#![feature(staged_api)]
#![no_std]
#![unstable(feature = "sanitizer_runtime_lib",
reason = "internal implementation detail of sanitizers",
issue = "0")]

extern crate alloc_system;
3 changes: 3 additions & 0 deletions src/librustc_llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ pub enum Attribute {
UWTable = 17,
ZExt = 18,
InReg = 19,
SanitizeThread = 20,
SanitizeAddress = 21,
SanitizeMemory = 22,
}

/// LLVMIntPredicate
Expand Down
Loading