MCPcopy Create free account
hub / github.com/esphome/esp-stacktrace-decoder / decode

Function decode

src/lib.rs:68–155  ·  view source on GitHub ↗
(bin: &[u8], dump: &str)

Source from the content-addressed store, hash-verified

66
67#[cfg_attr(target_family = "wasm", wasm_bindgen)]
68pub fn decode(bin: &[u8], dump: &str) -> ReturnType {
69 // Prepare vector for output data
70 let mut decoded_data = Vec::<DecodedAddress>::new();
71 #[cfg(target_family = "wasm")]
72 let format_return = |decoded_data: Vec::<DecodedAddress>| {
73 decoded_data.into_iter().map(JsValue::from).collect()
74 };
75 #[cfg(not(target_family = "wasm"))]
76 let format_return = |decoded_data| {
77 decoded_data
78 };
79
80 // Used to keep slices from uncompressed section data
81 let arena_data = Arena::new();
82
83 // Parse the binary as an object file
84 let object = &object::File::parse(bin);
85 let object = match object {
86 Ok(object) => object,
87 Err(_) => return format_return(decoded_data),
88 };
89 let endianness = match object.endianness() {
90 Endianness::Little => gimli::RunTimeEndian::Little,
91 Endianness::Big => gimli::RunTimeEndian::Big
92 };
93
94 // Wrapper for the Dwarf loader
95 let mut load_section = |id: gimli::SectionId| -> Result<_, _> {
96 load_file_section(id, object, endianness, &arena_data)
97 };
98
99 // Load the Dwarf sections
100 let dwarf = gimli::Dwarf::load(&mut load_section);
101 let dwarf = match dwarf {
102 Ok(dwarf) => dwarf,
103 Err(_) => return format_return(decoded_data),
104 };
105 let ctx = Context::from_dwarf(dwarf);
106 let ctx = match ctx {
107 Ok(ctx) => ctx,
108 Err(_) => return format_return(decoded_data),
109 };
110
111 // Match everything that looks like a program address
112 let re = Regex::new(r"(4[0-9a-fA-F]{7})\b").unwrap();
113 for cap in re.captures_iter(dump) {
114 let address = u64::from_str_radix(&cap[0], 16).unwrap();
115 // Look for frame that contains the address
116 let mut frames = match ctx.find_frames(address) {
117 Ok(frames) => frames.enumerate(),
118 Err(_) => continue,
119 };
120 while let Some((_, frame)) = frames.next().unwrap() {
121 // Skip if it doesn't point to a function
122 if frame.function.is_none() {
123 continue;
124 }
125 // Extract function name

Callers 1

mainFunction · 0.85

Calls 1

load_file_sectionFunction · 0.85

Tested by

no test coverage detected