summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs44
1 files changed, 21 insertions, 23 deletions
diff --git a/src/main.rs b/src/main.rs
index 30ed4b4..aab5cbb 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -45,7 +45,6 @@ impl fmt::Display for BlockedEvent {
const STACK_START_FILTER: &[&str] = &[
"trace_event_raw_event_sched_blocked",
"__schedule",
- "_schedule",
"schedule",
];
@@ -53,6 +52,7 @@ const STACK_END_FILTER: &[&str] = &[
"entry_SYSCALL_64_after_hwframe",
"do_syscall_64",
"__x86_sys_",
+ "syscall_exit_to_user_mode",
"ret_from_fork",
"kthread",
"worker_thread",
@@ -70,37 +70,32 @@ const STACK_FILTER: &[&[&str]] = &[
&["smpboot_thread_fn"],
];
-fn should_skip_event(ev: &BlockedEvent) -> bool {
- if ev.stacktrace.is_empty() {
- return true;
- }
+fn fn_matches(l: &str, r: &str) -> bool {
+ let idx = r.find(|c: char| c == '.' || c == '/' || c == '+');
- for i in STACK_FILTER {
- if !i.iter()
- .zip(ev.stacktrace.iter())
- .find(|(l, r)| !r.starts_with(*l)).is_some() {
- return true;
- }
+ l == if let Some(idx) = idx {
+ &r[..idx]
+ } else {
+ &r[..]
}
-
- false
}
-fn string_matches(a: &[&str], v: &str) -> bool {
- for i in a {
- if v.starts_with(i) {
- return true;
- }
+fn should_skip_event(ev: &BlockedEvent) -> bool {
+ if ev.stacktrace.is_empty() {
+ return true;
}
- false
+ STACK_FILTER.iter()
+ .any(|i| i.iter()
+ .zip(ev.stacktrace.iter())
+ .all(|(l, r)| fn_matches(l, r)))
}
fn event_trim(ev: &mut BlockedEvent) {
while ev.stacktrace.len() > 1 {
let l = ev.stacktrace.last().unwrap();
- if string_matches(STACK_END_FILTER, &l[..]) {
+ if STACK_END_FILTER.iter().any(|i| fn_matches(i, &l[..])) {
ev.stacktrace.pop();
} else {
break;
@@ -136,12 +131,15 @@ fn read_trace(mut child: std::process::Child) -> io::Result<Vec<BlockedEvent>> {
continue;
}
+ let mut skip = STACK_START_FILTER.iter();
+
while let Some(line) = lines.next_if(|i| i.starts_with(" => ")) {
let func = &line[4..];
- if !ev.stacktrace.is_empty() ||
- !string_matches(STACK_START_FILTER, func) {
- ev.stacktrace.push(func.to_string());
+ let s = skip.next();
+ if s.is_none() || !fn_matches(s.unwrap(), func) {
+ ev.stacktrace.push(func.to_string());
+ skip.all(|_i| true);
}
}