Removes heapviz (#671)
Unused, and triggers security audit problems through its dependencies.
This commit is contained in:
194
tools/heapviz/Cargo.lock
generated
194
tools/heapviz/Cargo.lock
generated
@@ -1,194 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapviz"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
"ncurses",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.150"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
|
||||
[[package]]
|
||||
name = "ncurses"
|
||||
version = "5.101.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e2c5d34d72657dc4b638a1c25d40aae81e4f1c699062f72f467237920752032"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
@@ -1,14 +0,0 @@
|
||||
[package]
|
||||
name = "heapviz"
|
||||
version = "0.1.0"
|
||||
authors = [
|
||||
"Guillaume Endignoux <guillaumee@google.com>",
|
||||
]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.1"
|
||||
lazy_static = "1.4.0"
|
||||
ncurses = "5.99.0"
|
||||
regex = "1"
|
||||
@@ -1,217 +0,0 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use clap::{App, Arg};
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader, Read, Write};
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
/// Configuration, built from CLI parameters.
|
||||
struct Config {
|
||||
/// Handle to the log file containing allocation operations.
|
||||
logfile: File,
|
||||
/// Number of allocation operations to show per second.
|
||||
fps: u64,
|
||||
}
|
||||
|
||||
fn parse_cli() -> Config {
|
||||
let matches = App::new("Heap visualizer")
|
||||
.version("0.1")
|
||||
.author("Guillaume Endignoux <guillaumee@google.com>")
|
||||
.about("Tool to visualize heap usage of libtock-rs applications")
|
||||
.arg(Arg::with_name("logfile")
|
||||
.short("f")
|
||||
.long("logfile")
|
||||
.value_name("FILE")
|
||||
.help("Log file containing allocation info (deploy OpenSK with --debug-allocations to obtain it)")
|
||||
.takes_value(true)
|
||||
.required(true))
|
||||
.arg(Arg::with_name("fps")
|
||||
.long("fps")
|
||||
.value_name("FPS")
|
||||
.help("Number of allocation operations to show per second")
|
||||
.takes_value(true)
|
||||
.default_value("20"))
|
||||
.get_matches();
|
||||
|
||||
let logpath = matches.value_of("logfile").unwrap();
|
||||
let fps = matches
|
||||
.value_of("fps")
|
||||
.unwrap()
|
||||
.parse::<u64>()
|
||||
.expect("The --fps parameter must be an integer");
|
||||
let logfile = File::open(logpath).expect("Couldn't open --logfile for reading");
|
||||
|
||||
Config { logfile, fps }
|
||||
}
|
||||
|
||||
/// An allocation or deallocation event.
|
||||
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||
struct Event {
|
||||
/// Whether this even is an allocation (true) or a deallocation (false).
|
||||
is_alloc: bool,
|
||||
/// The start address of the (de)allocated block, in bytes.
|
||||
start: usize,
|
||||
/// The length of the (de)allocated block, in bytes.
|
||||
len: usize,
|
||||
}
|
||||
|
||||
fn parse_event(line: &str) -> Option<Event> {
|
||||
// The following regex matches lines looking like the following from OpenSK's output. Such lines
|
||||
// are printed to the console when the `--debug-allocations` feature is enabled in the deploy
|
||||
// script.
|
||||
//
|
||||
// ```
|
||||
// alloc[256, 1] = 0x2002401c (2 ptrs, 384 bytes)
|
||||
// dealloc[64, 1] = 0x2002410c (1 ptrs, 512 bytes)
|
||||
// ```
|
||||
//
|
||||
// The two integers between square brackets after the (de)alloc keywords represent the length
|
||||
// and alignement of the allocated block, respectively. The integer serialized in hexadecimal
|
||||
// after the equal sign represents the starting address of the allocated block. The two
|
||||
// integers within parentheses represent statistics about the total number of allocated blocks
|
||||
// and the total number of allocated bytes after the (de)allocation operation, respectively.
|
||||
//
|
||||
// This regex captures three elements, in this order.
|
||||
// - The keyword to know whether this operation is an allocation or a deallocation.
|
||||
// - The length of the allocated block.
|
||||
// - The starting address of the allocated block.
|
||||
lazy_static! {
|
||||
static ref RE: Regex =
|
||||
Regex::new(r"^(alloc|dealloc)\[(\d+), \d+\] = 0x([0-9a-f]+) \(\d+ ptrs, \d+ bytes\)$")
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
RE.captures(line).map(|caps| {
|
||||
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();
|
||||
Event {
|
||||
is_alloc: typ == "alloc",
|
||||
start,
|
||||
len,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let config = parse_cli();
|
||||
|
||||
let mut events = Vec::new();
|
||||
for line in BufReader::new(config.logfile).lines() {
|
||||
if let Some(event) = parse_event(&line.unwrap()) {
|
||||
events.push(event);
|
||||
}
|
||||
}
|
||||
|
||||
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!("\nPress ENTER to start the visualization...");
|
||||
std::io::stdout().flush().unwrap();
|
||||
// Wait for ENTER, by reading a single byte and discarding it.
|
||||
let _ = std::io::stdin().lock().read(&mut [0u8]).unwrap();
|
||||
|
||||
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_nanos(1_000_000_000 / config.fps));
|
||||
}
|
||||
|
||||
ncurses::endwin();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_event_alloc() {
|
||||
assert_eq!(
|
||||
parse_event("alloc[256, 1] = 0x2002401c (2 ptrs, 384 bytes)"),
|
||||
Some(Event {
|
||||
is_alloc: true,
|
||||
start: 0x2002401c,
|
||||
len: 256,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_event_dealloc() {
|
||||
assert_eq!(
|
||||
parse_event("dealloc[64, 1] = 0x2002410c (1 ptrs, 512 bytes)"),
|
||||
Some(Event {
|
||||
is_alloc: false,
|
||||
start: 0x2002410c,
|
||||
len: 64,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_event_none() {
|
||||
assert_eq!(
|
||||
parse_event(
|
||||
"NRF52 HW INFO: Variant: AAD0, Part: N52840, Package: QI, Ram: K256, Flash: K1024"
|
||||
),
|
||||
None
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user