profile woets
This commit is contained in:
parent
64d1151e96
commit
bbf99eca8b
@ -141,8 +141,8 @@ rule run_bench:
|
|||||||
export RUST_BACKTRACE=1
|
export RUST_BACKTRACE=1
|
||||||
mkdir -p $(dirname {output[0]})
|
mkdir -p $(dirname {output[0]})
|
||||||
set +e
|
set +e
|
||||||
echo $(pwd)/{input[1]}/release/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -s {select_task} -t -a -g -k {input[0]} -c ./target_symbols.csv fuzz --random -t {RUNTIME} -s {wildcards.num}
|
echo $(pwd)/{input[1]}/release/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -s {select_task} -t -a -r -g -k {input[0]} -c ./target_symbols.csv fuzz --random -t {RUNTIME} -s {wildcards.num}
|
||||||
$(pwd)/{input[1]}/release/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -s {select_task} -t -a -g -k {input[0]} -c ./target_symbols.csv fuzz --random -t {RUNTIME} -s {wildcards.num} > {output[1]} 2>&1
|
$(pwd)/{input[1]}/release/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -s {select_task} -t -a -r -g -k {input[0]} -c ./target_symbols.csv fuzz --random -t {RUNTIME} -s {wildcards.num} > {output[1]} 2>&1
|
||||||
exit 0
|
exit 0
|
||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
@ -150,8 +150,8 @@ rule run_bench:
|
|||||||
export RUST_BACKTRACE=1
|
export RUST_BACKTRACE=1
|
||||||
mkdir -p $(dirname {output[0]})
|
mkdir -p $(dirname {output[0]})
|
||||||
set +e
|
set +e
|
||||||
echo $(pwd)/{input[1]}/release/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -s {select_task} -t -a -g -k {input[0]} -c ./target_symbols.csv fuzz -t {RUNTIME} -s {wildcards.num}
|
echo $(pwd)/{input[1]}/release/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -s {select_task} -t -a -r -g -k {input[0]} -c ./target_symbols.csv fuzz -t {RUNTIME} -s {wildcards.num}
|
||||||
$(pwd)/{input[1]}/release/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -s {select_task} -t -a -g -k {input[0]} -c ./target_symbols.csv fuzz -t {RUNTIME} -s {wildcards.num} > {output[1]} 2>&1
|
$(pwd)/{input[1]}/release/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -s {select_task} -t -a -r -g -k {input[0]} -c ./target_symbols.csv fuzz -t {RUNTIME} -s {wildcards.num} > {output[1]} 2>&1
|
||||||
exit 0
|
exit 0
|
||||||
"""
|
"""
|
||||||
shell(script)
|
shell(script)
|
||||||
|
@ -56,11 +56,11 @@ where
|
|||||||
where {
|
where {
|
||||||
match &self.dumpfile {
|
match &self.dumpfile {
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
let time_has_come = self.last_dump.map(|t| Instant::now()-t > Duration::from_secs(60)).unwrap_or(true);
|
let time_has_come = self.last_dump.map(|t| Instant::now()-t > Duration::from_secs(1200)).unwrap_or(true);
|
||||||
if time_has_come {
|
if time_has_come {
|
||||||
self.last_dump = Some(Instant::now());
|
self.last_dump = Some(Instant::now());
|
||||||
// Try dumping the worst case
|
// Try dumping the worst case
|
||||||
let casename = s.with_extension(format!("at_{}h.case", (Instant::now()-self.init_time).as_secs()/60));
|
let casename = s.with_extension(format!("at_{}h.case", (Instant::now()-self.init_time).as_secs()/3600));
|
||||||
let corpus = state.corpus();
|
let corpus = state.corpus();
|
||||||
let mut worst = Duration::new(0,0);
|
let mut worst = Duration::new(0,0);
|
||||||
let mut worst_input = None;
|
let mut worst_input = None;
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl_bolts::prelude::{SerdeAny, SerdeAnyMap};
|
use libafl_bolts::prelude::{SerdeAny, SerdeAnyMap};
|
||||||
use libafl_qemu::{elf::EasyElf, read_user_reg_unchecked, GuestAddr, GuestPhysAddr};
|
use libafl_qemu::{elf::EasyElf, read_user_reg_unchecked, GuestAddr, GuestPhysAddr};
|
||||||
use std::ops::Range;
|
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
use std::ops::Range;
|
||||||
|
|
||||||
use crate::{fuzzer::{DO_NUM_INTERRUPT, FIRST_INT}, time::clock::QEMU_ISNS_PER_USEC};
|
use crate::{
|
||||||
|
fuzzer::{DO_NUM_INTERRUPT, FIRST_INT},
|
||||||
|
time::clock::QEMU_ISNS_PER_USEC,
|
||||||
|
};
|
||||||
|
|
||||||
use super::ExecInterval;
|
use super::ExecInterval;
|
||||||
|
|
||||||
@ -99,39 +102,47 @@ pub fn get_icount(emulator: &libafl_qemu::Qemu) -> u64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_bytes_to_interrupt_times(buf: &[u8], config: (usize,u32)) -> Vec<u32> {
|
pub fn input_bytes_to_interrupt_times(buf: &[u8], config: (usize, u32)) -> Vec<u32> {
|
||||||
let len = buf.len();
|
let len = buf.len();
|
||||||
let mut start_tick;
|
let mut start_tick;
|
||||||
let mut ret = Vec::with_capacity(min(DO_NUM_INTERRUPT, len/4));
|
let mut ret = Vec::with_capacity(min(DO_NUM_INTERRUPT, len / 4));
|
||||||
for i in 0..DO_NUM_INTERRUPT {
|
for i in 0..DO_NUM_INTERRUPT {
|
||||||
let mut buf4b : [u8; 4] = [0,0,0,0];
|
let mut buf4b: [u8; 4] = [0, 0, 0, 0];
|
||||||
if len >= (i+1)*4 {
|
if len >= (i + 1) * 4 {
|
||||||
for j in 0usize..4usize {
|
for j in 0usize..4usize {
|
||||||
buf4b[j]=buf[i*4+j];
|
buf4b[j] = buf[i * 4 + j];
|
||||||
}
|
}
|
||||||
start_tick = u32::from_le_bytes(buf4b);
|
start_tick = u32::from_le_bytes(buf4b);
|
||||||
if start_tick < FIRST_INT {start_tick=0;}
|
if start_tick < FIRST_INT {
|
||||||
|
start_tick = 0;
|
||||||
|
}
|
||||||
ret.push(start_tick);
|
ret.push(start_tick);
|
||||||
} else {break;}
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ret.sort_unstable();
|
ret.sort_unstable();
|
||||||
// obey the minimum inter arrival time while maintaining the sort
|
// obey the minimum inter arrival time while maintaining the sort
|
||||||
for i in 0..ret.len() {
|
for i in 0..ret.len() {
|
||||||
if ret[i]==0 {continue;}
|
if ret[i] == 0 {
|
||||||
for j in i+1..ret.len() {
|
continue;
|
||||||
if ret[j]-ret[i] < config.1 * QEMU_ISNS_PER_USEC {
|
}
|
||||||
|
for j in i + 1..ret.len() {
|
||||||
|
if ret[j] - ret[i] < config.1 * QEMU_ISNS_PER_USEC {
|
||||||
// ret[j] = u32::saturating_add(ret[i],config.1 * QEMU_ISNS_PER_USEC);
|
// ret[j] = u32::saturating_add(ret[i],config.1 * QEMU_ISNS_PER_USEC);
|
||||||
ret[j] = 0; // remove the interrupt
|
ret[j] = 0; // remove the interrupt
|
||||||
ret.sort_unstable();
|
ret.sort_unstable();
|
||||||
break;
|
break;
|
||||||
} else {break;}
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interrupt_times_to_input_bytes(interrupt_times: &[u32]) -> Vec<u8> {
|
pub fn interrupt_times_to_input_bytes(interrupt_times: &[u32]) -> Vec<u8> {
|
||||||
let mut ret = Vec::with_capacity(interrupt_times.len()*4);
|
let mut ret = Vec::with_capacity(interrupt_times.len() * 4);
|
||||||
for i in interrupt_times {
|
for i in interrupt_times {
|
||||||
ret.extend(u32::to_le_bytes(*i));
|
ret.extend(u32::to_le_bytes(*i));
|
||||||
}
|
}
|
||||||
@ -178,21 +189,57 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Build an ABB-profile from a stretch of intervals
|
/// Build an ABB-profile from a stretch of intervals
|
||||||
/// returns mapping: task_name -> (abb_addr -> (interval_count, exec_count, exec_time))
|
/// returns mapping: task_name -> (abb_addr -> (interval_count, exec_count, exec_time, woet))
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn abb_profile(
|
pub fn abb_profile(
|
||||||
mut intervals: Vec<ExecInterval>,
|
mut intervals: Vec<ExecInterval>,
|
||||||
) -> HashMap<String, HashMap<u32, (usize, usize, u64)>> {
|
) -> HashMap<String, HashMap<u32, (usize, usize, u64, u64)>> {
|
||||||
let mut ret: HashMap<String, HashMap<u32, (usize, usize, u64)>> = HashMap::new();
|
let mut ret: HashMap<String, HashMap<u32, (usize, usize, u64, u64)>> = HashMap::new();
|
||||||
intervals.sort_by_key(|x| x.get_task_name_unchecked());
|
intervals.sort_by_key(|x| x.get_task_name_unchecked());
|
||||||
intervals
|
intervals
|
||||||
.chunk_by_mut(|x, y| x.get_task_name_unchecked() == y.get_task_name_unchecked())
|
.chunk_by_mut(|x, y| x.get_task_name_unchecked() == y.get_task_name_unchecked())
|
||||||
.for_each(|x| {
|
// Iterate over all tasks
|
||||||
x.sort_by_key(|y| y.abb.as_ref().unwrap().start);
|
.for_each(|intv_of_task| {
|
||||||
x.chunk_by(|y, z| y.abb.as_ref().unwrap().start == z.abb.as_ref().unwrap().start)
|
// Iterate over all intervals of this task
|
||||||
.for_each(|y| match ret.get_mut(&y[0].get_task_name_unchecked()) {
|
intv_of_task.sort_by_key(|y| y.abb.as_ref().unwrap().start);
|
||||||
|
// Iterate over each abb of this task
|
||||||
|
let mut inter_per_abb_of_task: Vec<&mut [ExecInterval]> = intv_of_task
|
||||||
|
.chunk_by_mut(|y, z| y.abb.as_ref().unwrap().start == z.abb.as_ref().unwrap().start)
|
||||||
|
.collect();
|
||||||
|
// arrange the abbs by their start address
|
||||||
|
inter_per_abb_of_task
|
||||||
|
.iter_mut()
|
||||||
|
.for_each(|ivs_of_abb_of_task| {
|
||||||
|
ivs_of_abb_of_task.sort_by_key(|y| y.abb.as_ref().unwrap().instance_id)
|
||||||
|
});
|
||||||
|
// find the woet for this abb
|
||||||
|
let abb_woet: HashMap<GuestAddr, u64> = inter_per_abb_of_task
|
||||||
|
.iter()
|
||||||
|
.map(|ivs_of_abb_of_task| {
|
||||||
|
// group intervals by id, sum up the exec time of the abb instance
|
||||||
|
ivs_of_abb_of_task
|
||||||
|
.chunk_by(
|
||||||
|
|y, z| {
|
||||||
|
y.abb.as_ref().unwrap().instance_id
|
||||||
|
== z.abb.as_ref().unwrap().instance_id
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.map(|intv_of_abb_with_id| {
|
||||||
|
(
|
||||||
|
intv_of_abb_with_id[0].abb.as_ref().unwrap().start,
|
||||||
|
intv_of_abb_with_id
|
||||||
|
.iter()
|
||||||
|
.map(|z| z.get_exec_time())
|
||||||
|
.sum::<_>(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.max_by_key(|x| x.1)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
inter_per_abb_of_task.into_iter().for_each(|y| {
|
||||||
|
match ret.get_mut(&y[0].get_task_name_unchecked()) {
|
||||||
Option::None => {
|
Option::None => {
|
||||||
ret.insert(
|
ret.insert(
|
||||||
y[0].get_task_name_unchecked(),
|
y[0].get_task_name_unchecked(),
|
||||||
@ -202,6 +249,7 @@ pub fn abb_profile(
|
|||||||
y.len(),
|
y.len(),
|
||||||
y.iter().filter(|x| x.is_abb_end()).count(),
|
y.iter().filter(|x| x.is_abb_end()).count(),
|
||||||
y.iter().map(|z| z.get_exec_time()).sum::<_>(),
|
y.iter().map(|z| z.get_exec_time()).sum::<_>(),
|
||||||
|
abb_woet[&y[0].abb.as_ref().unwrap().start],
|
||||||
),
|
),
|
||||||
)]),
|
)]),
|
||||||
);
|
);
|
||||||
@ -213,15 +261,16 @@ pub fn abb_profile(
|
|||||||
y.len(),
|
y.len(),
|
||||||
y.iter().filter(|x| x.is_abb_end()).count(),
|
y.iter().filter(|x| x.is_abb_end()).count(),
|
||||||
y.iter().map(|z| z.get_exec_time()).sum(),
|
y.iter().map(|z| z.get_exec_time()).sum(),
|
||||||
|
abb_woet[&y[0].abb.as_ref().unwrap().start],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn unmut<T>(x: &mut T) -> &T {
|
pub fn unmut<T>(x: &mut T) -> &T {
|
||||||
&(*x)
|
&(*x)
|
||||||
}
|
}
|
||||||
|
@ -77,16 +77,15 @@ pub trait SystemTraceData: Serialize + Sized + for<'a> Deserialize<'a> + Default
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// extract computation time spent in each task and abb
|
/// extract computation time spent in each task and abb
|
||||||
/// task_name -> (abb_addr -> (interval_count, exec_count, exec_time))
|
/// task_name -> (abb_addr -> (interval_count, exec_count, exec_time, woet))
|
||||||
fn select_abb_profile(
|
fn select_abb_profile(
|
||||||
&self,
|
&self,
|
||||||
select_task: Option<String>,
|
select_task: Option<String>,
|
||||||
) -> HashMap<String, HashMap<u32, (usize, usize, u64)>> {
|
) -> HashMap<String, HashMap<u32, (usize, usize, u64, u64)>> {
|
||||||
if let Some(select_task) = select_task.as_ref() {
|
if let Some(select_task) = select_task.as_ref() {
|
||||||
// Task selected, only profile this task
|
// Task selected, only profile this task
|
||||||
if let Some(worst_instance) = self
|
let wjptybrt = self.worst_jobs_per_task_by_response_time();
|
||||||
.worst_jobs_per_task_by_response_time()
|
if let Some(worst_instance) = wjptybrt.get(select_task)
|
||||||
.get(select_task)
|
|
||||||
{
|
{
|
||||||
let t: Vec<_> = self
|
let t: Vec<_> = self
|
||||||
.intervals()
|
.intervals()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user