Do not crash with dirty init
This commit is contained in:
@@ -133,7 +133,7 @@ impl<'a> Fuzzer<'a> {
|
|||||||
page_size: 1 << self.entropy.read_range(5, 12),
|
page_size: 1 << self.entropy.read_range(5, 12),
|
||||||
max_word_writes: 2,
|
max_word_writes: 2,
|
||||||
max_page_erases: self.entropy.read_range(0, 50000),
|
max_page_erases: self.entropy.read_range(0, 50000),
|
||||||
strict_write: true,
|
strict_mode: true,
|
||||||
};
|
};
|
||||||
let num_pages = self.entropy.read_range(3, 64);
|
let num_pages = self.entropy.read_range(3, 64);
|
||||||
self.record(StatKey::PageSize, options.page_size);
|
self.record(StatKey::PageSize, options.page_size);
|
||||||
@@ -156,7 +156,7 @@ impl<'a> Fuzzer<'a> {
|
|||||||
if self.debug {
|
if self.debug {
|
||||||
println!("Start with dirty storage.");
|
println!("Start with dirty storage.");
|
||||||
}
|
}
|
||||||
options.strict_write = false;
|
options.strict_mode = false;
|
||||||
let storage = BufferStorage::new(storage, options);
|
let storage = BufferStorage::new(storage, options);
|
||||||
StoreDriver::Off(StoreDriverOff::new_dirty(storage))
|
StoreDriver::Off(StoreDriverOff::new_dirty(storage))
|
||||||
} else if self.entropy.read_bit() {
|
} else if self.entropy.read_bit() {
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ use alloc::vec;
|
|||||||
/// for tests and fuzzing, for which it has dedicated functionalities.
|
/// for tests and fuzzing, for which it has dedicated functionalities.
|
||||||
///
|
///
|
||||||
/// This storage tracks how many times words are written between page erase cycles, how many times
|
/// This storage tracks how many times words are written between page erase cycles, how many times
|
||||||
/// pages are erased, and whether an operation flips bits in the wrong direction (optional).
|
/// pages are erased, and whether an operation flips bits in the wrong direction. Operations panic
|
||||||
/// Operations panic if those conditions are broken. This storage also permits to interrupt
|
/// if those conditions are broken (optional). This storage also permits to interrupt operations for
|
||||||
/// operations for inspection or to corrupt the operation.
|
/// inspection or to corrupt the operation.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BufferStorage {
|
pub struct BufferStorage {
|
||||||
/// Content of the storage.
|
/// Content of the storage.
|
||||||
@@ -59,8 +59,13 @@ pub struct BufferOptions {
|
|||||||
/// How many times a page can be erased.
|
/// How many times a page can be erased.
|
||||||
pub max_page_erases: usize,
|
pub max_page_erases: usize,
|
||||||
|
|
||||||
/// Whether bits cannot be written from 0 to 1.
|
/// Whether the storage should check the flash invariant.
|
||||||
pub strict_write: bool,
|
///
|
||||||
|
/// When set, the following conditions would panic:
|
||||||
|
/// - A bit is written from 0 to 1.
|
||||||
|
/// - A word is written more than `max_word_writes`.
|
||||||
|
/// - A page is erased more than `max_page_erases`.
|
||||||
|
pub strict_mode: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Corrupts a slice given actual and expected value.
|
/// Corrupts a slice given actual and expected value.
|
||||||
@@ -214,7 +219,10 @@ impl BufferStorage {
|
|||||||
///
|
///
|
||||||
/// Panics if the maximum number of erase cycles per page is reached.
|
/// Panics if the maximum number of erase cycles per page is reached.
|
||||||
fn incr_page_erases(&mut self, page: usize) {
|
fn incr_page_erases(&mut self, page: usize) {
|
||||||
assert!(self.page_erases[page] < self.max_page_erases());
|
// Check that pages are not erased too many times.
|
||||||
|
if self.options.strict_mode {
|
||||||
|
assert!(self.page_erases[page] < self.max_page_erases());
|
||||||
|
}
|
||||||
self.page_erases[page] += 1;
|
self.page_erases[page] += 1;
|
||||||
let num_words = self.page_size() / self.word_size();
|
let num_words = self.page_size() / self.word_size();
|
||||||
for word in 0..num_words {
|
for word in 0..num_words {
|
||||||
@@ -252,7 +260,10 @@ impl BufferStorage {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let word = index / word_size + i;
|
let word = index / word_size + i;
|
||||||
assert!(self.word_writes[word] < self.max_word_writes());
|
// Check that words are not written too many times.
|
||||||
|
if self.options.strict_mode {
|
||||||
|
assert!(self.word_writes[word] < self.max_word_writes());
|
||||||
|
}
|
||||||
self.word_writes[word] += 1;
|
self.word_writes[word] += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,8 +317,8 @@ impl Storage for BufferStorage {
|
|||||||
self.interruption.tick(&operation)?;
|
self.interruption.tick(&operation)?;
|
||||||
// Check and update counters.
|
// Check and update counters.
|
||||||
self.incr_word_writes(range.start, value, value);
|
self.incr_word_writes(range.start, value, value);
|
||||||
// Check strict write.
|
// Check that bits are correctly flipped.
|
||||||
if self.options.strict_write {
|
if self.options.strict_mode {
|
||||||
for (byte, &val) in range.clone().zip(value.iter()) {
|
for (byte, &val) in range.clone().zip(value.iter()) {
|
||||||
assert_eq!(self.storage[byte] & val, val);
|
assert_eq!(self.storage[byte] & val, val);
|
||||||
}
|
}
|
||||||
@@ -472,7 +483,7 @@ mod tests {
|
|||||||
page_size: 16,
|
page_size: 16,
|
||||||
max_word_writes: 2,
|
max_word_writes: 2,
|
||||||
max_page_erases: 3,
|
max_page_erases: 3,
|
||||||
strict_write: true,
|
strict_mode: true,
|
||||||
};
|
};
|
||||||
// Those words are decreasing bit patterns. Bits are only changed from 1 to 0 and at least one
|
// Those words are decreasing bit patterns. Bits are only changed from 1 to 0 and at least one
|
||||||
// bit is changed.
|
// bit is changed.
|
||||||
|
|||||||
@@ -1257,7 +1257,7 @@ mod tests {
|
|||||||
page_size: self.page_size,
|
page_size: self.page_size,
|
||||||
max_word_writes: self.max_word_writes,
|
max_word_writes: self.max_word_writes,
|
||||||
max_page_erases: self.max_page_erases,
|
max_page_erases: self.max_page_erases,
|
||||||
strict_write: true,
|
strict_mode: true,
|
||||||
};
|
};
|
||||||
StoreDriverOff::new(options, self.num_pages)
|
StoreDriverOff::new(options, self.num_pages)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user