about summary refs log tree commit diff
path: root/compiler/rustc_query_system
diff options
context:
space:
mode:
authorJubilee <46493976+workingjubilee@users.noreply.github.com>2024-03-12 09:04:00 -0700
committerGitHub <noreply@github.com>2024-03-12 09:04:00 -0700
commitf54350a9ba43773fb8bb3f56fba119b81b346fbc (patch)
tree0786ea2ddfd3c62ee808ba686b9f09181ce5d669 /compiler/rustc_query_system
parent45cc461bfd3819e870c44950b2e1f74c3e6616a3 (diff)
parent11f8866ca811628275a9e17c788462804444226f (diff)
downloadrust-f54350a9ba43773fb8bb3f56fba119b81b346fbc.tar.gz
rust-f54350a9ba43773fb8bb3f56fba119b81b346fbc.zip
Rollup merge of #122245 - saethlin:check-dep-graph-size, r=petrochenkov
Detect truncated DepGraph files

I suspect that the following issues are caused by truncated incr comp files:

* https://github.com/rust-lang/rust/issues/120582
* https://github.com/rust-lang/rust/issues/121499
* https://github.com/rust-lang/rust/issues/122210

We fail with an allocation failure or capacity overflow in this case because we assume that the ending bytes of an DepGraph file are the lengths of arrays. If the file has somehow been truncated then the ending bytes are probably some of our varint encoding, which tries to eliminate zero bytes, so interpreting a random 8 bytes as an array length has a very high chance of producing a byte capacity over `isize::MAX`.

Now theoretically since https://github.com/rust-lang/rust/pull/119510 merged I have fixed the out-of-disk issues and yet in https://github.com/rust-lang/rust/issues/120894#issuecomment-1945126700 I still see some decoding failures that look like out-of-disk ICEs, for example https://crater-reports.s3.amazonaws.com/beta-1.77-1/beta-2024-02-10/gh/scottfones.aoc_2022/log.txt

So this PR should ensure that we get an ICE that clearly identifies if the file in question is truncated.
Diffstat (limited to 'compiler/rustc_query_system')
-rw-r--r--compiler/rustc_query_system/src/dep_graph/serialized.rs10
1 files changed, 7 insertions, 3 deletions
diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index cc823917ce8..0c6a6358293 100644
--- a/compiler/rustc_query_system/src/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
@@ -179,13 +179,15 @@ impl SerializedDepGraph {
     pub fn decode<D: Deps>(d: &mut MemDecoder<'_>) -> SerializedDepGraph {
         // The last 16 bytes are the node count and edge count.
         debug!("position: {:?}", d.position());
-        let (node_count, edge_count) =
-            d.with_position(d.len() - 2 * IntEncodedWithFixedSize::ENCODED_SIZE, |d| {
+        let (node_count, edge_count, graph_size) =
+            d.with_position(d.len() - 3 * IntEncodedWithFixedSize::ENCODED_SIZE, |d| {
                 debug!("position: {:?}", d.position());
                 let node_count = IntEncodedWithFixedSize::decode(d).0 as usize;
                 let edge_count = IntEncodedWithFixedSize::decode(d).0 as usize;
-                (node_count, edge_count)
+                let graph_size = IntEncodedWithFixedSize::decode(d).0 as usize;
+                (node_count, edge_count, graph_size)
             });
+        assert_eq!(d.len(), graph_size);
         debug!("position: {:?}", d.position());
 
         debug!(?node_count, ?edge_count);
@@ -491,6 +493,8 @@ impl<D: Deps> EncoderState<D> {
         debug!("position: {:?}", encoder.position());
         IntEncodedWithFixedSize(node_count).encode(&mut encoder);
         IntEncodedWithFixedSize(edge_count).encode(&mut encoder);
+        let graph_size = encoder.position() + IntEncodedWithFixedSize::ENCODED_SIZE;
+        IntEncodedWithFixedSize(graph_size as u64).encode(&mut encoder);
         debug!("position: {:?}", encoder.position());
         // Drop the encoder so that nothing is written after the counts.
         let result = encoder.finish();