mina_tree/util/
backtrace.rs

1use backtrace::Backtrace;
2use std::fmt::Write;
3
4/// Make a backtrace without OCaml dependencies
5/// Those are very noisy and are not meaningful for our case
6/// Only Rust and Mina codebase symbols should remain.
7pub fn short_backtrace() -> String {
8    let bt = Backtrace::new();
9
10    let mut s = String::with_capacity(2000);
11
12    for (index, (filename, name, line)) in bt
13        .frames()
14        .iter()
15        .flat_map(|frame| frame.symbols())
16        .map(|sym| (sym.filename(), sym.name(), sym.lineno()))
17        .enumerate()
18        .filter(|(_, (filename, name, _))| {
19            !(filename
20                .map(|filename| {
21                    filename.ends_with("ledger/src/util/backtrace.rs")
22                        || filename
23                            .components()
24                            .any(|comp| comp.as_os_str() == "_opam")
25                })
26                .unwrap_or(false)
27                || name
28                    .as_ref()
29                    .and_then(|n| n.as_str())
30                    .map(|name| {
31                        name.starts_with("camlAsync_")
32                            || name.starts_with("camlBase__")
33                            || name.starts_with("camlCore__")
34                            || name.starts_with("camlCamlinternalLazy__")
35                            || name.starts_with("camlO1trace__") // This belongs to the mina repo, but useless to us
36                    })
37                    .unwrap_or(false))
38        })
39        .take_while(|(_, (_, name, _))| {
40            name.as_ref().and_then(|n| n.as_str()) != Some("caml_program")
41        })
42    {
43        match (name, filename, line) {
44            (Some(name), None, None) => writeln!(&mut s, " {:>3} - {}", index, name).unwrap(),
45            (Some(name), Some(filename), None) => {
46                writeln!(&mut s, " {:>3} - {:80} ({:?})", index, name, filename).unwrap();
47            }
48            (Some(name), Some(filename), Some(line)) => {
49                writeln!(
50                    &mut s,
51                    " {:>3} - {:80} ({:?}:{:?})",
52                    index, name, filename, line
53                )
54                .unwrap();
55            }
56            _ => {}
57        }
58    }
59
60    s.pop(); // Remove last newline
61    s
62}