@@ -17,161 +17,161 @@ legitimate bugs. (We begin with such a case.)
17
17
18
18
### ` impl core::iter::RandomAccessIter for core::iter::Rev `
19
19
20
- if one calls the `iter.idx(index)` with `index <= amt`,
21
- then it calls the wrapped inner iterstor with a wrapped
22
- around value. The contract for `idx` does say that it
23
- does need to handle out-of-bounds inputs, so this
24
- appeared benign at first, but there is the corner case
25
- of an iterator that actually covers the whole range
26
- of indices, which would then return `Some(_)` here when
27
- (pnkfelix thinks) `None` should be expected.
28
-
29
- reference:
30
- https://github.com/rust-lang/rust/pull/22532#issuecomment-75168901
20
+ if one calls the ` iter.idx(index) ` with ` index <= amt ` ,
21
+ then it calls the wrapped inner iterstor with a wrapped
22
+ around value. The contract for ` idx ` does say that it
23
+ does need to handle out-of-bounds inputs, so this
24
+ appeared benign at first, but there is the corner case
25
+ of an iterator that actually covers the whole range
26
+ of indices, which would then return ` Some(_) ` here when
27
+ (pnkfelix thinks) ` None ` should be expected.
28
+
29
+ reference:
30
+ https://github.com/rust-lang/rust/pull/22532#issuecomment-75168901
31
31
32
32
### ` std::sys::windows::time::SteadyTime `
33
33
34
- `fn ns` was converting a tick count `t` to nanoseconds
35
- via the computation `t * 1_000_000_000 / frequency()`;
36
- but the multiplication there can overflow, thus losing
37
- the high-order bits.
34
+ ` fn ns ` was converting a tick count ` t ` to nanoseconds
35
+ via the computation ` t * 1_000_000_000 / frequency() ` ;
36
+ but the multiplication there can overflow, thus losing
37
+ the high-order bits.
38
38
39
- Full disclosure: This bug was known prior to landing
40
- arithmetic overflow checks, and filed as:
39
+ Full disclosure: This bug was known prior to landing
40
+ arithmetic overflow checks, and filed as:
41
41
42
- https://github.com/rust-lang/rust/issues/17845
42
+ https://github.com/rust-lang/rust/issues/17845
43
43
44
- Despite being filed, it was left unfixed for months,
45
- despite the fact that the overflow would start
46
- occurring after 2 hours of machine uptime, according to:
44
+ Despite being filed, it was left unfixed for months,
45
+ despite the fact that the overflow would start
46
+ occurring after 2 hours of machine uptime, according to:
47
47
48
- https://github.com/rust-lang/rust/pull/22788
48
+ https://github.com/rust-lang/rust/pull/22788
49
49
50
- pnkfelix included it on this list because having arithmetic
51
- overflow forces such bugs to be fixed in some manner
52
- rather than ignored.
50
+ pnkfelix included it on this list because having arithmetic
51
+ overflow forces such bugs to be fixed in some manner
52
+ rather than ignored.
53
53
54
54
### ` std::rt::lang_start `
55
55
56
- The runtime startup uses a fairly loose computation to
57
- determine the stack extent to pass to
58
- record_os_managed_stack_bounds (which sets up guard
59
- pages and fault handlers to deal with call stack over-
60
- or underflows).
61
-
62
- In this case, the arithmetic involved was actually
63
- *overflowing*, in this calculation:
64
-
65
- ```
66
- let top_plus_20k = my_stack_top + 20000;
67
- ```
68
-
69
- pnkfelix assumes that in practice this would lead to us
70
- attempting to install a guard page starting from some
71
- random location, rather than the actual desired
72
- address range. While the lack of a guard page in the
73
- right spot is probably of no consequence here (assuming
74
- that the OS is already going to stop us from actually
75
- attempting to write to stack locations resulting from
76
- overflow if that ever occurs), attempting to install a
77
- guard page on a random unrelated address range seems
78
- completely bogus.
79
- pnkfelix only observed this bug when building a 32-bit
80
- Rust on a 64-bit Linux host via cross-compilation.
81
-
82
- So, probably qualifies a rare bug.
83
- reference:
84
-
85
- https://github.com/rust-lang/rust/pull/22532#issuecomment-76927295
86
-
87
- UPDATE: In hindsight, one might argue this should be
88
- reclassified as a transient overflow, because the whole
89
- computation in context is:
90
-
91
- ```
92
- let my_stack_bottom =
93
- my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
94
- ```
95
-
96
- where `OS_DEFAULT_STACK_ESTIMATE` is a large value
97
- (> 1mb).
98
-
99
- However, my claim is that this code is playing guessing
100
- games; do we really know that the stack is sufficiently
101
- large that the computation above does not *underflow*?
102
-
103
- So pnkfelix is going to leave it on this list, at least
104
- for now. (pnkfelix subsequently changed the code to use
105
- saturated arithmetic in both cases, though obviously
106
- that could be tweaked a bit.)
56
+ The runtime startup uses a fairly loose computation to
57
+ determine the stack extent to pass to
58
+ record_os_managed_stack_bounds (which sets up guard
59
+ pages and fault handlers to deal with call stack over-
60
+ or underflows).
61
+
62
+ In this case, the arithmetic involved was actually
63
+ * overflowing* , in this calculation:
64
+
65
+ ```
66
+ let top_plus_20k = my_stack_top + 20000;
67
+ ```
68
+
69
+ pnkfelix assumes that in practice this would lead to us
70
+ attempting to install a guard page starting from some
71
+ random location, rather than the actual desired
72
+ address range. While the lack of a guard page in the
73
+ right spot is probably of no consequence here (assuming
74
+ that the OS is already going to stop us from actually
75
+ attempting to write to stack locations resulting from
76
+ overflow if that ever occurs), attempting to install a
77
+ guard page on a random unrelated address range seems
78
+ completely bogus.
79
+ pnkfelix only observed this bug when building a 32-bit
80
+ Rust on a 64-bit Linux host via cross-compilation.
81
+
82
+ So, probably qualifies a rare bug.
83
+ reference:
84
+
85
+ https://github.com/rust-lang/rust/pull/22532#issuecomment-76927295
86
+
87
+ UPDATE: In hindsight, one might argue this should be
88
+ reclassified as a transient overflow, because the whole
89
+ computation in context is:
90
+
91
+ ```
92
+ let my_stack_bottom =
93
+ my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
94
+ ```
95
+
96
+ where ` OS_DEFAULT_STACK_ESTIMATE ` is a large value
97
+ (> 1mb).
98
+
99
+ However, my claim is that this code is playing guessing
100
+ games; do we really know that the stack is sufficiently
101
+ large that the computation above does not * underflow* ?
102
+
103
+ So pnkfelix is going to leave it on this list, at least
104
+ for now. (pnkfelix subsequently changed the code to use
105
+ saturated arithmetic in both cases, though obviously
106
+ that could be tweaked a bit.)
107
107
108
108
### struct order of evaluation
109
109
110
- There is an explanatory story here:
110
+ There is an explanatory story here:
111
111
112
- https://github.com/rust-lang/rust/issues/23112
112
+ https://github.com/rust-lang/rust/issues/23112
113
113
114
- In short, one of our tests was quite weak and not
115
- actually checking the computed values. But
116
- arithmetic-overflow checking immediately pointed
117
- out an attempt to reserve a ridiculous amount
118
- of space within a `Vec`. (This was on an experimental
119
- branch of the codebase where we would fill with
120
- a series of `0xC1` bytes when a value was dropped, rather
121
- than filling with `0x00` bytes.)
114
+ In short, one of our tests was quite weak and not
115
+ actually checking the computed values. But
116
+ arithmetic-overflow checking immediately pointed
117
+ out an attempt to reserve a ridiculous amount
118
+ of space within a ` Vec ` . (This was on an experimental
119
+ branch of the codebase where we would fill with
120
+ a series of ` 0xC1 ` bytes when a value was dropped, rather
121
+ than filling with ` 0x00 ` bytes.)
122
122
123
- It is actually quite likely that this test would still
124
- have failed without the arithmetic overflow checking,
125
- but it probably would have been much harder to diagnose
126
- since the panic would have happened at some arbitrary
127
- point later in the control flow.
123
+ It is actually quite likely that this test would still
124
+ have failed without the arithmetic overflow checking,
125
+ but it probably would have been much harder to diagnose
126
+ since the panic would have happened at some arbitrary
127
+ point later in the control flow.
128
128
129
129
### Invalid ` Span ` constructions:
130
130
131
- https://github.com/rust-lang/rust/issues/23480
131
+ https://github.com/rust-lang/rust/issues/23480
132
132
133
- Experts in the syntax system probably already knew
134
- about this bug, but overflow checking forced everyone
135
- to be reminded of it, repeatedly, in:
133
+ Experts in the syntax system probably already knew
134
+ about this bug, but overflow checking forced everyone
135
+ to be reminded of it, repeatedly, in:
136
136
137
- https://github.com/rust-lang/rust/issues/23115
137
+ https://github.com/rust-lang/rust/issues/23115
138
138
139
- See in particular:
139
+ See in particular:
140
140
141
- https://github.com/rust-lang/rust/issues/23115#issuecomment-82960834
141
+ https://github.com/rust-lang/rust/issues/23115#issuecomment-82960834
142
142
143
- We have not actually *fixed* issue #23480 at the time of
144
- this writing. Instead we put in a workaround:
143
+ We have not actually * fixed* issue #23480 at the time of
144
+ this writing. Instead we put in a workaround:
145
145
146
- https://github.com/rust-lang/rust/pull/23489
146
+ https://github.com/rust-lang/rust/pull/23489
147
147
148
148
### Overflow in benchmark iteration increment
149
149
150
- The implementation of `#[bench]` was not prepared to deal
151
- with an overflow in the iteration count.
150
+ The implementation of ` #[bench] ` was not prepared to deal
151
+ with an overflow in the iteration count.
152
152
153
- The arithmetic overflow checking forced that to fail on a
154
- benchmark like
153
+ The arithmetic overflow checking forced that to fail on a
154
+ benchmark like
155
155
156
- ```rust
157
- #[bench]
158
- fn foo(b: &mut test::Bencher) {}
159
- ```
156
+ ``` rust
157
+ #[bench]
158
+ fn foo (b : & mut test :: Bencher ) {}
159
+ ```
160
160
161
- rather than return bogus results.
161
+ rather than return bogus results.
162
162
163
- The iteration count is stored in a `u64`, so overflow sounds
164
- unlikely -- even though `n` is being multiplied by 2 on every
165
- increment, so it sounds plausible that we could get to very large
166
- numbers indeed, the fact that we have to actually *run* that many
167
- iterations is what gives me pause.
163
+ The iteration count is stored in a ` u64 ` , so overflow sounds
164
+ unlikely -- even though ` n ` is being multiplied by 2 on every
165
+ increment, so it sounds plausible that we could get to very large
166
+ numbers indeed, the fact that we have to actually * run* that many
167
+ iterations is what gives me pause.
168
168
169
- At this point I am assuming that the compiler is doing something
170
- to optimize away the looping when the benchmark code is empty:
171
- keep in mind that the `#[bench]` code above is not calling the
172
- `black_box` method of `b`. Maybe we should be requring that?
169
+ At this point I am assuming that the compiler is doing something
170
+ to optimize away the looping when the benchmark code is empty:
171
+ keep in mind that the ` #[bench] ` code above is not calling the
172
+ ` black_box ` method of ` b ` . Maybe we should be requring that?
173
173
174
- Anyway, the chosen fix was to just return the results so far before
175
- hitting the overflow:
174
+ Anyway, the chosen fix was to just return the results so far before
175
+ hitting the overflow:
176
176
177
- https://github.com/rust-lang/rust/pull/23127
177
+ https://github.com/rust-lang/rust/pull/23127
0 commit comments