Skip to content

Commit 0359eb1

Browse files
Merge pull request #432 from microsoft/main
Fork Sync: Update from parent repository
2 parents 1969132 + d53646e commit 0359eb1

File tree

16 files changed

+194
-82
lines changed

16 files changed

+194
-82
lines changed

src/agent/Cargo.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/agent/coverage/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ version = "0.1.0"
44
edition = "2021"
55
license = "MIT"
66

7+
[features]
8+
slow-tests = []
9+
710
[dependencies]
811
anyhow = { version = "1.0", features = ["backtrace"] }
912
cobertura = { path = "../cobertura" }
@@ -32,3 +35,8 @@ procfs = { version = "0.12", default-features = false, features = ["flate2"] }
3235
clap = { version = "4.3", features = ["derive"] }
3336
env_logger = "0.10.0"
3437
pretty_assertions = "1.4.0"
38+
insta = { version = "1.31.0", features = ["glob"] }
39+
coverage = { path = "../coverage" }
40+
cc = "1.0"
41+
tempfile = "3.7.0"
42+
dunce = "1.0"

src/agent/coverage/examples/record.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ use std::process::Command;
22
use std::sync::Arc;
33
use std::time::Duration;
44

5-
use anyhow::{bail, Result};
5+
use anyhow::{bail, Context, Result};
66
use clap::Parser;
77
use cobertura::CoberturaCoverage;
8-
use coverage::allowlist::{AllowList, TargetAllowList};
8+
use coverage::allowlist::AllowList;
99
use coverage::binary::{BinaryCoverage, DebugInfoCache};
1010
use coverage::record::{CoverageRecorder, Recorded};
1111
use debuggable_module::load_module::LoadModule;
@@ -57,19 +57,21 @@ fn main() -> Result<()> {
5757
.map(Duration::from_millis)
5858
.unwrap_or(DEFAULT_TIMEOUT);
5959

60-
let mut allowlist = TargetAllowList::default();
60+
let module_allowlist = args
61+
.module_allowlist
62+
.map(AllowList::load)
63+
.unwrap_or_else(|| Ok(AllowList::default()))
64+
.context("loading module allowlist")?;
6165

62-
if let Some(path) = &args.module_allowlist {
63-
allowlist.modules = AllowList::load(path)?;
64-
}
65-
66-
if let Some(path) = &args.source_allowlist {
67-
allowlist.source_files = AllowList::load(path)?;
68-
}
66+
let source_allowlist = args
67+
.source_allowlist
68+
.map(AllowList::load)
69+
.unwrap_or_else(|| Ok(AllowList::default()))
70+
.context("loading source allowlist")?;
6971

7072
let mut coverage = BinaryCoverage::default();
7173
let loader = Arc::new(Loader::new());
72-
let cache = Arc::new(DebugInfoCache::new(allowlist.source_files.clone()));
74+
let cache = Arc::new(DebugInfoCache::new(source_allowlist.clone()));
7375

7476
let t = std::time::Instant::now();
7577
precache_target(&args.command[0], &loader, &cache)?;
@@ -84,7 +86,7 @@ fn main() -> Result<()> {
8486

8587
let t = std::time::Instant::now();
8688
let recorded = CoverageRecorder::new(cmd)
87-
.allowlist(allowlist.clone())
89+
.module_allowlist(module_allowlist.clone())
8890
.loader(loader.clone())
8991
.debuginfo_cache(cache.clone())
9092
.timeout(timeout)
@@ -102,7 +104,7 @@ fn main() -> Result<()> {
102104

103105
let t = std::time::Instant::now();
104106
let recorded = CoverageRecorder::new(cmd)
105-
.allowlist(allowlist.clone())
107+
.module_allowlist(module_allowlist)
106108
.loader(loader)
107109
.debuginfo_cache(cache)
108110
.timeout(timeout)
@@ -118,8 +120,8 @@ fn main() -> Result<()> {
118120

119121
match args.output {
120122
OutputFormat::ModOff => dump_modoff(&coverage)?,
121-
OutputFormat::Source => dump_source_line(&coverage, allowlist.source_files)?,
122-
OutputFormat::Cobertura => dump_cobertura(&coverage, allowlist.source_files)?,
123+
OutputFormat::Source => dump_source_line(&coverage, source_allowlist)?,
124+
OutputFormat::Cobertura => dump_cobertura(&coverage, source_allowlist)?,
123125
}
124126

125127
Ok(())

src/agent/coverage/src/allowlist.rs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,6 @@ use anyhow::Result;
55
use regex::{Regex, RegexSet};
66
use std::path::Path;
77

8-
#[derive(Clone, Debug, Default)]
9-
pub struct TargetAllowList {
10-
pub modules: AllowList,
11-
pub source_files: AllowList,
12-
}
13-
14-
impl TargetAllowList {
15-
pub fn new(modules: AllowList, source_files: AllowList) -> Self {
16-
Self {
17-
modules,
18-
source_files,
19-
}
20-
}
21-
22-
#[allow(clippy::field_reassign_with_default)]
23-
pub fn extend(&self, other: &Self) -> Self {
24-
let mut new = Self::default();
25-
26-
new.modules = self.modules.extend(&other.modules);
27-
new.source_files = self.source_files.extend(&other.source_files);
28-
29-
new
30-
}
31-
}
32-
338
#[derive(Clone, Debug)]
349
pub struct AllowList {
3510
allow: RegexSet,

src/agent/coverage/src/binary.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub use debuggable_module::{block, path::FilePath, Offset};
1111
use symbolic::debuginfo::Object;
1212
use symbolic::symcache::{SymCache, SymCacheConverter};
1313

14-
use crate::allowlist::{AllowList, TargetAllowList};
14+
use crate::allowlist::AllowList;
1515

1616
#[derive(Clone, Debug, Default, Eq, PartialEq)]
1717
pub struct BinaryCoverage {
@@ -214,7 +214,7 @@ impl CachedDebugInfo {
214214

215215
pub fn find_coverage_sites(
216216
module: &dyn Module,
217-
allowlist: &TargetAllowList,
217+
source_allowlist: &AllowList,
218218
) -> Result<ModuleBinaryCoverage> {
219219
let debuginfo = module.debuginfo()?;
220220

@@ -232,7 +232,7 @@ pub fn find_coverage_sites(
232232
for function in debuginfo.functions() {
233233
if let Some(location) = symcache.lookup(function.offset.0).next() {
234234
if let Some(file) = location.file() {
235-
if !allowlist.source_files.is_allowed(file.full_path()) {
235+
if !source_allowlist.is_allowed(file.full_path()) {
236236
debug!(
237237
"skipping sweep of `{}:{}` due to excluded source path `{}`",
238238
module.executable_path(),
@@ -253,7 +253,7 @@ pub fn find_coverage_sites(
253253

254254
// Apply allowlists per block, to account for inlining. The `location` values
255255
// here describe the top of the inline-inclusive call stack.
256-
if !allowlist.source_files.is_allowed(path) {
256+
if !source_allowlist.is_allowed(path) {
257257
continue;
258258
}
259259

src/agent/coverage/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub mod source;
1212
mod timer;
1313

1414
#[doc(inline)]
15-
pub use allowlist::{AllowList, TargetAllowList};
15+
pub use allowlist::AllowList;
1616

1717
#[doc(inline)]
1818
pub use record::{CoverageRecorder, Recorded};

src/agent/coverage/src/record.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use std::time::Duration;
88
use anyhow::Result;
99
use debuggable_module::loader::Loader;
1010

11-
use crate::allowlist::TargetAllowList;
1211
use crate::binary::{BinaryCoverage, DebugInfoCache};
12+
use crate::AllowList;
1313

1414
#[cfg(target_os = "linux")]
1515
pub mod linux;
@@ -18,7 +18,7 @@ pub mod linux;
1818
pub mod windows;
1919

2020
pub struct CoverageRecorder {
21-
allowlist: TargetAllowList,
21+
module_allowlist: AllowList,
2222
cache: Arc<DebugInfoCache>,
2323
cmd: Command,
2424
loader: Arc<Loader>,
@@ -30,22 +30,20 @@ impl CoverageRecorder {
3030
cmd.stdout(Stdio::piped());
3131
cmd.stderr(Stdio::piped());
3232

33-
let allowlist = TargetAllowList::default();
34-
let cache = Arc::new(DebugInfoCache::new(allowlist.source_files.clone()));
3533
let loader = Arc::new(Loader::new());
3634
let timeout = Duration::from_secs(5);
3735

3836
Self {
39-
allowlist,
40-
cache,
37+
module_allowlist: AllowList::default(),
38+
cache: Arc::new(DebugInfoCache::new(AllowList::default())),
4139
cmd,
4240
loader,
4341
timeout,
4442
}
4543
}
4644

47-
pub fn allowlist(mut self, allowlist: TargetAllowList) -> Self {
48-
self.allowlist = allowlist;
45+
pub fn module_allowlist(mut self, module_allowlist: AllowList) -> Self {
46+
self.module_allowlist = module_allowlist;
4947
self
5048
}
5149

@@ -82,7 +80,7 @@ impl CoverageRecorder {
8280
let child_pid = child_pid.clone();
8381

8482
timer::timed(self.timeout, move || {
85-
let mut recorder = LinuxRecorder::new(&loader, self.allowlist, &self.cache);
83+
let mut recorder = LinuxRecorder::new(&loader, self.module_allowlist, &self.cache);
8684
let mut dbg = Debugger::new(&mut recorder);
8785
let child = dbg.spawn(self.cmd)?;
8886

@@ -128,7 +126,8 @@ impl CoverageRecorder {
128126
let loader = self.loader.clone();
129127

130128
crate::timer::timed(self.timeout, move || {
131-
let mut recorder = WindowsRecorder::new(&loader, self.allowlist, &self.cache);
129+
let mut recorder =
130+
WindowsRecorder::new(&loader, self.module_allowlist, self.cache.as_ref());
132131
let (mut dbg, child) = Debugger::init(self.cmd, &mut recorder)?;
133132
dbg.run(&mut recorder)?;
134133

src/agent/coverage/src/record/linux.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ use pete::Tracee;
1414
pub mod debugger;
1515
use debugger::{DebugEventHandler, DebuggerContext, ModuleImage};
1616

17-
use crate::allowlist::TargetAllowList;
17+
use crate::allowlist::AllowList;
1818
use crate::binary::{BinaryCoverage, DebugInfoCache};
1919

2020
pub struct LinuxRecorder<'cache, 'data> {
21-
allowlist: TargetAllowList,
21+
module_allowlist: AllowList,
2222
cache: &'cache DebugInfoCache,
2323
pub coverage: BinaryCoverage,
2424
loader: &'data Loader,
@@ -28,14 +28,14 @@ pub struct LinuxRecorder<'cache, 'data> {
2828
impl<'cache, 'data> LinuxRecorder<'cache, 'data> {
2929
pub fn new(
3030
loader: &'data Loader,
31-
allowlist: TargetAllowList,
31+
module_allowlist: AllowList,
3232
cache: &'cache DebugInfoCache,
3333
) -> Self {
3434
let coverage = BinaryCoverage::default();
3535
let modules = BTreeMap::new();
3636

3737
Self {
38-
allowlist,
38+
module_allowlist,
3939
cache,
4040
coverage,
4141
loader,
@@ -80,7 +80,7 @@ impl<'cache, 'data> LinuxRecorder<'cache, 'data> {
8080

8181
let path = image.path();
8282

83-
if !self.allowlist.modules.is_allowed(path) {
83+
if !self.module_allowlist.is_allowed(path) {
8484
debug!("not inserting denylisted module: {path}");
8585
return Ok(());
8686
}

src/agent/coverage/src/record/windows.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use debuggable_module::windows::WindowsModule;
1313
use debuggable_module::{Module, Offset};
1414
use debugger::{BreakpointId, BreakpointType, DebugEventHandler, Debugger, ModuleLoadInfo};
1515

16-
use crate::allowlist::TargetAllowList;
1716
use crate::binary::{BinaryCoverage, DebugInfoCache};
17+
use crate::AllowList;
1818

1919
// For a new module image, we defer setting coverage breakpoints until exit from one of these
2020
// functions (when present). This avoids breaking hotpatching routines in the ASan interceptor
@@ -26,7 +26,7 @@ const PROCESS_IMAGE_DEFERRAL_TRIGGER: &str = "__asan::AsanInitInternal(";
2626
const LIBRARY_IMAGE_DEFERRAL_TRIGGER: &str = "DllMain(";
2727

2828
pub struct WindowsRecorder<'cache, 'data> {
29-
allowlist: TargetAllowList,
29+
module_allowlist: AllowList,
3030
breakpoints: Breakpoints,
3131
cache: &'cache DebugInfoCache,
3232
deferred_breakpoints: BTreeMap<BreakpointId, (Breakpoint, DeferralState)>,
@@ -39,7 +39,7 @@ pub struct WindowsRecorder<'cache, 'data> {
3939
impl<'cache, 'data> WindowsRecorder<'cache, 'data> {
4040
pub fn new(
4141
loader: &'data Loader,
42-
allowlist: TargetAllowList,
42+
module_allowlist: AllowList,
4343
cache: &'cache DebugInfoCache,
4444
) -> Self {
4545
let breakpoints = Breakpoints::default();
@@ -49,7 +49,7 @@ impl<'cache, 'data> WindowsRecorder<'cache, 'data> {
4949
let stop_error = None;
5050

5151
Self {
52-
allowlist,
52+
module_allowlist,
5353
breakpoints,
5454
cache,
5555
deferred_breakpoints,
@@ -60,12 +60,12 @@ impl<'cache, 'data> WindowsRecorder<'cache, 'data> {
6060
}
6161
}
6262

63-
pub fn allowlist(&self) -> &TargetAllowList {
64-
&self.allowlist
63+
pub fn module_allowlist(&self) -> &AllowList {
64+
&self.module_allowlist
6565
}
6666

67-
pub fn allowlist_mut(&mut self) -> &mut TargetAllowList {
68-
&mut self.allowlist
67+
pub fn module_allowlist_mut(&mut self) -> &mut AllowList {
68+
&mut self.module_allowlist
6969
}
7070

7171
fn try_on_create_process(&mut self, dbg: &mut Debugger, module: &ModuleLoadInfo) -> Result<()> {
@@ -163,7 +163,7 @@ impl<'cache, 'data> WindowsRecorder<'cache, 'data> {
163163
return Ok(());
164164
}
165165

166-
if !self.allowlist.modules.is_allowed(&path) {
166+
if !self.module_allowlist.is_allowed(&path) {
167167
debug!("not inserting denylisted module: {path}");
168168
return Ok(());
169169
}

src/agent/coverage/src/source.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ impl From<Line> for u32 {
5151

5252
pub fn binary_to_source_coverage(
5353
binary: &BinaryCoverage,
54-
allowlist: impl Into<Option<AllowList>>,
54+
source_allowlist: impl Into<Option<AllowList>>,
5555
) -> Result<SourceCoverage> {
5656
use std::collections::btree_map::Entry;
5757

5858
use symbolic::debuginfo::Object;
5959
use symbolic::symcache::{SymCache, SymCacheConverter};
6060

61-
let allowlist = allowlist.into().unwrap_or_default();
61+
let source_allowlist = source_allowlist.into().unwrap_or_default();
6262
let loader = Loader::new();
6363

6464
let mut source = SourceCoverage::default();
@@ -106,7 +106,7 @@ pub fn binary_to_source_coverage(
106106

107107
if let Some(file) = location.file() {
108108
// Only include relevant inlinees.
109-
if !allowlist.is_allowed(&file.full_path()) {
109+
if !source_allowlist.is_allowed(&file.full_path()) {
110110
continue;
111111
}
112112

0 commit comments

Comments
 (0)