diff options
| author | Daniel Paoliello <danpao@microsoft.com> | 2023-12-19 10:29:47 -0800 |
|---|---|---|
| committer | Daniel Paoliello <danpao@microsoft.com> | 2024-01-03 10:00:15 -0800 |
| commit | bc3b7c9930d3500d69a39c2a34d7ef63c403d74d (patch) | |
| tree | d386660d565977bd576b9d86e1a84fc17b666d7f /src/bootstrap | |
| parent | 2e79c8deb05320c6f2bc35cc0e21b943ec0f29b5 (diff) | |
Enable address sanitizer for MSVC targets using INFERASANLIBS linker flag
Diffstat (limited to 'src/bootstrap')
| -rw-r--r-- | src/bootstrap/src/core/build_steps/compile.rs | 2 | ||||
| -rw-r--r-- | src/bootstrap/src/core/build_steps/test.rs | 23 | ||||
| -rw-r--r-- | src/bootstrap/src/core/config/config.rs | 11 | ||||
| -rw-r--r-- | src/bootstrap/src/core/sanity.rs | 2 |
4 files changed, 34 insertions, 4 deletions
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index dbb64583d56..d699c4fe536 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -274,7 +274,7 @@ fn copy_third_party_objects( ) -> Vec<(PathBuf, DependencyType)> { let mut target_deps = vec![]; - if builder.config.sanitizers_enabled(target) && compiler.stage != 0 { + if builder.config.needs_sanitizer_runtime_built(target) && compiler.stage != 0 { // The sanitizers are only copied in stage1 or above, // to avoid creating dependency on LLVM. target_deps.extend( diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 92140b00da8..3ae3af38bf8 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1937,6 +1937,29 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } } + // Special setup to enable running with sanitizers on MSVC. + if !builder.config.dry_run() + && target.contains("msvc") + && builder.config.sanitizers_enabled(target) + { + // Ignore interception failures: not all dlls in the process will have been built with + // address sanitizer enabled (e.g., ntdll.dll). + cmd.env("ASAN_WIN_CONTINUE_ON_INTERCEPTION_FAILURE", "1"); + // Add the address sanitizer runtime to the PATH - it is located next to cl.exe. + let asan_runtime_path = + builder.cc.borrow()[&target].path().parent().unwrap().to_path_buf(); + let old_path = cmd + .get_envs() + .find_map(|(k, v)| (k == "PATH").then_some(v)) + .flatten() + .map_or_else(|| env::var_os("PATH").unwrap_or_default(), |v| v.to_owned()); + let new_path = env::join_paths( + env::split_paths(&old_path).chain(std::iter::once(asan_runtime_path)), + ) + .expect("Could not add ASAN runtime path to PATH"); + cmd.env("PATH", new_path); + } + // Some UI tests trigger behavior in rustc where it reads $CARGO and changes behavior if it exists. // To make the tests work that rely on it not being set, make sure it is not set. cmd.env_remove("CARGO"); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index c6bf71c8837..3ac3e545631 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2180,8 +2180,15 @@ impl Config { self.target_config.get(&target).map(|t| t.sanitizers).flatten().unwrap_or(self.sanitizers) } - pub fn any_sanitizers_enabled(&self) -> bool { - self.target_config.values().any(|t| t.sanitizers == Some(true)) || self.sanitizers + pub fn needs_sanitizer_runtime_built(&self, target: TargetSelection) -> bool { + // MSVC uses the Microsoft-provided sanitizer runtime, but all other runtimes we build. + !target.is_msvc() && self.sanitizers_enabled(target) + } + + pub fn any_sanitizers_to_build(&self) -> bool { + self.target_config + .iter() + .any(|(ts, t)| !ts.is_msvc() && t.sanitizers.unwrap_or(self.sanitizers)) } pub fn profiler_path(&self, target: TargetSelection) -> Option<&str> { diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 9101d94ea88..82755f41800 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -96,7 +96,7 @@ pub fn check(build: &mut Build) { }) .any(|build_llvm_ourselves| build_llvm_ourselves); - let need_cmake = building_llvm || build.config.any_sanitizers_enabled(); + let need_cmake = building_llvm || build.config.any_sanitizers_to_build(); if need_cmake && cmd_finder.maybe_have("cmake").is_none() { eprintln!( " |
