Skip to content

Commit

Permalink
Merge branch 'ispras:master' into add-casr-csharp
Browse files Browse the repository at this point in the history
  • Loading branch information
headshog authored Mar 13, 2024
2 parents d936ad6 + da980b3 commit 9953a59
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 22 deletions.
50 changes: 41 additions & 9 deletions casr/src/bin/casr-cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ fn main() -> Result<()> {
.action(ArgAction::Set)
.help("Tool name that detected crashes/errors for SARIF report"),
)
.arg(
Arg::new("strip-path")
.long("strip-path")
.env("CASR_STRIP_PATH")
.action(ArgAction::Set)
.value_name("PREFIX")
.help("Path prefix to strip from crash path in joint report statistics"),
)
.get_matches();

let report_path = matches.get_one::<PathBuf>("target").unwrap();
Expand Down Expand Up @@ -120,7 +128,11 @@ fn main() -> Result<()> {
}

if report_path.is_dir() {
print_summary(report_path, matches.get_flag("unique"));
print_summary(
report_path,
matches.get_flag("unique"),
matches.get_one::<String>("strip-path"),
);
return Ok(());
}

Expand Down Expand Up @@ -793,7 +805,9 @@ fn change_text_view(layout1: &mut LinearLayout, act: Action) -> Option<EventResu
///
/// * 'unique_crash_line' - print summary only for unique crash lines
///
fn print_summary(dir: &Path, unique_crash_line: bool) {
/// * 'strip_path' - strip prefix from crash paths
///
fn print_summary(dir: &Path, unique_crash_line: bool, strip_path: Option<&String>) {
// Hash each class in whole casr directory
let mut casr_classes: BTreeMap<String, i32> = BTreeMap::new();

Expand Down Expand Up @@ -900,7 +914,7 @@ fn print_summary(dir: &Path, unique_crash_line: bool) {
report.push_str(".casrep");

let (san_desc, san_line) = if let Some((report_sum, san_desc, san_line, ubsan_flag)) =
process_report(&report, "casrep")
process_report(&report, "casrep", strip_path)
{
if !ubsan_flag {
ubsan = false;
Expand All @@ -917,7 +931,7 @@ fn print_summary(dir: &Path, unique_crash_line: bool) {
let report = report.replace(".casrep", ".gdb.casrep");
let (casr_gdb_desc, casr_gdb_line) =
if let Some((report_sum, casr_gdb_desc, casr_gdb_line, _)) =
process_report(&report, "gdb.casrep")
process_report(&report, "gdb.casrep", strip_path)
{
ubsan = false;
if san_line.is_empty() && skip_crash(&casr_gdb_line) {
Expand Down Expand Up @@ -965,13 +979,19 @@ fn print_summary(dir: &Path, unique_crash_line: bool) {

println!("==> <{}>", filename.magenta());
for info in cluster_hash.values() {
let mut path = info.0.last().unwrap().clone();
if let Some(prefix) = strip_path {
if let Ok(stripped) = Path::new(&path).strip_prefix(prefix) {
path = stripped.display().to_string();
}
}
if ubsan {
// /path/to/report.casrep: Description: crashline (path:line:column)
println!("{}: {}", info.0.last().unwrap(), info.0[0]);
println!("{}: {}", path, info.0[0]);
continue;
}
// Crash: /path/to/input or /path/to/report.casrep
println!("{}: {}", "Crash".green(), info.0.last().unwrap());
println!("{}: {}", "Crash".green(), path);
// casrep: SeverityType: Description: crashline (path:line:column) or /path/to/report.casrep
println!(" {}", info.0[0]);
if info.0.len() == 3 {
Expand Down Expand Up @@ -1012,16 +1032,28 @@ fn print_summary(dir: &Path, unique_crash_line: bool) {
///
/// * 'extension' - casrep extension
///
/// * 'strip_path' - strip prefix from report paths
///
/// # Return value
///
/// 1 String - summary of one report in cluster
/// 2 String - crash description
/// 3 String - crashline (path:line:column)
/// bool - ubsan report indicator
fn process_report(report: &str, extension: &str) -> Option<(String, String, String, bool)> {
fn process_report(
report: &str,
extension: &str,
strip_path: Option<&String>,
) -> Option<(String, String, String, bool)> {
let Ok(file) = fs::File::open(report) else {
return None;
};
let mut report = report.to_string();
if let Some(prefix) = strip_path {
if let Ok(stripped) = Path::new(&report).strip_prefix(prefix) {
report = stripped.display().to_string();
}
}
let Ok(jreport): Result<Value, _> = serde_json::from_reader(BufReader::new(file)) else {
return None;
};
Expand Down Expand Up @@ -1057,7 +1089,7 @@ fn process_report(report: &str, extension: &str) -> Option<(String, String, Stri
"{}: {}",
desc.red(),
if crashline.is_empty() {
report
&report
} else {
&crashline
}
Expand All @@ -1074,7 +1106,7 @@ fn process_report(report: &str, extension: &str) -> Option<(String, String, Stri
},
desc,
if crashline.is_empty() {
report
&report
} else {
&crashline
}
Expand Down
27 changes: 23 additions & 4 deletions casr/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ pub fn save_reports(reports: &Vec<PathBuf>, dir: &str) -> Result<()> {
Ok(())
}

/// Strip paths for stacktrace and crash line in CrashReport
/// Strip paths for stacktrace, crash line, and cmd line in CrashReport
///
/// # Arguments
///
Expand All @@ -581,10 +581,29 @@ pub fn strip_paths(report: &mut CrashReport, stacktrace: &Stacktrace, prefix: &s
report.stacktrace[idx] =
report.stacktrace[idx].replace(&entry.debug.file, &stripped.debug.file);
}
if !stripped.module.is_empty() {
report.stacktrace[idx] =
report.stacktrace[idx].replace(&entry.module, &stripped.module);
}
}
if !report.crashline.is_empty() {
if let Ok(stripped) = Path::new(&report.crashline).strip_prefix(prefix) {
report.crashline = stripped.display().to_string();

let strip_path = |path: &str| {
if let Ok(stripped) = Path::new(path).strip_prefix(prefix) {
stripped.display().to_string()
} else {
path.to_string()
}
};

if !report.crashline.is_empty() {
report.crashline = strip_path(&report.crashline);
}
if !report.proc_cmdline.is_empty() {
report.proc_cmdline = report
.proc_cmdline
.split(' ')
.map(strip_path)
.collect::<Vec<_>>()
.join(" ");
}
}
20 changes: 11 additions & 9 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,15 +395,17 @@ all reports, and converts CASR reports to SARIF format.
<REPORT|DIR> CASR report file to view or directory with reports

Options:
-v, --view <MODE> View mode [default: tree] [possible values: tree, slider,
stdout]
-u, --unique Print only unique crash lines in joint statistics
--sarif <OUTPUT> Generate SARIF report from CASR reports
--source-root <PATH> Source root path in CASR reports for SARIF report generation
--tool <NAME> Tool name that detected crashes/errors for SARIF report
[default: CASR]
-h, --help Print help
-V, --version Print version
-v, --view <MODE> View mode [default: tree] [possible values: tree, slider,
stdout]
-u, --unique Print only unique crash lines in joint statistics
--sarif <OUTPUT> Generate SARIF report from CASR reports
--source-root <PATH> Source root path in CASR reports for SARIF report generation
--tool <NAME> Tool name that detected crashes/errors for SARIF report
[default: CASR]
--strip-path <PREFIX> Path prefix to strip from crash path in joint report
statistics [env: CASR_STRIP_PATH=]
-h, --help Print help
-V, --version Print version

There are three view modes: tree, slider (list), and stdout. In stdout mode
`casr-cli` prints text-based CASR report to stdout.
Expand Down

0 comments on commit 9953a59

Please sign in to comment.