Add a heap visualization tool.
This commit is contained in:
@@ -26,6 +26,8 @@ cd ../..
|
|||||||
|
|
||||||
echo "Building sha256sum tool..."
|
echo "Building sha256sum tool..."
|
||||||
cargo build --manifest-path third_party/tock/tools/sha256sum/Cargo.toml
|
cargo build --manifest-path third_party/tock/tools/sha256sum/Cargo.toml
|
||||||
|
echo "Checking that heapviz tool builds properly..."
|
||||||
|
cargo build --manifest-path tools/heapviz/Cargo.toml
|
||||||
|
|
||||||
echo "Checking that CTAP2 builds properly..."
|
echo "Checking that CTAP2 builds properly..."
|
||||||
cargo check --release --target=thumbv7em-none-eabi
|
cargo check --release --target=thumbv7em-none-eabi
|
||||||
|
|||||||
12
tools/heapviz/Cargo.toml
Normal file
12
tools/heapviz/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "heapviz"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = [
|
||||||
|
"Guillaume Endignoux <guillaumee@google.com>",
|
||||||
|
]
|
||||||
|
license = "Apache-2.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ncurses = "5.99.0"
|
||||||
|
regex = "1"
|
||||||
90
tools/heapviz/src/main.rs
Normal file
90
tools/heapviz/src/main.rs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
use regex::Regex;
|
||||||
|
use std::io::{BufRead, Write};
|
||||||
|
use std::thread::sleep;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
struct Event {
|
||||||
|
is_alloc: bool,
|
||||||
|
start: usize,
|
||||||
|
len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let re = Regex::new(r"^(alloc|dealloc)\[(\d+), \d+\] = 0x([0-9a-f]+) \(\d+ ptrs, \d+ bytes\)$")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut events = Vec::new();
|
||||||
|
for line in std::io::stdin().lock().lines() {
|
||||||
|
if let Some(caps) = re.captures(&line.unwrap()) {
|
||||||
|
let typ = caps.get(1).unwrap().as_str();
|
||||||
|
let len = caps.get(2).unwrap().as_str().parse::<usize>().unwrap();
|
||||||
|
let start = usize::from_str_radix(&caps.get(3).unwrap().as_str(), 16).unwrap();
|
||||||
|
events.push(Event {
|
||||||
|
is_alloc: typ == "alloc",
|
||||||
|
start,
|
||||||
|
len,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let count_alloc = events.iter().filter(|e| e.is_alloc).count();
|
||||||
|
let count_dealloc = events.len() - count_alloc;
|
||||||
|
let start = events.iter().map(|e| e.start).min().unwrap_or(0);
|
||||||
|
let end = events.iter().map(|e| e.start + e.len).max().unwrap_or(0);
|
||||||
|
let mut usage = 0;
|
||||||
|
let peak = events
|
||||||
|
.iter()
|
||||||
|
.map(|e| {
|
||||||
|
if e.is_alloc {
|
||||||
|
usage += e.len;
|
||||||
|
} else {
|
||||||
|
usage -= e.len;
|
||||||
|
}
|
||||||
|
usage
|
||||||
|
})
|
||||||
|
.max()
|
||||||
|
.unwrap_or(0);
|
||||||
|
let len = end - start;
|
||||||
|
println!(
|
||||||
|
"Observed {} allocations and {} deallocations",
|
||||||
|
count_alloc, count_dealloc
|
||||||
|
);
|
||||||
|
println!("Start address: {:08x}", start);
|
||||||
|
println!("End address: {:08x}", end);
|
||||||
|
println!("Peak usage: {0} = {0:08x} bytes", peak);
|
||||||
|
println!("Peak consumption: {0} = {0:08x} bytes", len);
|
||||||
|
println!("Fragmentation overhead: {0} = {0:08x} bytes", len - peak);
|
||||||
|
|
||||||
|
print!("\nLoading visualization");
|
||||||
|
for _ in 0..30 {
|
||||||
|
print!(".");
|
||||||
|
std::io::stdout().flush().unwrap();
|
||||||
|
sleep(Duration::from_millis(50));
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
|
||||||
|
let window = ncurses::initscr();
|
||||||
|
ncurses::cbreak();
|
||||||
|
ncurses::noecho();
|
||||||
|
ncurses::intrflush(window, false);
|
||||||
|
ncurses::curs_set(ncurses::CURSOR_VISIBILITY::CURSOR_INVISIBLE);
|
||||||
|
|
||||||
|
let width = ncurses::getmaxx(window) as usize;
|
||||||
|
|
||||||
|
for e in events.iter() {
|
||||||
|
let position = e.start - start;
|
||||||
|
ncurses::wmove(window, (position / width) as i32, (position % width) as i32);
|
||||||
|
|
||||||
|
let mut s = Vec::with_capacity(e.len);
|
||||||
|
if e.is_alloc {
|
||||||
|
s.resize(e.len, b'#');
|
||||||
|
} else {
|
||||||
|
s.resize(e.len, b'.');
|
||||||
|
}
|
||||||
|
ncurses::addstr(std::str::from_utf8(s.as_slice()).unwrap());
|
||||||
|
ncurses::refresh();
|
||||||
|
sleep(Duration::from_millis(50));
|
||||||
|
}
|
||||||
|
|
||||||
|
ncurses::endwin();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user