|
2 | 2 | extern crate kodama; |
3 | 3 | extern crate lazy_static; |
4 | 4 |
|
| 5 | +use crate::constants::{ |
| 6 | + STACK_FRAME_FILEPATH_IGNORE_REGEXES_CPP, STACK_FRAME_FILEPATH_IGNORE_REGEXES_GO, |
| 7 | + STACK_FRAME_FILEPATH_IGNORE_REGEXES_JAVA, STACK_FRAME_FILEPATH_IGNORE_REGEXES_PYTHON, |
| 8 | + STACK_FRAME_FILEPATH_IGNORE_REGEXES_RUST, STACK_FRAME_FUNCTION_IGNORE_REGEXES_CPP, |
| 9 | + STACK_FRAME_FUNCTION_IGNORE_REGEXES_GO, STACK_FRAME_FUNCTION_IGNORE_REGEXES_JAVA, |
| 10 | + STACK_FRAME_FUNCTION_IGNORE_REGEXES_PYTHON, STACK_FRAME_FUNCTION_IGNORE_REGEXES_RUST, |
| 11 | +}; |
5 | 12 | use crate::error::*; |
6 | 13 | use kodama::{linkage, Method}; |
7 | 14 | use regex::Regex; |
@@ -31,18 +38,7 @@ lazy_static::lazy_static! { |
31 | 38 | macro_rules! init_ignored_frames { |
32 | 39 | ( $( $x:expr ),* ) => { |
33 | 40 | { |
34 | | - let (funcs, files): (Vec<_>, Vec<_>) = [$($x,)*].iter().map(|&x| |
35 | | - match x { |
36 | | - "python" => (STACK_FRAME_FUNCTION_IGNORE_REGEXES_PYTHON, STACK_FRAME_FILEPATH_IGNORE_REGEXES_PYTHON), |
37 | | - "rust" => (STACK_FRAME_FUNCTION_IGNORE_REGEXES_RUST, STACK_FRAME_FILEPATH_IGNORE_REGEXES_RUST), |
38 | | - "cpp" => (STACK_FRAME_FUNCTION_IGNORE_REGEXES_CPP, STACK_FRAME_FILEPATH_IGNORE_REGEXES_CPP), |
39 | | - "go" => (STACK_FRAME_FUNCTION_IGNORE_REGEXES_GO, STACK_FRAME_FILEPATH_IGNORE_REGEXES_GO), |
40 | | - "java" => (STACK_FRAME_FUNCTION_IGNORE_REGEXES_JAVA, STACK_FRAME_FILEPATH_IGNORE_REGEXES_JAVA), |
41 | | - &_ => (["^[^.]$"].as_slice(), ["^[^.]$"].as_slice()), |
42 | | - } |
43 | | - ).unzip(); |
44 | | - *STACK_FRAME_FUNCTION_IGNORE_REGEXES.write().unwrap() = funcs.concat().iter().map(|x| x.to_string()).collect::<Vec<String>>(); |
45 | | - *STACK_FRAME_FILEPATH_IGNORE_REGEXES.write().unwrap() = files.concat().iter().map(|x| x.to_string()).collect::<Vec<String>>(); |
| 41 | + <Stacktrace as Filter>::init_frame_filter(&[$($x,)*]); |
46 | 42 | } |
47 | 43 | }; |
48 | 44 | } |
@@ -257,27 +253,77 @@ pub fn cluster_stacktraces(stacktraces: &[Stacktrace]) -> Result<Vec<u32>> { |
257 | 253 | pub trait Filter { |
258 | 254 | /// Filter frames from the stack trace that are not related to analyzed code containing crash. |
259 | 255 | fn filter(&mut self); |
| 256 | + |
| 257 | + /// Initialize global variables for stacktrace filtering |
| 258 | + /// |
| 259 | + /// # Arguments |
| 260 | + /// |
| 261 | + /// * `languages` - list of program languages for filtering |
| 262 | + fn init_frame_filter(languages: &[&str]) { |
| 263 | + let (funcs, files): (Vec<_>, Vec<_>) = languages |
| 264 | + .iter() |
| 265 | + .map(|&x| match x { |
| 266 | + "python" => ( |
| 267 | + STACK_FRAME_FUNCTION_IGNORE_REGEXES_PYTHON, |
| 268 | + STACK_FRAME_FILEPATH_IGNORE_REGEXES_PYTHON, |
| 269 | + ), |
| 270 | + "rust" => ( |
| 271 | + STACK_FRAME_FUNCTION_IGNORE_REGEXES_RUST, |
| 272 | + STACK_FRAME_FILEPATH_IGNORE_REGEXES_RUST, |
| 273 | + ), |
| 274 | + "cpp" => ( |
| 275 | + STACK_FRAME_FUNCTION_IGNORE_REGEXES_CPP, |
| 276 | + STACK_FRAME_FILEPATH_IGNORE_REGEXES_CPP, |
| 277 | + ), |
| 278 | + "go" => ( |
| 279 | + STACK_FRAME_FUNCTION_IGNORE_REGEXES_GO, |
| 280 | + STACK_FRAME_FILEPATH_IGNORE_REGEXES_GO, |
| 281 | + ), |
| 282 | + "java" => ( |
| 283 | + STACK_FRAME_FUNCTION_IGNORE_REGEXES_JAVA, |
| 284 | + STACK_FRAME_FILEPATH_IGNORE_REGEXES_JAVA, |
| 285 | + ), |
| 286 | + &_ => (["^[^.]$"].as_slice(), ["^[^.]$"].as_slice()), |
| 287 | + }) |
| 288 | + .unzip(); |
| 289 | + *STACK_FRAME_FUNCTION_IGNORE_REGEXES.write().unwrap() = funcs |
| 290 | + .concat() |
| 291 | + .iter() |
| 292 | + .map(|x| x.to_string()) |
| 293 | + .collect::<Vec<String>>(); |
| 294 | + *STACK_FRAME_FILEPATH_IGNORE_REGEXES.write().unwrap() = files |
| 295 | + .concat() |
| 296 | + .iter() |
| 297 | + .map(|x| x.to_string()) |
| 298 | + .collect::<Vec<String>>(); |
| 299 | + } |
260 | 300 | } |
261 | 301 |
|
262 | 302 | impl Filter for Stacktrace { |
263 | 303 | fn filter(&mut self) { |
264 | 304 | // Compile function regexp. |
265 | | - let rstring = STACK_FRAME_FUNCTION_IGNORE_REGEXES |
266 | | - .read() |
267 | | - .unwrap() |
268 | | - .iter() |
269 | | - .map(|s| format!("({s})|")) |
270 | | - .collect::<String>(); |
271 | | - let rfunction = Regex::new(&rstring[0..rstring.len() - 1]).unwrap(); |
| 305 | + let function_regexes = STACK_FRAME_FUNCTION_IGNORE_REGEXES.read().unwrap(); |
| 306 | + let rfunction = if !function_regexes.is_empty() { |
| 307 | + let rstring = function_regexes |
| 308 | + .iter() |
| 309 | + .map(|s| format!("({s})|")) |
| 310 | + .collect::<String>(); |
| 311 | + Regex::new(&rstring[0..rstring.len() - 1]).unwrap() |
| 312 | + } else { |
| 313 | + Regex::new(r"^[^.]$").unwrap() |
| 314 | + }; |
272 | 315 |
|
273 | 316 | // Compile file regexp. |
274 | | - let rstring = STACK_FRAME_FILEPATH_IGNORE_REGEXES |
275 | | - .read() |
276 | | - .unwrap() |
277 | | - .iter() |
278 | | - .map(|s| format!("({s})|")) |
279 | | - .collect::<String>(); |
280 | | - let rfile = Regex::new(&rstring[0..rstring.len() - 1]).unwrap(); |
| 317 | + let file_regexes = STACK_FRAME_FILEPATH_IGNORE_REGEXES.read().unwrap(); |
| 318 | + let rfile = if !file_regexes.is_empty() { |
| 319 | + let rstring = file_regexes |
| 320 | + .iter() |
| 321 | + .map(|s| format!("({s})|")) |
| 322 | + .collect::<String>(); |
| 323 | + Regex::new(&rstring[0..rstring.len() - 1]).unwrap() |
| 324 | + } else { |
| 325 | + Regex::new(r"^[^.]$").unwrap() |
| 326 | + }; |
281 | 327 |
|
282 | 328 | // For libfuzzer: delete functions below LLVMFuzzerTestOneInput |
283 | 329 | if let Some(pos) = &self |
|
0 commit comments