Skip to content

Commit 27c33f0

Browse files
impr: Speed up getBinaryImages V2
Follow up on GH-4435. Use binary image cache to get debug meta when finishing the tracer and capturing profiles. Mark all methods to get debug meta not using the cache as deprecated to ensure we migrate to the methods using the cache.
1 parent 01bdff8 commit 27c33f0

18 files changed

+239
-52
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
- Make `Scope.span` fully thread safe (#4519)
1515
- Finish TTFD when not calling reportFullyDisplayed before binding a new transaction to the scope (#4526).
1616

17+
### Improvements
18+
19+
- impr: Speed up getBinaryImages V2 (#4539). Follow up on (#4435)
20+
1721
## 8.40.1
1822

1923
### Fixes

Sentry.xcodeproj/project.pbxproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
620203B22C59025E0008317C /* SentryFileContents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 620203B12C59025E0008317C /* SentryFileContents.swift */; };
7777
620379DB2AFE1415005AC0C1 /* SentryBuildAppStartSpans.h in Headers */ = {isa = PBXBuildFile; fileRef = 620379DA2AFE1415005AC0C1 /* SentryBuildAppStartSpans.h */; };
7878
620379DD2AFE1432005AC0C1 /* SentryBuildAppStartSpans.m in Sources */ = {isa = PBXBuildFile; fileRef = 620379DC2AFE1432005AC0C1 /* SentryBuildAppStartSpans.m */; };
79+
6205B4A42CE73AA100744684 /* TestDebugImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85790282976A69F00C6AC1F /* TestDebugImageProvider.swift */; };
7980
621AE74B2C626C230012E730 /* SentryANRTrackerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = 621AE74A2C626C230012E730 /* SentryANRTrackerV2.h */; };
8081
621AE74D2C626C510012E730 /* SentryANRTrackerV2.m in Sources */ = {isa = PBXBuildFile; fileRef = 621AE74C2C626C510012E730 /* SentryANRTrackerV2.m */; };
8182
621C88482CAD23B9000EABCB /* SentryCaptureTransactionWithProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 621C88472CAD23B9000EABCB /* SentryCaptureTransactionWithProfile.h */; };
@@ -834,7 +835,6 @@
834835
D855AD62286ED6A4002573E1 /* SentryCrashTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D855AD61286ED6A4002573E1 /* SentryCrashTests.m */; };
835836
D855B3E827D652AF00BCED76 /* SentryCoreDataTrackingIntegrationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D855B3E727D652AF00BCED76 /* SentryCoreDataTrackingIntegrationTest.swift */; };
836837
D855B3EA27D652C700BCED76 /* TestCoreDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = D855B3E927D652C700BCED76 /* TestCoreDataStack.swift */; };
837-
D85790292976A69F00C6AC1F /* TestDebugImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85790282976A69F00C6AC1F /* TestDebugImageProvider.swift */; };
838838
D85852B627ECEEDA00C6D8AE /* SentryScreenshot.m in Sources */ = {isa = PBXBuildFile; fileRef = D85852B427ECEEDA00C6D8AE /* SentryScreenshot.m */; };
839839
D85852BA27EDDC5900C6D8AE /* SentryUIApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = D85852B827EDDC5900C6D8AE /* SentryUIApplication.m */; };
840840
D858FA662A29EAB3002A3503 /* SentryBinaryImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = D858FA642A29EAB3002A3503 /* SentryBinaryImageCache.h */; };
@@ -3069,7 +3069,6 @@
30693069
7B2A70DE27D60904008B0D15 /* SentryTestThreadWrapper.swift */,
30703070
7B18DE4928DA0C8B004845C6 /* SentryNSNotificationCenterWrapperTests.swift */,
30713071
84A8892028DBD8D600C51DFD /* SentryDeviceTests.mm */,
3072-
D85790282976A69F00C6AC1F /* TestDebugImageProvider.swift */,
30733072
8431EE5A29ADB8EA00D8DC56 /* SentryTimeTests.m */,
30743073
62C3168A2B1F865A000D7031 /* SentryTimeSwiftTests.swift */,
30753074
33042A1629DC2C4300C60085 /* SentryExtraContextProviderTests.swift */,
@@ -3487,6 +3486,7 @@
34873486
8E25C97425F8511A00DC215B /* TestRandom.swift */,
34883487
7BE3C7762445E50A00A38442 /* TestCurrentDateProvider.swift */,
34893488
7BDB03BE25136A7D00BAE198 /* TestSentryDispatchQueueWrapper.swift */,
3489+
D85790282976A69F00C6AC1F /* TestDebugImageProvider.swift */,
34903490
7BAF3DC7243DB90E008A5414 /* TestTransport.swift */,
34913491
7BA0C049280563AA003E0326 /* TestTransportAdapter.swift */,
34923492
7B944FAF2469B46000A10721 /* TestClient.swift */,
@@ -4859,7 +4859,6 @@
48594859
62F05D2B2C0DB1F100916E3F /* SentryLogTestHelper.m in Sources */,
48604860
7B68345128F7EB3D00FB7064 /* SentryMeasurementUnitTests.swift in Sources */,
48614861
7B14089A248791660035403D /* SentryCrashStackEntryMapperTests.swift in Sources */,
4862-
D85790292976A69F00C6AC1F /* TestDebugImageProvider.swift in Sources */,
48634862
7B869EBC249B91D8004F4FDB /* SentryDebugMetaEquality.swift in Sources */,
48644863
7B01CE3D271993AC00B5AF31 /* SentryTransportFactoryTests.swift in Sources */,
48654864
7B30B68026527C3C006B2752 /* SentryFramesTrackerTests.swift in Sources */,
@@ -5136,6 +5135,7 @@
51365135
84A5D75B29D5170700388BFA /* TimeInterval+Sentry.swift in Sources */,
51375136
62AB8C9E2BF3925700BFC2AC /* WeakReference.swift in Sources */,
51385137
84AC61D929F7643B009EEF61 /* TestDispatchFactory.swift in Sources */,
5138+
6205B4A42CE73AA100744684 /* TestDebugImageProvider.swift in Sources */,
51395139
8431F01929B2852D00D8DC56 /* Invocation.swift in Sources */,
51405140
84B7FA4629B2935F00AD93B1 /* ClearTestState.swift in Sources */,
51415141
84281C622A579D0700EE88F2 /* SentryProfilerMocksSwiftCompatible.mm in Sources */,

SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@
2727
#import "PrivateSentrySDKOnly.h"
2828
#import "SentryAppStartMeasurement.h"
2929
#import "SentryAppState.h"
30+
#import "SentryBinaryImageCache.h"
3031
#import "SentryClient+Private.h"
3132
#import "SentryClient+TestInit.h"
3233
#import "SentryCrash+Test.h"
3334
#import "SentryCrashCachedData.h"
3435
#import "SentryCrashInstallation+Private.h"
3536
#import "SentryCrashMonitor_MachException.h"
3637
#import "SentryCrashWrapper.h"
38+
#import "SentryDebugImageProvider+HybridSDKs.h"
3739
#import "SentryDependencyContainer.h"
3840
#import "SentryDispatchFactory.h"
3941
#import "SentryDispatchSourceWrapper.h"
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import _SentryPrivate
2+
import Foundation
3+
@testable import Sentry
4+
5+
public class TestDebugImageProvider: SentryDebugImageProvider {
6+
public var debugImages: [DebugMeta]?
7+
8+
@available(*, deprecated)
9+
public override func getDebugImages() -> [DebugMeta] {
10+
getDebugImagesCrashed(true)
11+
}
12+
13+
@available(*, deprecated)
14+
public override func getDebugImagesCrashed(_ isCrash: Bool) -> [DebugMeta] {
15+
debugImages ?? super.getDebugImagesCrashed(isCrash)
16+
}
17+
18+
public var getDebugImagesFromCacheForFramesInvocations = Invocations<Void>()
19+
public override func getDebugImagesFromCacheForFrames(frames: [Frame]) -> [DebugMeta] {
20+
getDebugImagesFromCacheForFramesInvocations.record(Void())
21+
22+
return debugImages ?? super.getDebugImagesFromCacheForFrames(frames: frames)
23+
}
24+
25+
public var getDebugImagesFromCacheForThreadsInvocations = Invocations<Void>()
26+
public override func getDebugImagesFromCacheForThreads(threads: [SentryThread]) -> [DebugMeta] {
27+
getDebugImagesFromCacheForThreadsInvocations.record(Void())
28+
return debugImages ?? super.getDebugImagesFromCacheForThreads(threads: threads)
29+
}
30+
31+
public var getDebugImagesFromCacheInvocations = Invocations<Void>()
32+
public override func getDebugImagesFromCache() -> [DebugMeta] {
33+
getDebugImagesFromCacheInvocations.record(Void())
34+
return debugImages ?? super.getDebugImagesFromCache()
35+
}
36+
}

Sources/Sentry/PrivateSentrySDKOnly.mm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,11 @@ + (nullable SentryEnvelope *)envelopeWithData:(NSData *)data
6060

6161
+ (NSArray<SentryDebugMeta *> *)getDebugImagesCrashed:(BOOL)isCrash
6262
{
63+
#pragma clang diagnostic push
64+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
6365
return [[SentryDependencyContainer sharedInstance].debugImageProvider
6466
getDebugImagesCrashed:isCrash];
67+
#pragma clang diagnostic pop
6568
}
6669

6770
+ (nullable SentryAppStartMeasurement *)appStartMeasurement

Sources/Sentry/Profiling/SentryProfilerSerialization.mm

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
# import "SentryClient+Private.h"
66
# import "SentryDateUtils.h"
7+
# import "SentryDebugImageProvider+HybridSDKs.h"
78
# import "SentryDependencyContainer.h"
89
# import "SentryDevice.h"
910
# import "SentryEnvelope.h"
@@ -312,7 +313,7 @@
312313
const auto chunkID = [[SentryId alloc] init];
313314
const auto payload = sentry_serializedContinuousProfileChunk(
314315
profileID, chunkID, profileState, metricProfilerState,
315-
[SentryDependencyContainer.sharedInstance.debugImageProvider getDebugImagesCrashed:NO],
316+
[SentryDependencyContainer.sharedInstance.debugImageProvider getDebugImagesFromCache],
316317
SentrySDK.currentHub
317318
# if SENTRY_HAS_UIKIT
318319
,
@@ -350,12 +351,14 @@
350351
SentryProfiler *profiler, NSDictionary<NSString *, id> *profilingData,
351352
SentryTransaction *transaction, NSDate *startTimestamp)
352353
{
354+
const auto images =
355+
[SentryDependencyContainer.sharedInstance.debugImageProvider getDebugImagesFromCache];
353356
const auto payload = sentry_serializedTraceProfileData(
354357
profilingData, transaction.startSystemTime, transaction.endSystemTime,
355358
sentry_profilerTruncationReasonName(profiler.truncationReason),
356359
[profiler.metricProfiler serializeTraceProfileMetricsBetween:transaction.startSystemTime
357360
and:transaction.endSystemTime],
358-
[SentryDependencyContainer.sharedInstance.debugImageProvider getDebugImagesCrashed:NO], hub
361+
images, hub
359362
# if SENTRY_HAS_UIKIT
360363
,
361364
profiler.screenFrameData
@@ -403,7 +406,7 @@
403406
endSystemTime, sentry_profilerTruncationReasonName(profiler.truncationReason),
404407
[profiler.metricProfiler serializeTraceProfileMetricsBetween:startSystemTime
405408
and:endSystemTime],
406-
[SentryDependencyContainer.sharedInstance.debugImageProvider getDebugImagesCrashed:NO], hub
409+
[SentryDependencyContainer.sharedInstance.debugImageProvider getDebugImagesFromCache], hub
407410
# if SENTRY_HAS_UIKIT
408411
,
409412
profiler.screenFrameData

Sources/Sentry/Public/SentryDebugImageProvider.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ NS_ASSUME_NONNULL_BEGIN
3131
* crash, each image's data section crash info is also included.
3232
*/
3333
- (NSArray<SentryDebugMeta *> *)getDebugImagesForThreads:(NSArray<SentryThread *> *)threads
34-
isCrash:(BOOL)isCrash;
34+
isCrash:(BOOL)isCrash
35+
DEPRECATED_MSG_ATTRIBUTE("This method is slow and will be removed in a future version. Use "
36+
"-[getDebugImagesFromCacheForThreads:] instead.");
37+
;
3538

3639
/**
3740
* Returns a list of debug images that are being referenced by the given frames.
@@ -52,7 +55,9 @@ NS_ASSUME_NONNULL_BEGIN
5255
* crash, each image's data section crash info is also included.
5356
*/
5457
- (NSArray<SentryDebugMeta *> *)getDebugImagesForFrames:(NSArray<SentryFrame *> *)frames
55-
isCrash:(BOOL)isCrash;
58+
isCrash:(BOOL)isCrash
59+
DEPRECATED_MSG_ATTRIBUTE("This method is slow and will be removed in a future version. Use "
60+
"-[getDebugImagesFromCacheForFrames:] instead.");
5661

5762
/**
5863
* Returns the current list of debug images. Be aware that the @c SentryDebugMeta is actually
@@ -71,8 +76,12 @@ NS_ASSUME_NONNULL_BEGIN
7176
* @param isCrash @c YES if we're collecting binary images for a crash report, @c NO if we're
7277
* gathering them for other backtrace information, like a performance transaction. If this is for a
7378
* crash, each image's data section crash info is also included.
79+
*
80+
* @warning This method is slow. Please consider using @c getDebugImagesFromCache.
7481
*/
75-
- (NSArray<SentryDebugMeta *> *)getDebugImagesCrashed:(BOOL)isCrash;
82+
- (NSArray<SentryDebugMeta *> *)getDebugImagesCrashed:(BOOL)isCrash
83+
DEPRECATED_MSG_ATTRIBUTE("This method is slow and will be removed in a future version. Use "
84+
"-[getDebugImagesFromCache:] instead.");
7685

7786
@end
7887

Sources/Sentry/SentryBinaryImageCache.m

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#import "SentryInAppLogic.h"
66
#import "SentryLog.h"
77

8+
NS_ASSUME_NONNULL_BEGIN
9+
810
static void binaryImageWasAdded(const SentryCrashBinaryImage *image);
911

1012
static void binaryImageWasRemoved(const SentryCrashBinaryImage *image);
@@ -155,6 +157,13 @@ - (NSInteger)indexOfImage:(uint64_t)address
155157
return imagePaths;
156158
}
157159

160+
- (NSArray<SentryBinaryImageInfo *> *)getAllBinaryImages
161+
{
162+
@synchronized(self) {
163+
return _cache.copy;
164+
}
165+
}
166+
158167
@end
159168

160169
static void
@@ -168,3 +177,5 @@ - (NSInteger)indexOfImage:(uint64_t)address
168177
{
169178
[SentryDependencyContainer.sharedInstance.binaryImageCache binaryImageRemoved:image];
170179
}
180+
181+
NS_ASSUME_NONNULL_END

Sources/Sentry/SentryDebugImageProvider.m

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#import "SentryThread.h"
1414
#import <Foundation/Foundation.h>
1515

16+
NS_ASSUME_NONNULL_BEGIN
17+
1618
@interface SentryDebugImageProvider ()
1719

1820
@property (nonatomic, strong) id<SentryCrashBinaryImageProvider> binaryImageProvider;
@@ -50,7 +52,10 @@ - (instancetype)initWithBinaryImageProvider:(id<SentryCrashBinaryImageProvider>)
5052
{
5153
NSMutableArray<SentryDebugMeta *> *result = [NSMutableArray array];
5254

55+
#pragma clang diagnostic push
56+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
5357
NSArray<SentryDebugMeta *> *binaryImages = [self getDebugImagesCrashed:isCrash];
58+
#pragma clang diagnostic pop
5459

5560
for (SentryDebugMeta *sourceImage in binaryImages) {
5661
if ([addresses containsObject:sourceImage.imageAddress]) {
@@ -134,19 +139,7 @@ - (void)extractDebugImageAddressFromFrames:(NSArray<SentryFrame *> *)frames
134139
continue;
135140
}
136141

137-
SentryDebugMeta *debugMeta = [[SentryDebugMeta alloc] init];
138-
debugMeta.debugID = info.UUID;
139-
debugMeta.type = SentryDebugImageType;
140-
141-
if (info.vmAddress > 0) {
142-
debugMeta.imageVmAddress = sentry_formatHexAddressUInt64(info.vmAddress);
143-
}
144-
145-
debugMeta.imageAddress = sentry_formatHexAddressUInt64(info.address);
146-
debugMeta.imageSize = @(info.size);
147-
debugMeta.codeFile = info.name;
148-
149-
[result addObject:debugMeta];
142+
[result addObject:[self fillDebugMetaFromBinaryImageInfo:info]];
150143
}
151144

152145
return result;
@@ -158,6 +151,17 @@ - (void)extractDebugImageAddressFromFrames:(NSArray<SentryFrame *> *)frames
158151
return [self getDebugImagesCrashed:YES];
159152
}
160153

154+
- (NSArray<SentryDebugMeta *> *)getDebugImagesFromCache
155+
{
156+
NSArray<SentryBinaryImageInfo *> *infos = [self.binaryImageCache getAllBinaryImages];
157+
NSMutableArray<SentryDebugMeta *> *result =
158+
[[NSMutableArray alloc] initWithCapacity:infos.count];
159+
for (SentryBinaryImageInfo *info in infos) {
160+
[result addObject:[self fillDebugMetaFromBinaryImageInfo:info]];
161+
}
162+
return result;
163+
}
164+
161165
- (NSArray<SentryDebugMeta *> *)getDebugImagesCrashed:(BOOL)isCrash
162166
{
163167
NSMutableArray<SentryDebugMeta *> *debugMetaArray = [NSMutableArray new];
@@ -193,4 +197,23 @@ - (SentryDebugMeta *)fillDebugMetaFrom:(SentryCrashBinaryImage)image
193197
return debugMeta;
194198
}
195199

200+
- (SentryDebugMeta *)fillDebugMetaFromBinaryImageInfo:(SentryBinaryImageInfo *)info
201+
{
202+
SentryDebugMeta *debugMeta = [[SentryDebugMeta alloc] init];
203+
debugMeta.debugID = info.UUID;
204+
debugMeta.type = SentryDebugImageType;
205+
206+
if (info.vmAddress > 0) {
207+
debugMeta.imageVmAddress = sentry_formatHexAddressUInt64(info.vmAddress);
208+
}
209+
210+
debugMeta.imageAddress = sentry_formatHexAddressUInt64(info.address);
211+
debugMeta.imageSize = @(info.size);
212+
debugMeta.codeFile = info.name;
213+
214+
return debugMeta;
215+
}
216+
196217
@end
218+
219+
NS_ASSUME_NONNULL_END

Sources/Sentry/SentryTracer.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ - (void)addAppStartMeasurements:(SentryTransaction *)transaction
863863

864864
// The backend calculates statistics on the number and size of debug images for app
865865
// start transactions. Therefore, we add all debug images here.
866-
transaction.debugMeta = [self.debugImageProvider getDebugImagesCrashed:NO];
866+
transaction.debugMeta = [self.debugImageProvider getDebugImagesFromCache];
867867
}
868868
}
869869
}

0 commit comments

Comments
 (0)