diff options
author | Alexis Beingessner <a.beingessner@gmail.com> | 2017-10-19 23:58:02 -0400 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-10-20 15:15:22 +0200 |
commit | f7f898b3b35da9e9274a0e20b1a70f25098b2363 (patch) | |
tree | 3ad267edd33aa2b21eb3edab8b4bd4fd7272fce3 | |
parent | 07e9794306d597afe5d90d192fd32a99572c3cc3 (diff) | |
download | servo-f7f898b3b35da9e9274a0e20b1a70f25098b2363.tar.gz servo-f7f898b3b35da9e9274a0e20b1a70f25098b2363.zip |
Report hash value at HashMap corruption location.
-rw-r--r-- | components/hashglobe/src/diagnostic.rs | 17 | ||||
-rw-r--r-- | components/hashglobe/src/hash_map.rs | 6 | ||||
-rw-r--r-- | components/hashglobe/src/table.rs | 9 |
3 files changed, 27 insertions, 5 deletions
diff --git a/components/hashglobe/src/diagnostic.rs b/components/hashglobe/src/diagnostic.rs index f761e31a6ab..e5cfebf5168 100644 --- a/components/hashglobe/src/diagnostic.rs +++ b/components/hashglobe/src/diagnostic.rs @@ -62,17 +62,21 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S> let mut position = 0; let mut count = 0; let mut bad_canary = None; - for (_,v) in self.map.iter() { + + let mut iter = self.map.iter(); + while let Some((h, _, v)) = iter.next_with_hash() { let canary_ref = &v.0; position += 1; + if *canary_ref == CANARY { continue; } + count += 1; - bad_canary = Some((*canary_ref, canary_ref, position)); + bad_canary = Some((h, *canary_ref, canary_ref, position)); } if let Some(c) = bad_canary { - self.report_corruption(c.0, c.1, c.2, count); + self.report_corruption(c.0, c.1, c.2, c.3, count); } } @@ -158,6 +162,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S> #[inline(never)] fn report_corruption( &self, + hash: usize, canary: usize, canary_addr: *const usize, position: usize, @@ -172,12 +177,14 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S> value.as_ptr(), ); } + panic!( - concat!("HashMap Corruption (sz={}, cap={}, pairsz={}, cnry={:#x}, count={}, ", - "last_pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})"), + concat!("HashMap Corruption (sz={}, cap={}, pairsz={}, hash={:#x}, cnry={:#x}, ", + "count={}, last_pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})"), self.map.len(), self.map.raw_capacity(), ::std::mem::size_of::<(K, (usize, V))>(), + hash, canary, count, position, diff --git a/components/hashglobe/src/hash_map.rs b/components/hashglobe/src/hash_map.rs index e17f6fd6a8e..e588b5b208c 100644 --- a/components/hashglobe/src/hash_map.rs +++ b/components/hashglobe/src/hash_map.rs @@ -1339,6 +1339,12 @@ impl<'a, K: Debug, V: Debug> fmt::Debug for Iter<'a, K, V> { } } +impl<'a, K: 'a, V: 'a> Iter<'a, K, V> { + pub fn next_with_hash(&mut self) -> Option<(usize, &'a K, &'a V)> { + self.inner.next_with_hash() + } +} + /// A mutable iterator over the entries of a `HashMap`. /// /// This `struct` is created by the [`iter_mut`] method on [`HashMap`]. See its diff --git a/components/hashglobe/src/table.rs b/components/hashglobe/src/table.rs index adaf52ee54e..65542de4be2 100644 --- a/components/hashglobe/src/table.rs +++ b/components/hashglobe/src/table.rs @@ -1130,6 +1130,15 @@ impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> { } } +impl<'a, K, V> Iter<'a, K, V> { + pub fn next_with_hash(&mut self) -> Option<(usize, &'a K, &'a V)> { + self.iter.next().map(|raw| unsafe { + let (hash_ptr, pair_ptr) = raw.hash_pair(); + (*hash_ptr, &(*pair_ptr).0, &(*pair_ptr).1) + }) + } +} + impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = (&'a K, &'a mut V); |