use dbgscope::dbgeng::{DbgEngError, DebugEngine};
const WAIT_MS: u32 = 60_000;
const BOUND_MS: u32 = 10_000;
fn main() {
let mut args = std::env::args().skip(1);
let Some(first) = args.next() else {
println!("usage: failed_command_output <dump> [<second dump>]");
return;
};
let second = args.next();
let engine = DebugEngine::new();
if let Err(e) = engine.open_dump(&first) {
println!("could not open {first}: {e}");
return;
}
if let Err(e) = engine.wait_for_event(WAIT_MS) {
println!("the load wait failed: {e}");
return;
}
match engine.execute_command("version") {
Ok(text) => text
.lines()
.filter(|line| line.contains("dbgeng") || line.contains("Version"))
.for_each(|line| println!("engine: {}", line.trim())),
Err(e) => println!("engine: `version` failed: {e}"),
}
unbounded(&engine, "zzzz");
bounded(&engine, "zzzz");
bounded(&engine, ".echo before the failure; zzzz");
for command in [
"dd 0 L4",
"? ntdll!Nope",
"u ntdll!Nope",
"dd ntdll!Nope",
"x ntdll!Nope",
"dt ntdll!_NOPE",
"lm m nope",
"!nosuchextension",
] {
bounded(&engine, command);
}
match engine.execute_and_wait("g", BOUND_MS) {
Ok(run) => println!("\n== execute_and_wait `g`: Ok\n{}", run.output),
Err(e) => failed("execute_and_wait `g`", &e),
}
if let Some(second) = second {
bounded(&engine, &format!(".opendump {second}"));
bounded(&engine, "||");
bounded(&engine, "||1s");
}
}
fn unbounded(engine: &DebugEngine, command: &str) {
match engine.execute_command(command) {
Ok(text) => println!("\n== execute_command `{command}`: Ok\n{text}"),
Err(e) => failed(&format!("execute_command `{command}`"), &e),
}
}
fn bounded(engine: &DebugEngine, command: &str) {
match engine.execute_command_bounded(command, BOUND_MS) {
Ok(run) => println!(
"\n== execute_command_bounded `{command}`: Ok (cut short: {:?})\n{}",
run.cut_short, run.output
),
Err(e) => failed(&format!("execute_command_bounded `{command}`"), &e),
}
}
fn failed(what: &str, error: &DbgEngError) {
println!("\n== {what}: Err `{error}`");
match error.output() {
Some(output) => println!("captured {} bytes:\n{output:?}", output.len()),
None => println!("no capture on this error"),
}
}