From 64f4925dd425db4192d979a795257aa6921c2dfd Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Wed, 7 Dec 2022 13:31:51 +0100 Subject: [PATCH] Operate app hang thread operations inside an autorelease pool --- Bugsnag/Helpers/BSGAppHangDetector.m | 78 ++++++++++++++-------------- CHANGELOG.md | 3 ++ 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/Bugsnag/Helpers/BSGAppHangDetector.m b/Bugsnag/Helpers/BSGAppHangDetector.m index 57448fbe3..e5ce6dda7 100644 --- a/Bugsnag/Helpers/BSGAppHangDetector.m +++ b/Bugsnag/Helpers/BSGAppHangDetector.m @@ -122,46 +122,48 @@ - (void)detectAppHangs { NSThread.currentThread.name = @"com.bugsnag.app-hang-detector"; while (!self.shouldStop) { - if (dispatch_semaphore_wait(self.processingStarted, DISPATCH_TIME_FOREVER) != 0) { - bsg_log_err(@"BSGAppHangDetector: dispatch_semaphore_wait failed unexpectedly"); - return; - } - - const dispatch_time_t deadline = self.processingDeadline; - - if (dispatch_semaphore_wait(self.processingFinished, deadline) == 0) { - // Run loop finished within the deadline - continue; - } - - BOOL shouldReportAppHang = YES; - - if (dispatch_time(DISPATCH_TIME_NOW, 0) > dispatch_time(deadline, 1 * NSEC_PER_SEC)) { - // If this thread has woken up long after the deadline, the app may have been suspended. - bsg_log_debug(@"Ignoring potential false positive app hang"); - shouldReportAppHang = NO; - } - + @autoreleasepool { + if (dispatch_semaphore_wait(self.processingStarted, DISPATCH_TIME_FOREVER) != 0) { + bsg_log_err(@"BSGAppHangDetector: dispatch_semaphore_wait failed unexpectedly"); + return; + } + + const dispatch_time_t deadline = self.processingDeadline; + + if (dispatch_semaphore_wait(self.processingFinished, deadline) == 0) { + // Run loop finished within the deadline + continue; + } + + BOOL shouldReportAppHang = YES; + + if (dispatch_time(DISPATCH_TIME_NOW, 0) > dispatch_time(deadline, 1 * NSEC_PER_SEC)) { + // If this thread has woken up long after the deadline, the app may have been suspended. + bsg_log_debug(@"Ignoring potential false positive app hang"); + shouldReportAppHang = NO; + } + #if defined(DEBUG) && DEBUG - if (shouldReportAppHang && bsg_ksmachisBeingTraced()) { - bsg_log_debug(@"Ignoring app hang because debugger is attached"); - shouldReportAppHang = NO; - } + if (shouldReportAppHang && bsg_ksmachisBeingTraced()) { + bsg_log_debug(@"Ignoring app hang because debugger is attached"); + shouldReportAppHang = NO; + } #endif - - if (shouldReportAppHang && !bsg_runContext->isForeground && !self.delegate.configuration.reportBackgroundAppHangs) { - bsg_log_debug(@"Ignoring app hang because app is in the background"); - shouldReportAppHang = NO; - } - - if (shouldReportAppHang) { - [self appHangDetected]; - } - - dispatch_semaphore_wait(self.processingFinished, DISPATCH_TIME_FOREVER); - - if (shouldReportAppHang) { - [self appHangEnded]; + + if (shouldReportAppHang && !bsg_runContext->isForeground && !self.delegate.configuration.reportBackgroundAppHangs) { + bsg_log_debug(@"Ignoring app hang because app is in the background"); + shouldReportAppHang = NO; + } + + if (shouldReportAppHang) { + [self appHangDetected]; + } + + dispatch_semaphore_wait(self.processingFinished, DISPATCH_TIME_FOREVER); + + if (shouldReportAppHang) { + [self appHangEnded]; + } } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 651757508..9ad5644cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ Changelog ### Bug fixes +* Fix memory leak in the app hang detection code. + [#1507](https://github.com/bugsnag/bugsnag-cocoa/pull/1507) + * Truncate additional data to reduce number of oversized payloads. [#1501](https://github.com/bugsnag/bugsnag-cocoa/pull/1501)