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

Fix use-after-move in console implementation #44297

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

motiz88
Copy link
Contributor

@motiz88 motiz88 commented Apr 27, 2024

Summary:
Changelog: [Internal]

In the new CDP backend, calling any console method a second time involves a call to a moved-from std::function. This shouldn't work, but depending on the toolchain, sometimes it does - likely because moving from a std::function leaves it in an unspecified state rather than a definitely empty state, and std::functions are always copyable so falling back to a copy is technically legal.

In the code in question, we're right to want to avoid a copy of the body function into the argument of delegateExecutorSync - only one copy of this function needs to exist at a time. But the correct way to avoid this copy is to capture body by reference, as we can do that repeatedly with no ill effects. (delegateExecutorSync is, as its name suggests, synchronous, so there are no lifetime issues.) Doing this also allows us to remove the use of mutable so the capturing is by const reference.

Differential Revision: D56673529

@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Facebook Partner: Facebook Partner labels Apr 27, 2024
@analysis-bot
Copy link

analysis-bot commented Apr 28, 2024

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 19,461,330 -1
android hermes armeabi-v7a n/a --
android hermes x86 n/a --
android hermes x86_64 n/a --
android jsc arm64-v8a 22,834,242 +8
android jsc armeabi-v7a n/a --
android jsc x86 n/a --
android jsc x86_64 n/a --

Base commit: e2ad669
Branch: main

Summary:
Changelog: [Internal]

In the new CDP backend, calling any `console` method a second time involves a call to a moved-from `std::function`. This shouldn't work, and indeed results in an exception on some platforms, but isn't strictly an error according to the C++ standard: moving from a `std::function` leaves it in an [unspecified state](https://en.cppreference.com/w/cpp/utility/functional/function/function#:~:text=the%20call%20too.-,other,is%20in%20a%20valid%20but%20unspecified%20state%20right%20after%20the%20call.,-5), not necessarily an empty state, so (in particular) it's perfectly legal for the implementation to perform a copy instead of a move and leave the original variable intact.

(See [Compiler Explorer](https://godbolt.org/z/qoo5Mnd68) for proof that libc++ and libstdc++ differ on this - the former performs a copy, while the latter actually performs a move, resulting in a `std::bad_function_call` exception later.)

In the code in question, we're right to want to avoid a copy of the `body` function into the argument of `delegateExecutorSync` - only one copy of this function needs to exist at a time. But the correct way to avoid this copy is to capture `body` by reference, as we can do that repeatedly with no ill effects. (`delegateExecutorSync` is, as its name suggests, synchronous, so there are no lifetime issues.) Doing this also allows us to remove the use of `mutable` so the capturing is by *const* reference.

Differential Revision: D56673529
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Facebook Partner: Facebook Partner
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants