diff --git a/AppCenter.podspec b/AppCenter.podspec index 8dc2478bae..61529ba62d 100644 --- a/AppCenter.podspec +++ b/AppCenter.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AppCenter' - s.version = '1.0.0' + s.version = '1.0.1' s.summary = 'Visual Studio App Center is your continuous integration, delivery and learning solution for iOS and macOS apps.' s.description = <<-DESC diff --git a/AppCenterCrashes/AppCenterCrashes/Internals/MSCrashesPrivate.h b/AppCenterCrashes/AppCenterCrashes/Internals/MSCrashesPrivate.h index 2466f2437c..51c60886b2 100644 --- a/AppCenterCrashes/AppCenterCrashes/Internals/MSCrashesPrivate.h +++ b/AppCenterCrashes/AppCenterCrashes/Internals/MSCrashesPrivate.h @@ -116,11 +116,6 @@ typedef struct MSCrashesCallbacks { */ @property(nonatomic) NSUncaughtExceptionHandler *exceptionHandler; -/** - * A flag that indicates that crashes are currently sent to the backend. - */ -@property(nonatomic) BOOL sendingInProgress; - /** * Temporary storage for crashes logs to handle user confirmation and callbacks. */ diff --git a/AppCenterCrashes/AppCenterCrashes/MSCrashes.mm b/AppCenterCrashes/AppCenterCrashes/MSCrashes.mm index 6f773acfa0..64bb34ffc7 100644 --- a/AppCenterCrashes/AppCenterCrashes/MSCrashes.mm +++ b/AppCenterCrashes/AppCenterCrashes/MSCrashes.mm @@ -84,7 +84,7 @@ static void plcr_post_crash_callback(siginfo_t *info, ucontext_t *uap, void *con } static PLCrashReporterCallbacks plCrashCallbacks = { - .version = 0, .context = NULL, .handleSignal = plcr_post_crash_callback}; + .version = 0, .context = NULL, .handleSignal = plcr_post_crash_callback}; /** * C++ Exception Handler @@ -113,6 +113,12 @@ @interface MSCrashes () */ @property BOOL didCrashInLastSession; +/** + * Indicates if the delayedProcessingSemaphore will need to be released + * anymore. Useful for preventing overflows. + */ +@property BOOL shouldReleaseProcessingSemaphore; + /** * Detail information about the last crash. */ @@ -153,7 +159,7 @@ + (void)generateTestCrash { } } else { MSLogWarning([MSCrashes logTag], @"GenerateTestCrash was just called in an App Store environment. The call will " - @"be ignored"); + @"be ignored"); } } } @@ -213,8 +219,9 @@ - (instancetype)init { _logBufferDir = [MSCrashesUtil logBufferDir]; _analyzerInProgressFile = [_crashesDir URLByAppendingPathComponent:kMSAnalyzerFilename]; _didCrashInLastSession = NO; - _delayedProcessingSemaphore = dispatch_semaphore_create(1); + _delayedProcessingSemaphore = dispatch_semaphore_create(0); _automaticProcessing = YES; + _shouldReleaseProcessingSemaphore = YES; #if !TARGET_OS_TV _enableMachExceptionHandler = YES; #endif @@ -246,7 +253,7 @@ - (instancetype)init { - (void)applyEnabledState:(BOOL)isEnabled { [super applyEnabledState:isEnabled]; - + // Enabling. if (isEnabled) { id crashSetupDelegate = [MSWrapperCrashesHelper getCrashHandlerSetupDelegate]; @@ -294,11 +301,14 @@ - (void)applyEnabledState:(BOOL)isEnabled { if (self.crashFiles.count > 0) { [self startDelayedCrashProcessing]; } + else { + dispatch_semaphore_signal(self.delayedProcessingSemaphore); + } // More details on log if a debugger is attached. if ([MSAppCenter isDebuggerAttached]) { MSLogInfo([MSCrashes logTag], @"Crashes service has been enabled but the service cannot detect crashes due to " - "running the application with a debugger attached."); + "running the application with a debugger attached."); } else { MSLogInfo([MSCrashes logTag], @"Crashes service has been enabled."); } @@ -433,12 +443,12 @@ - (void)onEnqueuingLog:(id)log withInternalId:(NSString *)internalId { // Overwrite the oldest buffered log. msCrashesLogBuffer[indexToDelete].buffer = - std::string(&reinterpret_cast(serializedLog.bytes)[0], - &reinterpret_cast(serializedLog.bytes)[serializedLog.length]); + std::string(&reinterpret_cast(serializedLog.bytes)[0], + &reinterpret_cast(serializedLog.bytes)[serializedLog.length]); msCrashesLogBuffer[indexToDelete].internalId = internalId.UTF8String; NSTimeInterval now = [[NSDate date] timeIntervalSince1970]; msCrashesLogBuffer[indexToDelete].timestamp = - [[NSString stringWithFormat:@"%f", now] cStringUsingEncoding:NSUTF8StringEncoding]; + [[NSString stringWithFormat:@"%f", now] cStringUsingEncoding:NSUTF8StringEncoding]; MSLogVerbose([MSCrashes logTag], @"Overwrote buffered log at index %ld.", indexToDelete); // We're done, no need to iterate any more. But no need to `return;` as we're at the end of the buffer. @@ -541,9 +551,9 @@ - (void)configureCrashReporterWithUncaughtExceptionHandlerEnabled:(BOOL)enableUn #endif PLCrashReporterSymbolicationStrategy symbolicationStrategy = PLCrashReporterSymbolicationStrategyNone; MSPLCrashReporterConfig *config = - [[MSPLCrashReporterConfig alloc] initWithSignalHandlerType:signalHandlerType - symbolicationStrategy:symbolicationStrategy - shouldRegisterUncaughtExceptionHandler:enableUncaughtExceptionHandler]; + [[MSPLCrashReporterConfig alloc] initWithSignalHandlerType:signalHandlerType + symbolicationStrategy:symbolicationStrategy + shouldRegisterUncaughtExceptionHandler:enableUncaughtExceptionHandler]; self.plCrashReporter = [[MSPLCrashReporter alloc] initWithConfiguration:config]; /* @@ -595,7 +605,6 @@ - (void)configureCrashReporterWithUncaughtExceptionHandlerEnabled:(BOOL)enableUn #pragma mark - Crash processing - (void)startDelayedCrashProcessing { - /* * FIXME: If application is crashed and relaunched from multitasking view, the SDK starts faster than normal launch * and application state is not updated from inactive to active at this time. Give more delay here for a workaround @@ -607,21 +616,30 @@ - (void)startDelayedCrashProcessing { */ // This must be performed asynchronously to prevent a deadlock with 'unprocessedCrashReports'. - dispatch_semaphore_wait(self.delayedProcessingSemaphore, DISPATCH_TIME_FOREVER); dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (1 * NSEC_PER_SEC)); dispatch_after(delay, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self startCrashProcessing]; - dispatch_semaphore_signal(self.delayedProcessingSemaphore); + + // Only release once to avoid releasing an unbounded number of times. + @synchronized(self) { + if (self.shouldReleaseProcessingSemaphore) { + dispatch_semaphore_signal(self.delayedProcessingSemaphore); + self.shouldReleaseProcessingSemaphore = NO; + } + } }); } - (void)startCrashProcessing { - // FIXME: There is no life cycle for app extensions yet so force start crash processing until then. - if ([MSUtility applicationState] != MSApplicationStateActive && - [MSUtility applicationState] != MSApplicationStateUnknown) { - return; - } + // Also force start crash processing when automatic processing is disabled. Though it sounds + // counterintuitive, this is important because there are scenarios in some wrappers (i.e. RN) where + // the application state is not ready by the time crash processing needs to happen. + if (self.automaticProcessing && + ([MSUtility applicationState] != MSApplicationStateActive && + [MSUtility applicationState] != MSApplicationStateUnknown)) { + return; + } MSLogDebug([MSCrashes logTag], @"Start delayed CrashManager processing"); // Was our own exception handler successfully added? @@ -637,13 +655,13 @@ - (void)startCrashProcessing { */ if (self.exceptionHandler != currentHandler) { MSLogWarning([MSCrashes logTag], @"Another exception handler was added. If " - @"this invokes any kind of exit() after processing the " - @"exception, which causes any subsequent error handler " - @"not to be invoked, these crashes will NOT be reported " - @"to App Center!"); + @"this invokes any kind of exit() after processing the " + @"exception, which causes any subsequent error handler " + @"not to be invoked, these crashes will NOT be reported " + @"to App Center!"); } } - if (!self.sendingInProgress && self.crashFiles.count > 0) { + if (self.crashFiles.count > 0) { [self processCrashReports]; } } @@ -869,7 +887,7 @@ - (void)handleLatestCrashReport { // Try loading the crash report NSData *crashData = - [[NSData alloc] initWithData:[self.plCrashReporter loadPendingCrashReportDataAndReturnError:&error]]; + [[NSData alloc] initWithData:[self.plCrashReporter loadPendingCrashReportDataAndReturnError:&error]]; if (crashData == nil) { MSLogError([MSCrashes logTag], @"Couldn't load crash report: %@", error.localizedDescription); } else { @@ -890,7 +908,6 @@ - (void)handleLatestCrashReport { // Purge the report marker at the end of the routine. [self removeAnalyzerFile]; } - [self.plCrashReporter purgePendingCrashReport]; } @@ -900,10 +917,10 @@ - (NSMutableArray *)persistedCrashReports { if ([self.crashesDir checkResourceIsReachableAndReturnError:nil]) { NSArray *files = - [self.fileManager contentsOfDirectoryAtURL:self.crashesDir - includingPropertiesForKeys:@[ NSURLNameKey, NSURLFileSizeKey, NSURLIsRegularFileKey ] - options:NSDirectoryEnumerationOptions(0) - error:&error]; + [self.fileManager contentsOfDirectoryAtURL:self.crashesDir + includingPropertiesForKeys:@[ NSURLNameKey, NSURLFileSizeKey, NSURLIsRegularFileKey ] + options:NSDirectoryEnumerationOptions(0) + error:&error]; if (!files) { MSLogError([MSCrashes logTag], @"Couldn't get files in the directory \"%@\": %@", self.crashesDir, error.localizedDescription); @@ -1196,3 +1213,4 @@ - (void)trackModelException:(MSException *)exception { } @end + diff --git a/AppCenterCrashes/AppCenterCrashesTests/MSCrashesTests.mm b/AppCenterCrashes/AppCenterCrashesTests/MSCrashesTests.mm index d82d9d6f8d..8a808a6abb 100644 --- a/AppCenterCrashes/AppCenterCrashesTests/MSCrashesTests.mm +++ b/AppCenterCrashes/AppCenterCrashesTests/MSCrashesTests.mm @@ -714,6 +714,7 @@ - (void)testSendOrAwaitWhenAlwaysSendIsFalseAndNotifyDontSend { MSCrashes *crashes = OCMPartialMock([MSCrashes new]); id logManagerMock = OCMProtocolMock(@protocol(MSLogManager)); [crashes setAutomaticProcessing:NO]; + [crashes applyEnabledState:YES]; OCMStub([crashes shouldAlwaysSend]).andReturn(NO); __block int numInvocations = 0; [self setProcessLogImplementation:(^(NSInvocation *) { @@ -787,6 +788,7 @@ - (void)testGetUnprocessedCrashReports { MSCrashes *crashes = OCMPartialMock([MSCrashes new]); id logManagerMock = OCMProtocolMock(@protocol(MSLogManager)); [crashes setAutomaticProcessing:NO]; + NSArray *reports = [self startCrashes:crashes withReports:YES withLogManager:logManagerMock]; // When @@ -833,7 +835,7 @@ - (void)testStartingCrashesWithoutAutomaticProcessing { #pragma mark Helper -/* +/** * Start Crashes (self.sut) with zero or one crash files on disk. */ - (NSMutableArray *)startCrashes:(MSCrashes *)crashes @@ -849,14 +851,26 @@ - (void)testStartingCrashesWithoutAutomaticProcessing { [reports addObject:[MSErrorLogFormatter errorReportFromCrashReport:report]]; } } - [crashes startWithLogManager:logManager appSecret:kMSTestAppSecret]; - if (startWithReports) { - assertThat(crashes.crashFiles, hasCountOf(1)); - } + + XCTestExpectation *expectation = [self expectationWithDescription:@"Start the Crashes module"]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [crashes startWithLogManager:logManager appSecret:kMSTestAppSecret]; + [expectation fulfill]; + }); + [self waitForExpectationsWithTimeout:1.0 + handler:^(NSError *error) { + if (startWithReports) { + assertThat(crashes.crashFiles, hasCountOf(1)); + } + if (error) { + XCTFail(@"Expectation Failed with error: %@", error); + } + }]; + return reports; } -/* +/** * Attaches the given block to the given logManager's "processLog" method when invoked with Crash's groupId. */ - (void)setProcessLogImplementation:(void (^)(NSInvocation *))invocation diff --git a/CHANGELOG.md b/CHANGELOG.md index a4d378b272..7b6df0b26f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,22 @@ # App Center SDK for iOS and macOS Change Log +## Version 1.0.1 + +This version contains a bugfix that is specifically for the App Center SDK for React Native. + +### AppCenterCrashes + +* **[Fix]** Fixes an issue that impacted the App Center SDK for React Native. + ## Version 1.0.0 ### General Availability (GA) Announcement. -This version contains **breaking changes** due to the renaming from Mobile Center to App Center. When you update to this release, existing telemetry and crash log information will not be migrated and will be discarded. This version introduces macOS support (preview). +This version contains **breaking changes** due to the renaming from Mobile Center to App Center. In the unlikely event there was data on the device not sent prior to the update, that data will be discarded. This version introduces macOS support (preview). ### AppCenter * **[Feature]** Now supports macOS (preview). -* **[Fix]** Don't send startService log while SDK is disabled. +* **[Fix]** Don't send startService log while SDK is disabled. ### AppCenterAnalytics diff --git a/Config/Version.xcconfig b/Config/Version.xcconfig index 35007feb95..cf13071e70 100644 --- a/Config/Version.xcconfig +++ b/Config/Version.xcconfig @@ -1,2 +1,2 @@ BUILD_NUMBER = 1 -VERSION_STRING = 1.0.0 +VERSION_STRING = 1.0.1 diff --git a/Documentation/iOS/AppCenter/.jazzy.yaml b/Documentation/iOS/AppCenter/.jazzy.yaml index 59ca500c75..62e8d5d9dd 100644 --- a/Documentation/iOS/AppCenter/.jazzy.yaml +++ b/Documentation/iOS/AppCenter/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: iphonesimulator theme: ../../Themes/apple module: AppCenter -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/Documentation/iOS/AppCenterAnalytics/.jazzy.yaml b/Documentation/iOS/AppCenterAnalytics/.jazzy.yaml index 5310a4d693..e88afb7084 100644 --- a/Documentation/iOS/AppCenterAnalytics/.jazzy.yaml +++ b/Documentation/iOS/AppCenterAnalytics/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: iphonesimulator theme: ../../Themes/apple module: AppCenterAnalytics -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/Documentation/iOS/AppCenterCrashes/.jazzy.yaml b/Documentation/iOS/AppCenterCrashes/.jazzy.yaml index c6d21b65aa..aa2334ab2f 100644 --- a/Documentation/iOS/AppCenterCrashes/.jazzy.yaml +++ b/Documentation/iOS/AppCenterCrashes/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: iphonesimulator theme: ../../Themes/apple module: AppCenterCrashes -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/Documentation/iOS/AppCenterDistribute/.jazzy.yaml b/Documentation/iOS/AppCenterDistribute/.jazzy.yaml index 1922a8eb6f..1628348eed 100644 --- a/Documentation/iOS/AppCenterDistribute/.jazzy.yaml +++ b/Documentation/iOS/AppCenterDistribute/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: iphonesimulator theme: ../../Themes/apple module: AppCenterDistribute -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/Documentation/iOS/AppCenterPush/.jazzy.yaml b/Documentation/iOS/AppCenterPush/.jazzy.yaml index e551a202d7..bfe4cfca80 100644 --- a/Documentation/iOS/AppCenterPush/.jazzy.yaml +++ b/Documentation/iOS/AppCenterPush/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: iphonesimulator theme: ../../Themes/apple module: AppCenterPush -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/Documentation/macOS/AppCenter/.jazzy.yaml b/Documentation/macOS/AppCenter/.jazzy.yaml index 550734bdad..89300efd32 100644 --- a/Documentation/macOS/AppCenter/.jazzy.yaml +++ b/Documentation/macOS/AppCenter/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: macosx theme: ../../Themes/apple module: AppCenter -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/Documentation/macOS/AppCenterAnalytics/.jazzy.yaml b/Documentation/macOS/AppCenterAnalytics/.jazzy.yaml index f16a597181..447f294aca 100644 --- a/Documentation/macOS/AppCenterAnalytics/.jazzy.yaml +++ b/Documentation/macOS/AppCenterAnalytics/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: macosx theme: ../../Themes/apple module: AppCenterAnalytics -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/Documentation/macOS/AppCenterCrashes/.jazzy.yaml b/Documentation/macOS/AppCenterCrashes/.jazzy.yaml index 11c68b5bd2..33dda23b8b 100644 --- a/Documentation/macOS/AppCenterCrashes/.jazzy.yaml +++ b/Documentation/macOS/AppCenterCrashes/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: macosx theme: ../../Themes/apple module: AppCenterCrashes -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/Documentation/macOS/AppCenterPush/.jazzy.yaml b/Documentation/macOS/AppCenterPush/.jazzy.yaml index e60d9ae2bd..01cae40913 100644 --- a/Documentation/macOS/AppCenterPush/.jazzy.yaml +++ b/Documentation/macOS/AppCenterPush/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: macosx theme: ../../Themes/apple module: AppCenterPush -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/Documentation/tvOS/AppCenter/.jazzy.yaml b/Documentation/tvOS/AppCenter/.jazzy.yaml index d6e62ac602..71ab5f7db3 100644 --- a/Documentation/tvOS/AppCenter/.jazzy.yaml +++ b/Documentation/tvOS/AppCenter/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: appletvsimulator theme: ../../Themes/apple module: AppCenter -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/Documentation/tvOS/AppCenterAnalytics/.jazzy.yaml b/Documentation/tvOS/AppCenterAnalytics/.jazzy.yaml index 361152704a..a1e0f3eb43 100644 --- a/Documentation/tvOS/AppCenterAnalytics/.jazzy.yaml +++ b/Documentation/tvOS/AppCenterAnalytics/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: appletvsimulator theme: ../../Themes/apple module: AppCenterAnalytics -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/Documentation/tvOS/AppCenterCrashes/.jazzy.yaml b/Documentation/tvOS/AppCenterCrashes/.jazzy.yaml index f2c8c05301..ac0e99c59f 100644 --- a/Documentation/tvOS/AppCenterCrashes/.jazzy.yaml +++ b/Documentation/tvOS/AppCenterCrashes/.jazzy.yaml @@ -5,7 +5,7 @@ sdk: appletvsimulator theme: ../../Themes/apple module: AppCenterCrashes -module_version: 1.0.0 +module_version: 1.0.1 author: Microsoft Corp author_url: http://www.microsoft.com diff --git a/README.md b/README.md index 5a01155162..112bc8663d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -[![Build Status](https://www.bitrise.io/app/e5b1a2ef546331fb.svg?token=Orwi_AVAExLTuN1ZAzvbFQ&branch=develop)](https://www.bitrise.io/app/e5b1a2ef546331fb) [![codecov](https://codecov.io/gh/Microsoft/AppCenter-SDK-Apple/branch/develop/graph/badge.svg?token=6dlCB5riVi)](https://codecov.io/gh/Microsoft/AppCenter-SDK-Apple) [![CocoaPods](https://img.shields.io/cocoapods/v/AppCenter.svg)](https://cocoapods.org/pods/AppCenter) [![CocoaPods](https://img.shields.io/cocoapods/dt/AppCenter.svg)](https://cocoapods.org/pods/AppCenter) diff --git a/bitrise/publish-podspec.sh b/bitrise/publish-podspec.sh index 48b97be232..ead44fb974 100755 --- a/bitrise/publish-podspec.sh +++ b/bitrise/publish-podspec.sh @@ -28,7 +28,7 @@ if [ "$1" == "internal" ] || [ "$1" == "test" ]; then sed "s/\(s\.version[[:space:]]*=[[:space:]]\)\'.*\'$/\1'$SDK_PUBLISH_VERSION'/1" AppCenter.podspec > AppCenter.podspec.tmp; mv AppCenter.podspec.tmp AppCenter.podspec # Change download URL in podspec - sed "s/https:\/\/github\.com\/microsoft\/app-center-sdk-ios\/releases\/download\/#{s.version}\(\/AppCenter-SDK-Apple-\)\(\#{s.version}\)\(.zip\)/https:\/\/mobilecentersdkdev\.blob\.core\.windows\.net\/sdk\1\2+$BITRISE_GIT_COMMIT\3/1" AppCenter.podspec > AppCenter.podspec.tmp; mv AppCenter.podspec.tmp AppCenter.podspec + sed "s/https:\/\/github\.com\/microsoft\/AppCenter-SDK-Apple\/releases\/download\/#{s.version}\(\/AppCenter-SDK-Apple-\)\(\#{s.version}\)\(.zip\)/https:\/\/mobilecentersdkdev\.blob\.core\.windows\.net\/sdk\1\2+$BITRISE_GIT_COMMIT\3/1" AppCenter.podspec > AppCenter.podspec.tmp; mv AppCenter.podspec.tmp AppCenter.podspec fi