Skip to content

Commit 2f62c28

Browse files
appdenfacebook-github-bot
authored andcommittedApr 28, 2021
Fix crash in RCTCoreModulesClassProvider during quit
Summary: This intentionally leaks the static map, since it still might be accessed after static destructors are run. This is a common approach to this problem, see facebook#22607 and facebook/componentkit#906 as examples. It also sets up an autorelease pool from `RCTNativeModule::invoke` as a precaution since there's no strict guarantee one exists when it is called. Changelog: [iOS][Fixed] - Fix crash in RCTCoreModulesClassProvider during quit Reviewed By: RSNara Differential Revision: D27932062 fbshipit-source-id: fa75da4b78290027a762440ac6943c81b8594a57
1 parent 08ea434 commit 2f62c28

File tree

10 files changed

+39
-28
lines changed

10 files changed

+39
-28
lines changed
 

‎Libraries/Blob/RCTBlobPlugins.mm

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717
#import <unordered_map>
1818

1919
Class RCTBlobClassProvider(const char *name) {
20-
static std::unordered_map<std::string, Class (*)(void)> sCoreModuleClassMap = {
20+
// Intentionally leak to avoid crashing after static destructors are run.
21+
static const auto sCoreModuleClassMap = new const std::unordered_map<std::string, Class (*)(void)>{
2122
{"FileReaderModule", RCTFileReaderModuleCls},
2223
{"BlobModule", RCTBlobManagerCls},
2324
};
2425

25-
auto p = sCoreModuleClassMap.find(name);
26-
if (p != sCoreModuleClassMap.end()) {
26+
auto p = sCoreModuleClassMap->find(name);
27+
if (p != sCoreModuleClassMap->end()) {
2728
auto classFunc = p->second;
2829
return classFunc();
2930
}

‎Libraries/Image/RCTImagePlugins.mm

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,17 @@
1717
#import <unordered_map>
1818

1919
Class RCTImageClassProvider(const char *name) {
20-
static std::unordered_map<std::string, Class (*)(void)> sCoreModuleClassMap = {
20+
// Intentionally leak to avoid crashing after static destructors are run.
21+
static const auto sCoreModuleClassMap = new const std::unordered_map<std::string, Class (*)(void)>{
2122
{"GIFImageDecoder", RCTGIFImageDecoderCls},
2223
{"ImageEditingManager", RCTImageEditingManagerCls},
2324
{"ImageLoader", RCTImageLoaderCls},
2425
{"ImageStoreManager", RCTImageStoreManagerCls},
2526
{"LocalAssetImageLoader", RCTLocalAssetImageLoaderCls},
2627
};
2728

28-
auto p = sCoreModuleClassMap.find(name);
29-
if (p != sCoreModuleClassMap.end()) {
29+
auto p = sCoreModuleClassMap->find(name);
30+
if (p != sCoreModuleClassMap->end()) {
3031
auto classFunc = p->second;
3132
return classFunc();
3233
}

‎Libraries/LinkingIOS/RCTLinkingPlugins.mm

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
#import <unordered_map>
1818

1919
Class RCTLinkingClassProvider(const char *name) {
20-
static std::unordered_map<std::string, Class (*)(void)> sCoreModuleClassMap = {
20+
// Intentionally leak to avoid crashing after static destructors are run.
21+
static const auto sCoreModuleClassMap = new const std::unordered_map<std::string, Class (*)(void)>{
2122
{"LinkingManager", RCTLinkingManagerCls},
2223
};
2324

24-
auto p = sCoreModuleClassMap.find(name);
25-
if (p != sCoreModuleClassMap.end()) {
25+
auto p = sCoreModuleClassMap->find(name);
26+
if (p != sCoreModuleClassMap->end()) {
2627
auto classFunc = p->second;
2728
return classFunc();
2829
}

‎Libraries/NativeAnimation/RCTAnimationPlugins.mm

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717
#import <unordered_map>
1818

1919
Class RCTAnimationClassProvider(const char *name) {
20-
static std::unordered_map<std::string, Class (*)(void)> sCoreModuleClassMap = {
20+
// Intentionally leak to avoid crashing after static destructors are run.
21+
static const auto sCoreModuleClassMap = new const std::unordered_map<std::string, Class (*)(void)>{
2122
{"NativeAnimatedModule", RCTNativeAnimatedModuleCls},
2223
{"NativeAnimatedTurboModule", RCTNativeAnimatedTurboModuleCls},
2324
};
2425

25-
auto p = sCoreModuleClassMap.find(name);
26-
if (p != sCoreModuleClassMap.end()) {
26+
auto p = sCoreModuleClassMap->find(name);
27+
if (p != sCoreModuleClassMap->end()) {
2728
auto classFunc = p->second;
2829
return classFunc();
2930
}

‎Libraries/Network/RCTNetworkPlugins.mm

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@
1717
#import <unordered_map>
1818

1919
Class RCTNetworkClassProvider(const char *name) {
20-
static std::unordered_map<std::string, Class (*)(void)> sCoreModuleClassMap = {
20+
// Intentionally leak to avoid crashing after static destructors are run.
21+
static const auto sCoreModuleClassMap = new const std::unordered_map<std::string, Class (*)(void)>{
2122
{"Networking", RCTNetworkingCls},
2223
{"DataRequestHandler", RCTDataRequestHandlerCls},
2324
{"FileRequestHandler", RCTFileRequestHandlerCls},
2425
{"HTTPRequestHandler", RCTHTTPRequestHandlerCls},
2526
};
2627

27-
auto p = sCoreModuleClassMap.find(name);
28-
if (p != sCoreModuleClassMap.end()) {
28+
auto p = sCoreModuleClassMap->find(name);
29+
if (p != sCoreModuleClassMap->end()) {
2930
auto classFunc = p->second;
3031
return classFunc();
3132
}

‎Libraries/PushNotificationIOS/RCTPushNotificationPlugins.mm

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
#import <unordered_map>
1818

1919
Class RCTPushNotificationClassProvider(const char *name) {
20-
static std::unordered_map<std::string, Class (*)(void)> sCoreModuleClassMap = {
20+
// Intentionally leak to avoid crashing after static destructors are run.
21+
static const auto sCoreModuleClassMap = new const std::unordered_map<std::string, Class (*)(void)>{
2122
{"PushNotificationManager", RCTPushNotificationManagerCls},
2223
};
2324

24-
auto p = sCoreModuleClassMap.find(name);
25-
if (p != sCoreModuleClassMap.end()) {
25+
auto p = sCoreModuleClassMap->find(name);
26+
if (p != sCoreModuleClassMap->end()) {
2627
auto classFunc = p->second;
2728
return classFunc();
2829
}

‎Libraries/Settings/RCTSettingsPlugins.mm

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
#import <unordered_map>
1818

1919
Class RCTSettingsClassProvider(const char *name) {
20-
static std::unordered_map<std::string, Class (*)(void)> sCoreModuleClassMap = {
20+
// Intentionally leak to avoid crashing after static destructors are run.
21+
static const auto sCoreModuleClassMap = new const std::unordered_map<std::string, Class (*)(void)>{
2122
{"SettingsManager", RCTSettingsManagerCls},
2223
};
2324

24-
auto p = sCoreModuleClassMap.find(name);
25-
if (p != sCoreModuleClassMap.end()) {
25+
auto p = sCoreModuleClassMap->find(name);
26+
if (p != sCoreModuleClassMap->end()) {
2627
auto classFunc = p->second;
2728
return classFunc();
2829
}

‎Libraries/Vibration/RCTVibrationPlugins.mm

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
#import <unordered_map>
1818

1919
Class RCTVibrationClassProvider(const char *name) {
20-
static std::unordered_map<std::string, Class (*)(void)> sCoreModuleClassMap = {
20+
// Intentionally leak to avoid crashing after static destructors are run.
21+
static const auto sCoreModuleClassMap = new const std::unordered_map<std::string, Class (*)(void)>{
2122
{"Vibration", RCTVibrationCls},
2223
};
2324

24-
auto p = sCoreModuleClassMap.find(name);
25-
if (p != sCoreModuleClassMap.end()) {
25+
auto p = sCoreModuleClassMap->find(name);
26+
if (p != sCoreModuleClassMap->end()) {
2627
auto classFunc = p->second;
2728
return classFunc();
2829
}

‎React/CoreModules/CoreModulesPlugins.mm

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
#import <unordered_map>
1818

1919
Class RCTCoreModulesClassProvider(const char *name) {
20-
static std::unordered_map<std::string, Class (*)(void)> sCoreModuleClassMap = {
20+
// Intentionally leak to avoid crashing after static destructors are run.
21+
static const auto sCoreModuleClassMap = new const std::unordered_map<std::string, Class (*)(void)>{
2122
{"AccessibilityManager", RCTAccessibilityManagerCls},
2223
{"Appearance", RCTAppearanceCls},
2324
{"DeviceInfo", RCTDeviceInfoCls},
@@ -45,8 +46,8 @@ Class RCTCoreModulesClassProvider(const char *name) {
4546
{"EventDispatcher", RCTEventDispatcherCls},
4647
};
4748

48-
auto p = sCoreModuleClassMap.find(name);
49-
if (p != sCoreModuleClassMap.end()) {
49+
auto p = sCoreModuleClassMap->find(name);
50+
if (p != sCoreModuleClassMap->end()) {
5051
auto classFunc = p->second;
5152
return classFunc();
5253
}

‎React/CxxModule/RCTNativeModule.mm

+3-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ static MethodCallResult invokeInner(
100100
#else
101101
(void)(callId);
102102
#endif
103-
invokeInner(weakBridge, weakModuleData, methodId, std::move(params), callId, isSyncModule ? Sync : Async);
103+
@autoreleasepool {
104+
invokeInner(weakBridge, weakModuleData, methodId, std::move(params), callId, isSyncModule ? Sync : Async);
105+
}
104106
};
105107

106108
if (isSyncModule) {

0 commit comments

Comments
 (0)
Please sign in to comment.