Skip to content
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

Remove some panics from zerovec's derive and icu_codepointtrie #6052

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Manishearth
Copy link
Member

@Manishearth Manishearth commented Feb 1, 2025

Discovered whilst working on bionic, I noticed panic machinery being pulled in.

@Manishearth Manishearth requested a review from sffc February 1, 2025 04:21
@Manishearth Manishearth requested a review from sffc as a code owner February 1, 2025 04:21
@Manishearth Manishearth requested a review from a team as a code owner February 1, 2025 04:22
@Manishearth Manishearth changed the title Remove some panics from zerovec's derive Remove some panics from zerovec's derive and icu_codepointtrie Feb 1, 2025
@Manishearth Manishearth requested a review from echeran as a code owner February 1, 2025 04:35
@Manishearth
Copy link
Member Author

Manishearth commented Feb 1, 2025

The zerovec one seems like a slam dunk to me. The codepointtrie one is iffy: it would be nice to have these panics as debug checks at least. Most Rust release builds do not panic on overflow, however Android does. We could in theory disable that behavior for the bionic binary, but I don't know if it's easy. It is nice to make an attempt to remove panics from this code. On the other hand, it makes the code gnarlier, and bugs will be harder to trace.

(I could introduce some code that wraps the wrapping arithmetic in debug assertions)

Routes to take here:

  • Land the second commit, take the complexity cost in code that is seldom looked at. Potentially add debug assertions
  • Land the second commit as a patch in bionic.
  • Don't worry too much about codesize in bionic, the owners are already fine with the 230KiB delta with panicking stuff (as opposed to 90 KiB without)
  • See if we can get bionic to build without overflow panics

We could also potentially add CI ensuring that panicking infra never makes it into bionic.

@Manishearth Manishearth force-pushed the rmpanic branch 3 times, most recently from 2073a5d to 6df2f3a Compare February 1, 2025 05:48
@Manishearth Manishearth added the U-android-bionic Bionic in Android label Feb 1, 2025
Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work. Just some small things

@@ -414,7 +414,9 @@ fn make_encode_impl(
let ty = &field.field.ty;
let accessor = &field.accessor;
quote!(
#[allow(clippy::indexing_slicing)] // generate_per_field_offsets produces valid indices
// generate_per_field_offsets produces valid indices,
// and we don't care about panics in Encode impls
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, human-readable deserialize for some VarULE types involves using EncodeAsVarULE.

Do we care about no-panic in JSON runtime mode?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we already have panics in Encode impls

@@ -108,16 +108,17 @@ pub fn derive_impl(
}
#validators
debug_assert_eq!(#remaining_offset, #ule_size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Since we are using unsafe, a debug_assert is not generally sufficient; this is easy to fix though since we are in a fallible function, though. Just change the debug_assert_eq to something that returns a UleError.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine in this case because the debug assert is double-checking something that is already known to be true. The length check that is relevant is the one before this, but I realized I could refactor this to remove unsafe by combining the indexing with the length check

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And while I was there I found something else to improve

let mut index1_pos: u32 = code_point >> SHIFT_1;
if self.header.trie_type == TrieType::Fast {
debug_assert!(
FAST_TYPE_FAST_INDEXING_MAX < code_point && code_point < self.header.high_start
);
index1_pos = index1_pos + BMP_INDEX_LENGTH - OMITTED_BMP_INDEX_1_LENGTH;
index1_pos = index1_pos.wrapping_add(BMP_INDEX_LENGTH - OMITTED_BMP_INDEX_1_LENGTH);
Copy link
Member

@sffc sffc Feb 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Given that we have a good GIGO code path, I agree with removing the panicky subtract impls in "safe release" mode like Android is using. However, I think we should keep the debug asserts in test mode. In other words, since we do this a lot in this file, please make a helper function or macro that does the wrapping_add or wrapping_sub with an explicit debug_assert and use it everywhere in this file.

The helper function/macro could eventually make its way into the shared-macro helper file. (#4467)

@sffc
Copy link
Member

sffc commented Feb 1, 2025

I prefer this option conditional on the "potentially" part:

Land the second commit, take the complexity cost in code that is seldom looked at. Potentially add debug assertions

@Manishearth
Copy link
Member Author

Works for me, happy to add debug assertions

@Manishearth
Copy link
Member Author

I managed to have a nice-looking but simple macro; and I also discovered another place in zerovec derive that could use a non-panicking bounds check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
U-android-bionic Bionic in Android
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants