-
-
Notifications
You must be signed in to change notification settings - Fork 335
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
feat: add method unswizzling #4647
base: main
Are you sure you want to change the base?
Conversation
🚨 Detected changes in high risk code 🚨High-risk code can easily blow up and is hard to test. We had severe bugs in the past. Be extra careful when changing these files, and have an extra careful look at these:
|
|
🚨 Detected changes in high risk code 🚨High-risk code can easily blow up and is hard to test. We had severe bugs in the past. Be extra careful when changing these files, and have an extra careful look at these:
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4647 +/- ##
=============================================
+ Coverage 90.584% 90.633% +0.048%
=============================================
Files 621 621
Lines 71120 71201 +81
Branches 25306 25936 +630
=============================================
+ Hits 64424 64532 +108
+ Misses 6602 6573 -29
- Partials 94 96 +2
... and 26 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
Performance metrics 🚀
|
Revision | Plain | With Sentry | Diff |
---|---|---|---|
b9a9ffd | 1201.61 ms | 1215.06 ms | 13.45 ms |
282cc99 | 1238.27 ms | 1253.46 ms | 15.19 ms |
984eb2d | 1220.62 ms | 1235.24 ms | 14.62 ms |
4350d44 | 1228.75 ms | 1246.75 ms | 18.00 ms |
279841c | 1237.29 ms | 1254.12 ms | 16.83 ms |
e145ca1 | 1207.19 ms | 1230.67 ms | 23.48 ms |
9b9f2a0 | 1233.36 ms | 1244.04 ms | 10.68 ms |
7b022df | 1220.53 ms | 1227.56 ms | 7.03 ms |
aa225e2 | 1218.00 ms | 1236.45 ms | 18.45 ms |
9f0d9e0 | 1226.31 ms | 1242.70 ms | 16.40 ms |
App size
Revision | Plain | With Sentry | Diff |
---|---|---|---|
b9a9ffd | 21.58 KiB | 418.43 KiB | 396.85 KiB |
282cc99 | 22.85 KiB | 414.09 KiB | 391.24 KiB |
984eb2d | 20.76 KiB | 425.77 KiB | 405.01 KiB |
4350d44 | 21.58 KiB | 629.82 KiB | 608.24 KiB |
279841c | 22.84 KiB | 403.19 KiB | 380.34 KiB |
e145ca1 | 21.58 KiB | 669.70 KiB | 648.12 KiB |
9b9f2a0 | 21.58 KiB | 707.42 KiB | 685.84 KiB |
7b022df | 22.85 KiB | 412.95 KiB | 390.10 KiB |
aa225e2 | 21.58 KiB | 694.47 KiB | 672.89 KiB |
9f0d9e0 | 21.58 KiB | 424.28 KiB | 402.70 KiB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, we already tried that in the past and it always blew up the tests. We instead chose a different approach: We don't unswizzle, but we make sure the operations are NoOps when closing the SDK. I mean we can try again, but we need some good reasons. What drove you to open this PR?
@philipphofmann in #4634 I added unit tests initializing the SentrySDK with an experimental feature flag enabled or disabled. If the SentrySDK is enabled, and swizzling happens, the swizzling remains even after closing and re-enabling the SentrySDK without swizzling. We could also change this PR to only unswizzle in unit tests, i.e. using |
I agree with this!! |
🚨 Detected changes in high risk code 🚨High-risk code can easily blow up and is hard to test. We had severe bugs in the past. Be extra careful when changing these files, and have an extra careful look at these:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a few comments. I'm fine to give this a shot for the tests, but definitely not in production cause swizzling can have drastic unwanted side effects.
@@ -164,7 +234,7 @@ + (BOOL)swizzleInstanceMethod:(SEL)selector | |||
} | |||
} | |||
|
|||
swizzle(classToSwizzle, selector, factoryBlock); | |||
swizzle(classToSwizzle, selector, factoryBlock, key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m
: The key could be nil
or NULL
here, if I'm not mistaken. We check for that below with if (key)
. The swizzle method would need to handle that.
NSStringFromSelector(selector), | ||
class_isMetaClass(classToUnswizzle) ? @"class" : @"instance", classToUnswizzle); | ||
|
||
static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m
: If I'm not mistaken, this is a different mutex from the one in Swizzle. Wouldn't it be better to share one mutex as they manipulate the same dict.
NSValue *originalImplementationValue = [refsToOriginalImplementations objectForKey:keyValue]; | ||
return (IMP)[originalImplementationValue pointerValue]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m
: What happens if the dict doesn't contain a value for the key?
NSAssert(key != NULL, @"Key may not be NULL."); | ||
|
||
if (key == NULL) { | ||
NSLog(@"Key may not be NULL."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l
: I would prefer using SentryLog in here instead of NSLog.
@@ -83,6 +83,21 @@ | |||
_SentrySWWrapArg(SentrySWArguments), _SentrySWWrapArg(SentrySWReplacement), \ | |||
SentrySwizzleMode, key) | |||
|
|||
#if TEST || TESTCI | |||
/** | |||
* Unswizzles the instance method of the class. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m
: Please also add a comment that we don't want to use this in production and only for tests explaining that this isn't safe to use in production.
|
||
[SentryTestsLog clear]; | ||
|
||
[SentrySwizzle unswizzleInstanceMethod:methodForUnswizzling |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m
: I would like to have some test cases for calling unswizzleInstanceMethod for non swizzled methods and calling unswizzleInstanceMethod twice.
📜 Description
I adapted the method swizzling helper to keep a reference to the original implementation, so that the
unswizzle
methods can revert swizzling.💡 Motivation and Context
We are introducing a new experimental flag in #4634 to conditionally swizzle Objective-C methods. Therefore some unit tests (e.g
testFoo
) swizzle methods, while others (e.g.testBar
) do not. If we do not offer a functionality to unswizzle methods, they are leaking isolation, i.e.testFoo
runs beforetestBar
therefore methods are swizzled, even tough we don't want that.This is required for #4634 to pass tests.
💚 How did you test it?
I added a unit test to test the unswizzling.
📝 Checklist
You have to check all boxes before merging:
sendDefaultPII
is enabled.🔮 Next steps
#if TEST
to not be used in production