1use linux_kernel_panic_parser::{LineKind, parse};
4use std::{
5 env,
6 error::Error,
7 fs,
8 io::{self, Read},
9};
10
11fn main() -> Result<(), Box<dyn Error>> {
12 let mut debug = false;
13 let mut path = None;
14 let mut positional_only = false;
15 for argument in env::args_os().skip(1) {
16 if !positional_only && argument == "--debug" {
17 debug = true;
18 } else if !positional_only && argument == "--" {
19 positional_only = true;
20 } else if !positional_only && (argument == "--help" || argument == "-h") {
21 println!(
22 "Usage: parse [--debug] [--] [path/to/panic.log]\nReads stdin when no path is supplied.\n--debug prints the parsed Rust structure to stdout."
23 );
24 return Ok(());
25 } else if (!positional_only && argument.to_string_lossy().starts_with('-'))
26 || path.is_some()
27 {
28 return Err(io::Error::new(
29 io::ErrorKind::InvalidInput,
30 "Usage: parse [--debug] [--] [path/to/panic.log]",
31 )
32 .into());
33 } else {
34 path = Some(argument);
35 }
36 }
37 let text = if let Some(path) = path {
38 fs::read_to_string(path)?
39 } else {
40 let mut text = String::new();
41 io::stdin().read_to_string(&mut text)?;
42 text
43 };
44 let log = parse(text);
45 if debug {
46 println!("{log:#?}");
47 return Ok(());
48 }
49 for line in log.lines() {
50 match line.kind() {
51 LineKind::Panic { message } => eprintln!("panic: {message}"),
52 LineKind::Cpu {
53 cpu,
54 uid,
55 pid,
56 details,
57 } => {
58 eprintln!("cpu: {cpu}, uid: {uid:?}, pid: {pid}, {details}");
59 if let Some(time) = line.timestamp() {
60 eprintln!("wall time: {time}");
61 }
62 if let Some(uptime) = line.uptime() {
63 eprintln!("uptime: {uptime}");
64 }
65 }
66 LineKind::Symbol {
67 label,
68 segment,
69 frame,
70 } => {
71 eprintln!(
72 "{label}: segment {segment:?}, {}+{}/{}",
73 frame.symbol, frame.offset, frame.size
74 );
75 }
76 LineKind::Diagnostic { label, details }
77 if matches!(label.as_str(), "Oops" | "BUG" | "#PF") =>
78 {
79 eprintln!("{label}: {details}");
80 }
81 LineKind::Frame(frame) => {
82 eprintln!("frame: {}+{}/{}", frame.symbol, frame.offset, frame.size)
83 }
84 _ => {}
85 }
86 }
87 print!("{log}");
89 Ok(())
90}