-
Notifications
You must be signed in to change notification settings - Fork 375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(spanner): avoid use-after-move bugs #7588
Conversation
@devbww and I debugged a use-after move issue that boiled down to these two Row iterators inspecting a data member (e.g., `row_` and `tup_`) on subsequent invocations of `op++`, after a caller may have rightfully moved the object. To avoid this issue, we keep an extra bool in both iterators to avoid the need to inspect the StatusOr data member again. Note: This issue didn't show up in our code or builds. It showed up only when trying to make a different change to `Status`. Kudos to @devbww for helping to track this down.
Google Cloud Build Logs
ℹ️ NOTE: Kokoro logs are linked from "Details" below. |
google/cloud/spanner/row_test.cc
Outdated
TEST(TupleStreamIterator, MovedFromValueOk) { | ||
std::vector<Row> rows; | ||
rows.emplace_back(MakeTestRow({{"num", Value(42)}})); | ||
rows.emplace_back(MakeTestRow({{"num", Value(42)}})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a distinct value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
google/cloud/spanner/row_test.cc
Outdated
EXPECT_NE(it, end); | ||
auto row = std::move(*it); | ||
EXPECT_STATUS_OK(row); | ||
EXPECT_EQ(1, row->size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at the values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Codecov Report
@@ Coverage Diff @@
## main #7588 +/- ##
=======================================
Coverage 95.24% 95.24%
=======================================
Files 1252 1252
Lines 112850 112894 +44
=======================================
+ Hits 107483 107529 +46
+ Misses 5367 5365 -2
Continue to review full report at Codecov.
|
Google Cloud Build Logs
ℹ️ NOTE: Kokoro logs are linked from "Details" below. |
Similar to: googleapis#7588 This code allowed callers to (rightfully) move-out the `StatusOr` that was held in `current_`. Therefore, it's a bug if we then consult the status of `current_.ok()`, because it may be in a moved-from state. The fix is to track the `current_ok_` bit separately, so that we only ever assign to `current_` and never read it after it could have been moved.
Similar to: googleapis#7588 This code allowed callers to (rightfully) move-out the `StatusOr` that was held in `current_`. Therefore, it's a bug if we then consult the status of `current_.ok()`, because it may be in a moved-from state. The fix is to track the `current_ok_` bit separately, so that we only ever assign to `current_` and never read it after it could have been moved.
Similar to: #7588 This code allowed callers to (rightfully) move-out the `StatusOr` that was held in `current_`. Therefore, it's a bug if we then consult the status of `current_.ok()`, because it may be in a moved-from state. The fix is to track the `current_ok_` bit separately, so that we only ever assign to `current_` and never read it after it could have been moved.
@devbww and I debugged a use-after move issue that boiled down to these
two Row iterators inspecting a data member (e.g.,
row_
andtup_
) onsubsequent invocations of
op++
, after a caller may have rightfullymoved the object. To avoid this issue, we keep an extra bool in both
iterators to avoid the need to inspect the StatusOr data member again.
Note: This issue didn't show up in our code or builds. It showed up only
when trying to make a different change to
Status
.Kudos to @devbww for helping to track this down.
This change is