Skip to content

Commit 0c2db32

Browse files
ahimbergfacebook-github-bot
authored andcommitted
timing fix for RCTCxxBridge.executeApplicationScript (#25991)
Summary: In one of our test apps (actually on Mac not iOS, but same code) we very consistently crash in RCTCxxBridge.executeApplicationScript when js debugging, due to a timing issue where another thread has reset _reactInstance in between the null check on self->_reactInstance and usage of it on these lines: ``` } else if (self->_reactInstance) { self->_reactInstance->loadScriptFromString(std::make_unique<NSDataBigString>(script), ``` The thread doing the reset is doing so switching the executorClass to WebSocketExecutor. In the scenario we crash, the packager has a bundle ready and quickly returns it, though its a 34MB string being passed to NSDataBigString which must be taking long enough for the other thread to get a chance to reset. ## Changelog [iOS] [Fixed] - Fix crash in RCTCxxBridge.executeApplicationScript Pull Request resolved: #25991 Test Plan: Ran apple code path in normal from bundle file and js debugging scenarios. Reviewed By: shergin Differential Revision: D19186065 Pulled By: hramos fbshipit-source-id: ae1d4b5b50b7fb33b74aba21addc2978e917479f
1 parent a3aaa47 commit 0c2db32

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

React/CxxBridge/RCTCxxBridge.mm

+8-4
Original file line numberDiff line numberDiff line change
@@ -1334,19 +1334,23 @@ - (void)executeApplicationScript:(NSData *)script url:(NSURL *)url async:(BOOL)a
13341334
[[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptWillStartExecutingNotification
13351335
object:self->_parentBridge
13361336
userInfo:@{@"bridge" : self}];
1337+
1338+
// hold a local reference to reactInstance in case a parallel thread
1339+
// resets it between null check and usage
1340+
auto reactInstance = self->_reactInstance;
13371341
if (isRAMBundle(script)) {
13381342
[self->_performanceLogger markStartForTag:RCTPLRAMBundleLoad];
13391343
auto ramBundle = std::make_unique<JSIndexedRAMBundle>(sourceUrlStr.UTF8String);
13401344
std::unique_ptr<const JSBigString> scriptStr = ramBundle->getStartupCode();
13411345
[self->_performanceLogger markStopForTag:RCTPLRAMBundleLoad];
13421346
[self->_performanceLogger setValue:scriptStr->size() forTag:RCTPLRAMStartupCodeSize];
1343-
if (self->_reactInstance) {
1347+
if (reactInstance) {
13441348
auto registry =
13451349
RAMBundleRegistry::multipleBundlesRegistry(std::move(ramBundle), JSIndexedRAMBundle::buildFactory());
1346-
self->_reactInstance->loadRAMBundle(std::move(registry), std::move(scriptStr), sourceUrlStr.UTF8String, !async);
1350+
reactInstance->loadRAMBundle(std::move(registry), std::move(scriptStr), sourceUrlStr.UTF8String, !async);
13471351
}
1348-
} else if (self->_reactInstance) {
1349-
self->_reactInstance->loadScriptFromString(
1352+
} else if (reactInstance) {
1353+
reactInstance->loadScriptFromString(
13501354
std::make_unique<NSDataBigString>(script), sourceUrlStr.UTF8String, !async);
13511355
} else {
13521356
std::string methodName = async ? "loadApplicationScript" : "loadApplicationScriptSync";

0 commit comments

Comments
 (0)