Skip to content

Commit 7a788b5

Browse files
authored
Merge pull request #275 from plasma-umass/filter-rust-stdlib
Filter Rust stdlib/dependency paths from profiling by default
2 parents 9b1540f + 49e54c6 commit 7a788b5

8 files changed

Lines changed: 597 additions & 43 deletions

File tree

libcoz/inspect.cpp

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "util.h"
3434

3535
#include "ccutil/log.h"
36+
#include "path_filter.h"
3637

3738
using namespace std;
3839

@@ -221,38 +222,6 @@ bool in_scope(const string& name, const unordered_set<string>& scope) {
221222
return in_scope_normalized(normalized, scope);
222223
}
223224

224-
static bool path_has_prefix(const string& path, const string& prefix) {
225-
if(prefix.empty())
226-
return false;
227-
if(prefix.size() > path.size())
228-
return false;
229-
if(path.compare(0, prefix.size(), prefix) != 0)
230-
return false;
231-
return path.size() == prefix.size() || path[prefix.size()] == '/';
232-
}
233-
234-
static bool is_system_path(const string& normalized) {
235-
static const vector<string> prefixes = {
236-
"/usr/include",
237-
"/usr/lib",
238-
"/usr/local/include",
239-
"/usr/local/lib",
240-
"/lib",
241-
"/lib64"
242-
};
243-
for(const auto& prefix : prefixes) {
244-
if(path_has_prefix(normalized, prefix))
245-
return true;
246-
}
247-
return false;
248-
}
249-
250-
static bool is_coz_header(const string& path) {
251-
// Never profile coz's own instrumentation header
252-
const string suffix = "/coz.h";
253-
return path.size() >= suffix.size() &&
254-
path.compare(path.size() - suffix.size(), suffix.size(), suffix) == 0;
255-
}
256225

257226
static bool file_matches_scope(const string& name,
258227
const unordered_set<string>& scope,
@@ -266,6 +235,10 @@ static bool file_matches_scope(const string& name,
266235
return false;
267236
if(scope.empty())
268237
return true;
238+
// Filter Rust toolchain/dependency paths unless user specified an explicit source scope
239+
bool default_scope = (scope.size() == 1 && scope.count("%") == 1);
240+
if(default_scope && is_rust_path(normalized))
241+
return false;
269242
return in_scope_normalized(normalized, scope);
270243
}
271244

libcoz/path_filter.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2015, Charlie Curtsinger and Emery Berger,
3+
* University of Massachusetts Amherst
4+
* This file is part of the Coz project. See LICENSE.md file at the top-level
5+
* directory of this distribution and at http://github.com/plasma-umass/coz.
6+
*/
7+
8+
#ifndef COZ_PATH_FILTER_H
9+
#define COZ_PATH_FILTER_H
10+
11+
#include <cstdlib>
12+
#include <string>
13+
#include <vector>
14+
15+
inline bool path_has_prefix(const std::string& path, const std::string& prefix) {
16+
if(prefix.empty())
17+
return false;
18+
if(prefix.size() > path.size())
19+
return false;
20+
if(path.compare(0, prefix.size(), prefix) != 0)
21+
return false;
22+
return path.size() == prefix.size() || path[prefix.size()] == '/';
23+
}
24+
25+
inline bool is_system_path(const std::string& normalized) {
26+
static const std::vector<std::string> prefixes = {
27+
"/usr/include",
28+
"/usr/lib",
29+
"/usr/local/include",
30+
"/usr/local/lib",
31+
"/lib",
32+
"/lib64"
33+
};
34+
for(const auto& prefix : prefixes) {
35+
if(path_has_prefix(normalized, prefix))
36+
return true;
37+
}
38+
return false;
39+
}
40+
41+
inline bool is_rust_path(const std::string& normalized) {
42+
// /rustc/<hash>/... paths are synthetic, always start with /rustc
43+
if(path_has_prefix(normalized, "/rustc"))
44+
return true;
45+
// .rustup and .cargo are only Rust toolchain paths when under $HOME
46+
const char* home = std::getenv("HOME");
47+
if(home && home[0] != '\0') {
48+
std::string h(home);
49+
if(path_has_prefix(normalized, h + "/.rustup"))
50+
return true;
51+
if(path_has_prefix(normalized, h + "/.cargo/registry"))
52+
return true;
53+
if(path_has_prefix(normalized, h + "/.cargo/git"))
54+
return true;
55+
}
56+
return false;
57+
}
58+
59+
inline bool is_coz_header(const std::string& path) {
60+
const std::string suffix = "/coz.h";
61+
return path.size() >= suffix.size() &&
62+
path.compare(path.size() - suffix.size(), suffix.size(), suffix) == 0;
63+
}
64+
65+
#endif // COZ_PATH_FILTER_H

rust/src/lib.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,11 @@ type GetCounterFn = unsafe extern "C" fn(libc::c_int, *const libc::c_char) -> *m
209209
/// `typedef void (*coz_add_delays_t)(void);`
210210
type AddDelaysFn = unsafe extern "C" fn();
211211

212-
#[cfg(target_os = "linux")]
213212
fn coz_get_counter(ty: libc::c_int, name: &CStr) -> Option<*mut coz_counter_t> {
214213
static GET_COUNTER: OnceCell<Option<GetCounterFn>> = OnceCell::new();
215214
let func = GET_COUNTER.get_or_init(|| {
216215
let name = CStr::from_bytes_with_nul(b"_coz_get_counter\0").unwrap();
217-
// SAFETY: We are calling an external function that does exist in Linux.
216+
// SAFETY: dlsym is available on all POSIX platforms (Linux, macOS, etc.).
218217
// No specific invariants that we must uphold have been defined.
219218
let func = unsafe { libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) };
220219
if func.is_null() {
@@ -237,7 +236,6 @@ fn coz_get_counter(ty: libc::c_int, name: &CStr) -> Option<*mut coz_counter_t> {
237236
/// This must be called after every counter increment to allow the profiler to
238237
/// inject virtual delays for causal profiling experiments. Without this call,
239238
/// the profiler cannot detect progress points and will report 0 experiments.
240-
#[cfg(target_os = "linux")]
241239
fn coz_add_delays() {
242240
static ADD_DELAYS: OnceCell<Option<AddDelaysFn>> = OnceCell::new();
243241
let func = ADD_DELAYS.get_or_init(|| {
@@ -255,11 +253,3 @@ fn coz_add_delays() {
255253
unsafe { f() };
256254
}
257255
}
258-
259-
#[cfg(not(target_os = "linux"))]
260-
fn coz_get_counter(_ty: libc::c_int, _name: &CStr) -> Option<*mut coz_counter_t> {
261-
None
262-
}
263-
264-
#[cfg(not(target_os = "linux"))]
265-
fn coz_add_delays() {}

tests/CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
add_executable(path_filter_test
2+
${CMAKE_SOURCE_DIR}/tests/path_filter/path_filter_test.cpp)
3+
target_include_directories(path_filter_test PRIVATE
4+
${CMAKE_SOURCE_DIR}/libcoz)
5+
target_compile_features(path_filter_test PRIVATE cxx_std_11)
6+
7+
add_test(NAME path_filter
8+
COMMAND path_filter_test)
9+
110
add_executable(dwarf_scope_test
211
${CMAKE_SOURCE_DIR}/tests/dwarf/dwarf_scope_test.cpp)
312
target_include_directories(dwarf_scope_test PRIVATE
@@ -21,3 +30,12 @@ add_test(NAME dwarf_scope_filter
2130
${TEST_OUTPUT_DIR})
2231
set_tests_properties(dwarf_scope_filter PROPERTIES
2332
ENVIRONMENT "PYTHONUNBUFFERED=1")
33+
34+
set(RUST_FILTER_OUTPUT_DIR "${CMAKE_BINARY_DIR}/tests/rust_filter")
35+
36+
add_test(NAME rust_source_filter
37+
COMMAND ${CMAKE_SOURCE_DIR}/tests/run_rust_filter_test.sh
38+
$<TARGET_FILE:coz>
39+
${RUST_FILTER_OUTPUT_DIR})
40+
set_tests_properties(rust_source_filter PROPERTIES
41+
ENVIRONMENT "PYTHONUNBUFFERED=1")

0 commit comments

Comments
 (0)