Skip to content

Commit 05504e4

Browse files
committed
Add gdb and signal support
1 parent 5197e94 commit 05504e4

File tree

7 files changed

+360
-1712
lines changed

7 files changed

+360
-1712
lines changed

casr/src/bin/casr-csharp.rs

Lines changed: 3 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -1,179 +1,7 @@
1-
use casr::util;
2-
use libcasr::{
3-
csharp::*, exception::Exception, init_ignored_frames, report::CrashReport, stacktrace::*,
4-
};
1+
use casr::stub;
52

6-
use anyhow::{Result, bail};
7-
use clap::{Arg, ArgAction, ArgGroup};
8-
use regex::Regex;
9-
use std::path::PathBuf;
10-
use std::process::Command;
3+
use anyhow::Result;
114

125
fn main() -> Result<()> {
13-
let matches = clap::Command::new("casr-csharp")
14-
.version(clap::crate_version!())
15-
.about("Create CASR reports (.casrep) from C# reports")
16-
.term_width(90)
17-
.arg(
18-
Arg::new("output")
19-
.short('o')
20-
.long("output")
21-
.action(ArgAction::Set)
22-
.value_parser(clap::value_parser!(PathBuf))
23-
.value_name("REPORT")
24-
.help(
25-
"Path to save report. Path can be a directory, then report name is generated",
26-
),
27-
)
28-
.arg(
29-
Arg::new("stdout")
30-
.action(ArgAction::SetTrue)
31-
.long("stdout")
32-
.help("Print CASR report to stdout"),
33-
)
34-
.group(
35-
ArgGroup::new("out")
36-
.args(["stdout", "output"])
37-
.required(true),
38-
)
39-
.arg(
40-
Arg::new("stdin")
41-
.long("stdin")
42-
.action(ArgAction::Set)
43-
.value_parser(clap::value_parser!(PathBuf))
44-
.value_name("FILE")
45-
.help("Stdin file for program"),
46-
)
47-
.arg(
48-
Arg::new("timeout")
49-
.short('t')
50-
.long("timeout")
51-
.action(ArgAction::Set)
52-
.default_value("0")
53-
.value_name("SECONDS")
54-
.help("Timeout (in seconds) for target execution, 0 value means that timeout is disabled")
55-
.value_parser(clap::value_parser!(u64))
56-
)
57-
.arg(
58-
Arg::new("ignore")
59-
.long("ignore")
60-
.action(ArgAction::Set)
61-
.value_parser(clap::value_parser!(PathBuf))
62-
.value_name("FILE")
63-
.help("File with regular expressions for functions and file paths that should be ignored"),
64-
)
65-
.arg(
66-
Arg::new("strip-path")
67-
.long("strip-path")
68-
.env("CASR_STRIP_PATH")
69-
.action(ArgAction::Set)
70-
.value_name("PREFIX")
71-
.help("Path prefix to strip from stacktrace and crash line"),
72-
)
73-
.arg(
74-
Arg::new("ld-preload")
75-
.long("ld-preload")
76-
.env("CASR_PRELOAD")
77-
.action(ArgAction::Set)
78-
.num_args(1..)
79-
.value_name("LIBS")
80-
.value_parser(clap::value_parser!(String))
81-
.help("Set LD_PRELOAD for the target program without disrupting the CASR process itself (both ` ` and `:` are valid delimiter)")
82-
)
83-
.arg(
84-
Arg::new("ARGS")
85-
.action(ArgAction::Set)
86-
.num_args(1..)
87-
.last(true)
88-
.required(true)
89-
.help("Add \"-- <path> <arguments>\" to run"),
90-
)
91-
.get_matches();
92-
93-
init_ignored_frames!("csharp", "cpp");
94-
if let Some(path) = matches.get_one::<PathBuf>("ignore") {
95-
util::add_custom_ignored_frames(path)?;
96-
}
97-
// Get program args.
98-
let argv: Vec<&str> = if let Some(argvs) = matches.get_many::<String>("ARGS") {
99-
argvs.map(|s| s.as_str()).collect()
100-
} else {
101-
bail!("Wrong arguments for starting program");
102-
};
103-
104-
// Check that args are valid.
105-
let Some(pos) = argv
106-
.iter()
107-
.position(|x| x.ends_with(".dll") || x.ends_with(".exe") || x.ends_with(".csproj"))
108-
else {
109-
bail!("dotnet/mono target is not specified by .dll, .exe or .csproj executable.");
110-
};
111-
112-
// Get stdin for target program.
113-
let stdin_file = util::stdin_from_matches(&matches)?;
114-
115-
// Get timeout.
116-
let timeout = *matches.get_one::<u64>("timeout").unwrap();
117-
118-
// Run program.
119-
let mut csharp_cmd = Command::new(argv[0]);
120-
// Set ld preload
121-
if let Some(ld_preload) = util::get_ld_preload(&matches) {
122-
csharp_cmd.env("LD_PRELOAD", ld_preload);
123-
}
124-
if let Some(ref file) = stdin_file {
125-
csharp_cmd.stdin(std::fs::File::open(file)?);
126-
}
127-
if argv.len() > 1 {
128-
csharp_cmd.args(&argv[1..]);
129-
}
130-
let csharp_result = util::get_output(&mut csharp_cmd, timeout, true)?;
131-
132-
let csharp_stderr = String::from_utf8_lossy(&csharp_result.stderr);
133-
134-
// Create report.
135-
let mut report = CrashReport::new();
136-
// Set executable path (for C# .dll, .csproj (dotnet) or .exe (mono) file).
137-
report.executable_path = argv.get(pos).unwrap().to_string();
138-
report.proc_cmdline = argv.join(" ");
139-
let _ = report.add_os_info();
140-
let _ = report.add_proc_environ();
141-
142-
// Get C# report.
143-
let csharp_stderr_list: Vec<String> =
144-
csharp_stderr.split('\n').map(|l| l.to_string()).collect();
145-
let re = Regex::new(r"^Unhandled [Ee]xception(?::\n|\. ).*").unwrap();
146-
if let Some(start) = csharp_stderr_list.iter().position(|x| re.is_match(x)) {
147-
let end = csharp_stderr_list[start..]
148-
.iter()
149-
.rposition(|x| !x.is_empty())
150-
.unwrap()
151-
+ 1;
152-
report.csharp_report = csharp_stderr_list[start..end].to_vec();
153-
let report_str = report.csharp_report.join("\n");
154-
report.stacktrace = CSharpStacktrace::extract_stacktrace(&report_str)?;
155-
if let Some(exception) = CSharpException::parse_exception(&report_str) {
156-
report.execution_class = exception;
157-
}
158-
} else {
159-
// Call casr-san
160-
return util::call_casr_san(&matches, &argv, "casr-csharp");
161-
}
162-
163-
let stacktrace = CSharpStacktrace::parse_stacktrace(&report.stacktrace)?;
164-
if let Ok(crash_line) = stacktrace.crash_line() {
165-
report.crashline = crash_line.to_string();
166-
if let CrashLine::Source(debug) = crash_line {
167-
if let Some(sources) = CrashReport::sources(&debug) {
168-
report.source = sources;
169-
}
170-
}
171-
}
172-
173-
if let Some(path) = matches.get_one::<String>("strip-path") {
174-
util::strip_paths(&mut report, &stacktrace, path);
175-
}
176-
177-
//Output report.
178-
util::output_report(&report, &matches, &argv)
6+
stub::stub("csharp")
1797
}

0 commit comments

Comments
 (0)