Skip to content

Commit

Permalink
Call stopControllerFactory atexit in the Darwin framework. (#24767)
Browse files Browse the repository at this point in the history
We have lots of things with static destructors that assert clean
shutdown in the destructor.  That means that calling exit() without a
clean shutdown is pretty much guaranteed to lead to a shutdown crash.

Just ensure that we are in fact shutting down the
MTRDeviceControllerFactory if exit() is called, to avoid those crashes.

Fixes project-chip/connectedhomeip#14859
  • Loading branch information
bzbarsky-apple authored and kkasperczyk-no committed Mar 15, 2023
1 parent 4d8b482 commit febc74e
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#include <lib/support/TestPersistentStorageDelegate.h>
#include <platform/PlatformManager.h>

#include <cstdlib>

using namespace chip;
using namespace chip::Controller;

Expand All @@ -58,6 +60,9 @@
static NSString * const kErrorCDCertStoreInit = @"Init failure while initializing Certificate Declaration Signing Keys store";
static NSString * const kErrorOtaProviderInit = @"Init failure while creating an OTA provider delegate";

static bool sExitHandlerRegistered = false;
static void ShutdownOnExit() { [[MTRDeviceControllerFactory sharedInstance] stopControllerFactory]; }

@interface MTRDeviceControllerFactory ()

@property (atomic, readonly) dispatch_queue_t chipWorkQueue;
Expand Down Expand Up @@ -382,7 +387,14 @@ - (BOOL)startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams
// This needs to happen after DeviceControllerFactory::Init,
// because that creates (lazily, by calling functions with
// static variables in them) some static-lifetime objects.
chip::HeapObjectPoolExitHandling::IgnoreLeaksOnExit();
if (!sExitHandlerRegistered) {
int ret = atexit(ShutdownOnExit);
if (ret != 0) {
MTR_LOG_ERROR("Error registering exit handler: %d", ret);
return;
}
}
HeapObjectPoolExitHandling::IgnoreLeaksOnExit();

// Make sure we don't leave a system state running while we have no
// controllers started. This is working around the fact that a system
Expand Down

0 comments on commit febc74e

Please sign in to comment.