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

[PLAT-5923] Improved thread recording #992

Merged
merged 28 commits into from
Feb 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
abdcc1d
Improve backtrace performance for handled errors
nickdowell Feb 5, 2021
7101094
Remove redundant @class
nickdowell Feb 5, 2021
4687dca
Remove redundant initializer
nickdowell Feb 5, 2021
9ee44d4
Move function outside @implementation
nickdowell Feb 5, 2021
091b9f7
Fix -[BugsnagClient collectThreads:]
nickdowell Feb 5, 2021
21cf552
Fix compiler warning
nickdowell Feb 5, 2021
39869e2
Update comment
nickdowell Feb 5, 2021
08dcc87
Fix thread naming
nickdowell Feb 5, 2021
466348a
Stop skipping too many stack frames
nickdowell Feb 5, 2021
118191a
Make caller responsible for passing call stack
nickdowell Feb 8, 2021
65675ae
Avoid symbolicating the current thread twice
nickdowell Feb 8, 2021
4ca0356
Remove redundant import
nickdowell Feb 8, 2021
1f89973
Fix hang in iOS 9 unit tests
nickdowell Feb 8, 2021
ef8cac1
Fix flake in testMainThreadFromBackground
nickdowell Feb 8, 2021
a9e67d6
Bypass xcpretty to allow diagnosing unit test hang
nickdowell Feb 8, 2021
0ca98e2
Improve reliability of new unit tests
nickdowell Feb 8, 2021
1354406
Add #992 to changelog
nickdowell Feb 8, 2021
673ae9b
Revert "Bypass xcpretty to allow diagnosing unit test hang"
nickdowell Feb 8, 2021
9ce974a
Use dlsym instead of bsg_ksbt_symbolicate for better performance
nickdowell Feb 8, 2021
1dfb4eb
Add basic thread checks to barebones E2E tests
nickdowell Feb 9, 2021
446bb20
Fix E2E test failure
nickdowell Feb 9, 2021
ebc94b8
Add comment re: behavior under Rosetta 2
nickdowell Feb 16, 2021
d2e0377
Initialize machine context to 0
nickdowell Feb 16, 2021
92b5b55
Merge branch 'next' into nickdowell/threads
nickdowell Feb 16, 2021
367bd0b
Improve reliability / reporting of testMainThreadFromBackground
nickdowell Feb 16, 2021
f1cc7d8
[full ci]
nickdowell Feb 16, 2021
03fa97c
Address macOS E2E test failures
nickdowell Feb 16, 2021
b554530
[full ci]
nickdowell Feb 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions Bugsnag.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
008966F12486D43700DC48C2 /* BugsnagMetadataRedactionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A62486D43400DC48C2 /* BugsnagMetadataRedactionTest.m */; };
008966F22486D43700DC48C2 /* BugsnagMetadataRedactionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A62486D43400DC48C2 /* BugsnagMetadataRedactionTest.m */; };
008966F32486D43700DC48C2 /* BugsnagMetadataRedactionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A62486D43400DC48C2 /* BugsnagMetadataRedactionTest.m */; };
008966F42486D43700DC48C2 /* BugsnagThreadTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A72486D43400DC48C2 /* BugsnagThreadTest.m */; };
008966F52486D43700DC48C2 /* BugsnagThreadTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A72486D43400DC48C2 /* BugsnagThreadTest.m */; };
008966F62486D43700DC48C2 /* BugsnagThreadTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A72486D43400DC48C2 /* BugsnagThreadTest.m */; };
008966F42486D43700DC48C2 /* BugsnagThreadTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A72486D43400DC48C2 /* BugsnagThreadTests.m */; };
008966F52486D43700DC48C2 /* BugsnagThreadTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A72486D43400DC48C2 /* BugsnagThreadTests.m */; };
008966F62486D43700DC48C2 /* BugsnagThreadTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A72486D43400DC48C2 /* BugsnagThreadTests.m */; };
008966FD2486D43700DC48C2 /* BugsnagOnBreadcrumbTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966AB2486D43500DC48C2 /* BugsnagOnBreadcrumbTest.m */; };
008966FE2486D43700DC48C2 /* BugsnagOnBreadcrumbTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966AB2486D43500DC48C2 /* BugsnagOnBreadcrumbTest.m */; };
008966FF2486D43700DC48C2 /* BugsnagOnBreadcrumbTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966AB2486D43500DC48C2 /* BugsnagOnBreadcrumbTest.m */; };
Expand Down Expand Up @@ -630,6 +630,9 @@
00AD1F302486A17900A27979 /* BugsnagSessionTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1F012486A17900A27979 /* BugsnagSessionTracker.m */; };
00AD1F312486A17900A27979 /* BugsnagSessionTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1F012486A17900A27979 /* BugsnagSessionTracker.m */; };
00E636C224878D84006CBF1A /* BSG_RFC3339DateTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 008969142486DAD000DC48C2 /* BSG_RFC3339DateTool.m */; };
01210B8825CD665000D683BB /* BugsnagThread+Recording.m in Sources */ = {isa = PBXBuildFile; fileRef = 01210B8725CD665000D683BB /* BugsnagThread+Recording.m */; };
01210B8925CD665000D683BB /* BugsnagThread+Recording.m in Sources */ = {isa = PBXBuildFile; fileRef = 01210B8725CD665000D683BB /* BugsnagThread+Recording.m */; };
01210B8A25CD665000D683BB /* BugsnagThread+Recording.m in Sources */ = {isa = PBXBuildFile; fileRef = 01210B8725CD665000D683BB /* BugsnagThread+Recording.m */; };
012482A325627B51003F7243 /* UIKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 012482A225627B51003F7243 /* UIKitTests.m */; };
0126DF1B257A92860031A70C /* BugsnagSession+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 0126DF1A257A92860031A70C /* BugsnagSession+Private.h */; };
0126DF1C257A92860031A70C /* BugsnagSession+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 0126DF1A257A92860031A70C /* BugsnagSession+Private.h */; };
Expand Down Expand Up @@ -1051,7 +1054,7 @@
008966A42486D43400DC48C2 /* BugsnagDeviceTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagDeviceTest.m; sourceTree = "<group>"; };
008966A52486D43400DC48C2 /* BugsnagClientPayloadInfoTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagClientPayloadInfoTest.m; sourceTree = "<group>"; };
008966A62486D43400DC48C2 /* BugsnagMetadataRedactionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagMetadataRedactionTest.m; sourceTree = "<group>"; };
008966A72486D43400DC48C2 /* BugsnagThreadTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagThreadTest.m; sourceTree = "<group>"; };
008966A72486D43400DC48C2 /* BugsnagThreadTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagThreadTests.m; sourceTree = "<group>"; };
008966A82486D43400DC48C2 /* BugsnagTestConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugsnagTestConstants.h; sourceTree = "<group>"; };
008966AB2486D43500DC48C2 /* BugsnagOnBreadcrumbTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagOnBreadcrumbTest.m; sourceTree = "<group>"; };
008966AC2486D43500DC48C2 /* BugsnagEventPersistLoadTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagEventPersistLoadTest.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1268,6 +1271,8 @@
00E636C02487031D006CBF1A /* Bugsnag.podspec.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = Bugsnag.podspec.json; sourceTree = SOURCE_ROOT; };
00E636C12487031D006CBF1A /* docker-compose.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = "docker-compose.yml"; sourceTree = SOURCE_ROOT; };
00E636C324878FFC006CBF1A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
01210B7C25CD661800D683BB /* BugsnagThread+Recording.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagThread+Recording.h"; sourceTree = "<group>"; };
01210B8725CD665000D683BB /* BugsnagThread+Recording.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "BugsnagThread+Recording.m"; sourceTree = "<group>"; };
012482A225627B51003F7243 /* UIKitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIKitTests.m; sourceTree = "<group>"; };
0126DED7257A87F40031A70C /* BugsnagAppWithState+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagAppWithState+Private.h"; sourceTree = "<group>"; };
0126DEDF257A89490031A70C /* BugsnagBreadcrumb+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagBreadcrumb+Private.h"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1703,7 +1708,7 @@
008966D22486D43700DC48C2 /* BugsnagTestsDummyClass.h */,
008966D12486D43600DC48C2 /* BugsnagTestsDummyClass.m */,
008966AD2486D43500DC48C2 /* BugsnagThreadSerializationTest.m */,
008966A72486D43400DC48C2 /* BugsnagThreadTest.m */,
008966A72486D43400DC48C2 /* BugsnagThreadTests.m */,
008966C52486D43600DC48C2 /* BugsnagUserTest.m */,
E701FAA62490EF77008D842F /* ClientApiValidationTest.m */,
E701FAAE2490EFE8008D842F /* ConfigurationApiValidationTest.m */,
Expand Down Expand Up @@ -1842,6 +1847,8 @@
008968582486DA9500DC48C2 /* BugsnagStateEvent.m */,
008968612486DA9500DC48C2 /* BugsnagThread.m */,
0134524B256BD00A0088C548 /* BugsnagThread+Private.h */,
01210B7C25CD661800D683BB /* BugsnagThread+Recording.h */,
01210B8725CD665000D683BB /* BugsnagThread+Recording.m */,
0089685F2486DA9500DC48C2 /* BugsnagUser.m */,
0126DF34257A94740031A70C /* BugsnagUser+Private.h */,
);
Expand Down Expand Up @@ -2548,6 +2555,7 @@
CBAB4DD82510D2460092CBAA /* BugsnagKVStoreObjC.m in Sources */,
008968A72486DA9600DC48C2 /* BugsnagSession.m in Sources */,
0089683A2486DA6C00DC48C2 /* BugsnagMetadata.m in Sources */,
01210B8825CD665000D683BB /* BugsnagThread+Recording.m in Sources */,
008969F62486DAD100DC48C2 /* BSG_KSCrash.m in Sources */,
0089695D2486DAD000DC48C2 /* BSG_KSMach_x86_32.c in Sources */,
00896A1A2486DAD100DC48C2 /* BSG_KSCrashSentry_MachException.c in Sources */,
Expand Down Expand Up @@ -2602,7 +2610,7 @@
008967572486D43700DC48C2 /* BugsnagClientMirrorTest.m in Sources */,
0089677B2486D43700DC48C2 /* RFC3339DateTool_Tests.m in Sources */,
0089676F2486D43700DC48C2 /* NSError+SimpleConstructor_Tests.m in Sources */,
008966F42486D43700DC48C2 /* BugsnagThreadTest.m in Sources */,
008966F42486D43700DC48C2 /* BugsnagThreadTests.m in Sources */,
008967692486D43700DC48C2 /* BugsnagSessionTrackerTest.m in Sources */,
016875C6258D003200DFFF69 /* NSUserDefaultsStub.m in Sources */,
008967842486D43700DC48C2 /* KSDynamicLinker_Tests.m in Sources */,
Expand Down Expand Up @@ -2714,6 +2722,7 @@
CBAB4DD92510D2460092CBAA /* BugsnagKVStoreObjC.m in Sources */,
008968A82486DA9600DC48C2 /* BugsnagSession.m in Sources */,
0089683B2486DA6C00DC48C2 /* BugsnagMetadata.m in Sources */,
01210B8925CD665000D683BB /* BugsnagThread+Recording.m in Sources */,
008969F72486DAD100DC48C2 /* BSG_KSCrash.m in Sources */,
0089695E2486DAD000DC48C2 /* BSG_KSMach_x86_32.c in Sources */,
00896A1B2486DAD100DC48C2 /* BSG_KSCrashSentry_MachException.c in Sources */,
Expand Down Expand Up @@ -2791,7 +2800,7 @@
008967942486D43700DC48C2 /* KSSignalInfo_Tests.m in Sources */,
004E35402487B3BE007FBAE4 /* BugsnagSwiftConfigurationTests.swift in Sources */,
0089678E2486D43700DC48C2 /* KSCrashReportConverter_Tests.m in Sources */,
008966F52486D43700DC48C2 /* BugsnagThreadTest.m in Sources */,
008966F52486D43700DC48C2 /* BugsnagThreadTests.m in Sources */,
0089679D2486D43700DC48C2 /* KSFileUtils_Tests.m in Sources */,
008967A32486D43700DC48C2 /* KSCrashSentry_Signal_Tests.m in Sources */,
004E353B2487B3B3007FBAE4 /* BugsnagSwiftPublicAPITests.swift in Sources */,
Expand Down Expand Up @@ -2878,6 +2887,7 @@
CBAB4DDA2510D2460092CBAA /* BugsnagKVStoreObjC.m in Sources */,
008968A92486DA9600DC48C2 /* BugsnagSession.m in Sources */,
0089683C2486DA6C00DC48C2 /* BugsnagMetadata.m in Sources */,
01210B8A25CD665000D683BB /* BugsnagThread+Recording.m in Sources */,
008969F82486DAD100DC48C2 /* BSG_KSCrash.m in Sources */,
0089695F2486DAD000DC48C2 /* BSG_KSMach_x86_32.c in Sources */,
00896A1C2486DAD100DC48C2 /* BSG_KSCrashSentry_MachException.c in Sources */,
Expand Down Expand Up @@ -2950,7 +2960,7 @@
008967292486D43700DC48C2 /* BugsnagStackframeTest.m in Sources */,
008967952486D43700DC48C2 /* KSSignalInfo_Tests.m in Sources */,
0089678F2486D43700DC48C2 /* KSCrashReportConverter_Tests.m in Sources */,
008966F62486D43700DC48C2 /* BugsnagThreadTest.m in Sources */,
008966F62486D43700DC48C2 /* BugsnagThreadTests.m in Sources */,
0089679E2486D43700DC48C2 /* KSFileUtils_Tests.m in Sources */,
008967A42486D43700DC48C2 /* KSCrashSentry_Signal_Tests.m in Sources */,
E701FAB12490EFE8008D842F /* ConfigurationApiValidationTest.m in Sources */,
Expand Down
65 changes: 25 additions & 40 deletions Bugsnag/Client/BugsnagClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#import "BugsnagStateEvent.h"
#import "BugsnagSystemState.h"
#import "BugsnagThread+Private.h"
#import "BugsnagThread+Recording.h"
#import "BugsnagUser+Private.h"

#if BSG_PLATFORM_IOS || BSG_PLATFORM_TVOS
Expand All @@ -83,8 +84,6 @@
NSString *const BSAttributeDepth = @"depth";
NSString *const BSEventLowMemoryWarning = @"lowMemoryWarning";

static NSInteger const BSGNotifierStackFrameCount = 4;

static struct {
// Contains the state of the event (handled/unhandled)
char *handledState;
Expand Down Expand Up @@ -820,9 +819,6 @@ - (void)notify:(NSException *)exception
handledState:(BugsnagHandledState *_Nonnull)handledState
block:(BugsnagOnErrorBlock)block
{
BugsnagError *error = [BugsnagError new];
error.type = BSGErrorTypeCocoa;

/**
* Stack frames starting from this one are removed by setting the depth.
* This helps remove bugsnag frames from showing in NSErrors as their
Expand All @@ -834,15 +830,28 @@ - (void)notify:(NSException *)exception
* 1. +[Bugsnag notifyError:block:]
* 2. -[BugsnagClient notifyError:block:]
* 3. -[BugsnagClient notify:handledState:block:]
* 4. -[BSG_KSCrash captureThreads:depth:]
*/
int depth = (int)(BSGNotifierStackFrameCount);
int depth = 3;

NSArray<NSNumber *> *callStack = exception.callStackReturnAddresses;
if (!callStack.count) {
callStack = BSGArraySubarrayFromIndex(NSThread.callStackReturnAddresses, depth);
}
BOOL recordAllThreads = self.configuration.sendThreads == BSGThreadSendPolicyAlways;
NSArray *threads = [[BSG_KSCrash sharedInstance] captureThreads:exception
depth:depth
recordAllThreads:recordAllThreads];
NSArray *errors = @[[self generateError:exception threads:threads]];
NSArray *threads = [BugsnagThread allThreads:recordAllThreads callStackReturnAddresses:callStack];

NSArray<BugsnagStackframe *> *stacktrace = nil;
for (BugsnagThread *thread in threads) {
if (thread.errorReportingThread) {
stacktrace = thread.stacktrace;
break;
}
}

BugsnagError *error = [[BugsnagError alloc] initWithErrorClass:exception.name ?: NSStringFromClass([exception class])
errorMessage:exception.reason ?: @""
errorType:BSGErrorTypeCocoa
stacktrace:stacktrace];

BugsnagMetadata *metadata = [self.metadata deepCopy];

Expand All @@ -852,8 +861,8 @@ - (void)notify:(NSException *)exception
handledState:handledState
user:self.user
metadata:metadata
breadcrumbs:[NSArray arrayWithArray:self.breadcrumbs.breadcrumbs]
errors:errors
breadcrumbs:self.breadcrumbs.breadcrumbs
errors:@[error]
threads:threads
session:self.sessionTracker.runningSession];
event.apiKey = self.configuration.apiKey;
Expand Down Expand Up @@ -940,27 +949,6 @@ - (void)notifyInternal:(BugsnagEvent *_Nonnull)event
[self flushPendingReports];
}

- (BugsnagError *)generateError:(NSException *)exception
threads:(NSArray<BugsnagThread *> *)threads {
NSString *errorClass = exception.name ?: NSStringFromClass([exception class]);
NSString *errorMessage = exception.reason;

BugsnagThread *errorReportingThread;

for (BugsnagThread *thread in threads) {
if (thread.errorReportingThread) {
errorReportingThread = thread;
break;
}
}

BugsnagError *error = [[BugsnagError alloc] initWithErrorClass:errorClass
errorMessage:errorMessage ?: @""
errorType:BSGErrorTypeCocoa
stacktrace:errorReportingThread.stacktrace];
return error;
}

// MARK: - Breadcrumbs

- (void)addBreadcrumbWithBlock:(void (^)(BugsnagBreadcrumb *))block {
Expand Down Expand Up @@ -1157,15 +1145,12 @@ - (NSArray *)collectThreads:(BOOL)unhandled {
// discard the following
// 1. [BugsnagReactNative getPayloadInfo:resolve:reject:]
// 2. [BugsnagClient collectThreads:]
// 3. [BSG_KSCrash captureThreads:depth:unhandled:]
int depth = 3;
NSException *exc = [NSException exceptionWithName:@"Bugsnag" reason:@"" userInfo:nil];
int depth = 2;
NSArray<NSNumber *> *callStack = BSGArraySubarrayFromIndex(NSThread.callStackReturnAddresses, depth);
BSGThreadSendPolicy sendThreads = self.configuration.sendThreads;
BOOL recordAllThreads = sendThreads == BSGThreadSendPolicyAlways
|| (unhandled && sendThreads == BSGThreadSendPolicyUnhandledOnly);
NSArray<BugsnagThread *> *threads = [[BSG_KSCrash sharedInstance] captureThreads:exc
depth:depth
recordAllThreads:recordAllThreads];
NSArray<BugsnagThread *> *threads = [BugsnagThread allThreads:recordAllThreads callStackReturnAddresses:callStack];
return [BugsnagThread serializeThreads:threads];
}

Expand Down
4 changes: 4 additions & 0 deletions Bugsnag/Helpers/BugsnagCollections.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@

#import <Foundation/Foundation.h>

/// Returns a new array containing the elements starting at position `index`, or
/// an empty array if `index` is beyond the array's range range of elements.
NSArray * BSGArraySubarrayFromIndex(NSArray *array, NSUInteger index);

/**
* Merge values from source dictionary with destination
*
Expand Down
7 changes: 7 additions & 0 deletions Bugsnag/Helpers/BugsnagCollections.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@

#import "BSGJSONSerialization.h"

NSArray * BSGArraySubarrayFromIndex(NSArray *array, NSUInteger index) {
if (index >= array.count) {
return @[];
}
return [array subarrayWithRange:NSMakeRange(index, array.count - index)];
}

NSDictionary *BSGDictMerge(NSDictionary *source, NSDictionary *destination) {
if ([destination count] == 0) {
return source;
Expand Down
14 changes: 0 additions & 14 deletions Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,20 +109,6 @@
metadata:(NSDictionary *)metadata
config:(NSDictionary *)config;

/**
* Collects a trace of all the threads running in application, if the user has
* configured this behaviour, and serializes them into an array of BugsnagThread.
*
* @param exc the exception to record
* @param depth the number of frames to discard from the main thread's stacktrace
* @param recordAllThreads whether all threads should be recorded or just the
* main thread's stacktrace
* @return an array of BugsnagThread
*/
- (NSArray<BugsnagThread *> *)captureThreads:(NSException *)exc
depth:(int)depth
recordAllThreads:(BOOL)recordAllThreads;

/**
* Collects information about the application's foreground state (duration in foreground/background)
*/
Expand Down
Loading