Auto merge of #18861 - upsuper:diagnose-fix, r=Manishearth

Some fixes to diagnostic hashmap

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18861)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-10-13 02:11:55 -05:00 committed by GitHub
commit ec00c660f0

View file

@ -1,6 +1,7 @@
use hash_map::HashMap; use hash_map::HashMap;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::hash::{BuildHasher, Hash}; use std::hash::{BuildHasher, Hash};
use std::ptr;
use FailedAllocationError; use FailedAllocationError;
@ -9,6 +10,11 @@ const CANARY: usize = 0x42cafe99;
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
const CANARY: usize = 0x42cafe9942cafe99; const CANARY: usize = 0x42cafe9942cafe99;
#[cfg(target_pointer_width = "32")]
const POISON: usize = 0xdeadbeef;
#[cfg(target_pointer_width = "64")]
const POISON: usize = 0xdeadbeefdeadbeef;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
enum JournalEntry { enum JournalEntry {
Insert(usize), Insert(usize),
@ -54,17 +60,19 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
fn verify(&self) { fn verify(&self) {
let mut position = 0; let mut position = 0;
let mut bad_canary: Option<(usize, *const usize)> = None; let mut count = 0;
let mut bad_canary = None;
for (_,v) in self.map.iter() { for (_,v) in self.map.iter() {
let canary_ref = &v.0; let canary_ref = &v.0;
position += 1;
if *canary_ref == CANARY { if *canary_ref == CANARY {
position += 1;
continue; continue;
} }
bad_canary = Some((*canary_ref, canary_ref)); count += 1;
bad_canary = Some((*canary_ref, canary_ref, position));
} }
if let Some(c) = bad_canary { if let Some(c) = bad_canary {
self.report_corruption(c.0, c.1, position); self.report_corruption(c.0, c.1, c.2, count);
} }
} }
@ -130,6 +138,9 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
{ {
assert!(!self.readonly); assert!(!self.readonly);
self.journal.push(JournalEntry::Remove(self.map.make_hash(k).inspect())); self.journal.push(JournalEntry::Remove(self.map.make_hash(k).inspect()));
if let Some(v) = self.map.get_mut(k) {
unsafe { ptr::write_volatile(&mut v.0, POISON); }
}
self.map.remove(k).map(|x| x.1) self.map.remove(k).map(|x| x.1)
} }
@ -149,7 +160,8 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
&self, &self,
canary: usize, canary: usize,
canary_addr: *const usize, canary_addr: *const usize,
position: usize position: usize,
count: usize,
) { ) {
use ::std::ffi::CString; use ::std::ffi::CString;
let key = b"HashMapJournal\0"; let key = b"HashMapJournal\0";
@ -161,11 +173,13 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
); );
} }
panic!( panic!(
"HashMap Corruption (sz={}, cap={}, pairsz={}, cnry={:#x}, pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})", concat!("HashMap Corruption (sz={}, cap={}, pairsz={}, cnry={:#x}, count={}, ",
"last_pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})"),
self.map.len(), self.map.len(),
self.map.raw_capacity(), self.map.raw_capacity(),
::std::mem::size_of::<(K, (usize, V))>(), ::std::mem::size_of::<(K, (usize, V))>(),
canary, canary,
count,
position, position,
self.map.raw_buffer(), self.map.raw_buffer(),
canary_addr, canary_addr,