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

Change jsinspector back to a shared library in the CMake build #42144

Closed
wants to merge 1 commit into from

Conversation

motiz88
Copy link
Contributor

@motiz88 motiz88 commented Jan 4, 2024

Summary:
D51895785 changed several CMake libraries from shared to static, including jsinspector. This happens to be semantically incorrect in the case of jsinspector, as the library contains singletons which can be inadvertently duplicated due to static linking. As a result, different parts of the code can end up accessing different instances of the supposed singleton, leading to bugs.

Here we revert the change to jsinspector (only) and add an explanatory comment to signpost this for future readers.

More context & general principle

While nothing is broken today, allowing static libraries to contain global state is brittle and breaks in surprising ways:

  • The upcoming diff D52231237 introduces a new dependency on jsinspector which builds cleanly, but causes debugging to stop working because of the duplicated singleton.
  • The only reason debugging currently works in the CMake build of Bridgeless is by a happy accident: the shared library hermesinstancejni depends on reactnativejni through a chain of three other libraries unrelated to debugging, and as a result, can access reactnativejni's copy of jsinspector (see graph).

{F1237835169}

It seems that the safest rule of thumb, given the way React Native is currently structured, is that singletons should live in their own shared libraries so no call site can cause them to be duplicated through static linking. (It's reasonable to revisit this guidance if we manage to consolidate React Native into one monolithic shared library, eliminating the footgun at the source.)

Changelog:
[Internal] [Changed] - Change jsinspector back to a shared library in the CMake build.

Differential Revision: D52541488

@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 Jan 4, 2024
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D52541488

@analysis-bot
Copy link

analysis-bot commented Jan 4, 2024

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 16,660,380 +86,200
android hermes armeabi-v7a n/a --
android hermes x86 n/a --
android hermes x86_64 n/a --
android jsc arm64-v8a 20,041,410 +86,201
android jsc armeabi-v7a n/a --
android jsc x86 n/a --
android jsc x86_64 n/a --

Base commit: 5aa425c
Branch: main

…ook#42144)

Summary:

D51895785 changed several CMake libraries from shared to static, including `jsinspector`. This happens to be semantically incorrect in the case of `jsinspector`, as the library contains singletons which can be inadvertently duplicated due to static linking. As a result, different parts of the code can end up accessing different instances of a supposed singleton, leading to bugs.

Here we revert the change to `jsinspector` (only) and add an explanatory comment to signpost this for future readers.

## More context & general principle

While nothing is broken today, allowing static libraries to contain global state is brittle and breaks in surprising ways:

* The upcoming diff D52231237 introduces a new dependency on `jsinspector` which builds cleanly, but causes debugging to stop working because of the duplicated singleton.
* The only reason debugging currently works in the CMake build of Bridgeless is by a happy accident: the shared library `hermesinstancejni` depends on `reactnativejni` through a chain of three other libraries unrelated to debugging, and as a result, can access `reactnativejni`'s copy of `jsinspector` (see graph).

 {F1237835169} 

It seems that the safest rule of thumb, given the way React Native is currently structured, is that **singletons should live in their own shared libraries** so no call site can cause them to be duplicated through static linking. (It's reasonable to revisit this guidance if we manage to consolidate React Native into one monolithic shared library, eliminating the footgun at the source.)

Changelog:
[Internal] [Changed] - Change jsinspector back to a shared library in the CMake build.

Reviewed By: cortinico, NickGerleman

Differential Revision: D52541488
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D52541488

Copy link

github-actions bot commented Jan 4, 2024

This pull request was successfully merged by @motiz88 in 9ba3bc9.

When will my fix make it into a release? | Upcoming Releases

@github-actions github-actions bot added the Merged This PR has been merged. label Jan 4, 2024
@facebook-github-bot
Copy link
Contributor

This pull request has been merged in 9ba3bc9.

Othinn pushed a commit to Othinn/react-native that referenced this pull request Jan 9, 2024
…ook#42144)

Summary:
Pull Request resolved: facebook#42144

D51895785 changed several CMake libraries from shared to static, including `jsinspector`. This happens to be semantically incorrect in the case of `jsinspector`, as the library contains singletons which can be inadvertently duplicated due to static linking. As a result, different parts of the code can end up accessing different instances of a supposed singleton, leading to bugs.

Here we revert the change to `jsinspector` (only) and add an explanatory comment to signpost this for future readers.

## More context & general principle

While nothing is broken today, allowing static libraries to contain global state is brittle and breaks in surprising ways:

* The upcoming diff D52231237 introduces a new dependency on `jsinspector` which builds cleanly, but causes debugging to stop working because of the duplicated singleton.
* The only reason debugging currently works in the CMake build of Bridgeless is by a happy accident: the shared library `hermesinstancejni` depends on `reactnativejni` through a chain of three other libraries unrelated to debugging, and as a result, can access `reactnativejni`'s copy of `jsinspector` (see graph).

 {F1237835169}

It seems that the safest rule of thumb, given the way React Native is currently structured, is that **singletons should live in their own shared libraries** so no call site can cause them to be duplicated through static linking. (It's reasonable to revisit this guidance if we manage to consolidate React Native into one monolithic shared library, eliminating the footgun at the source.)

Changelog:
[Internal] [Changed] - Change jsinspector back to a shared library in the CMake build.

Reviewed By: cortinico, NickGerleman

Differential Revision: D52541488

fbshipit-source-id: 502210add0b734a9bbc470bdf38fb70a41e149a9
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. fb-exported Merged This PR has been merged. p: Facebook Partner: Facebook Partner
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants