Modify global variables to not call the destructor on exit.

In logging.cc, use the pointer of the static variable so that
it doesn't need a global constructor/exit time destructor.

In RTCFieldTrials.mm, store the field trial string as a char pointer
instead of a std::unique_ptr to ensure that it is never freed.

LSAN will be unhappy with this fix, but WebRTC itself hasn't been
tested with LSAN enabled, and any code changed in this CL does not
build with build_with_chromium=true, so it shouldn't be a problem.

Bug: webrtc:9693, webrtc:11665
Change-Id: Ia28e3534170e0817b815717f6efe862f7b51ef62
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/237320
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Byoungchan Lee <daniel.l@hpcnt.com>
Cr-Commit-Position: refs/heads/main@{#35391}
diff --git a/BUILD.gn b/BUILD.gn
index 5702792..168dcf9 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -227,14 +227,6 @@
 
 # TODO(bugs.webrtc.org/9693): Remove the possibility to suppress this warning
 # as soon as WebRTC compiles without it.
-config("no_exit_time_destructors") {
-  if (is_clang) {
-    cflags = [ "-Wno-exit-time-destructors" ]
-  }
-}
-
-# TODO(bugs.webrtc.org/9693): Remove the possibility to suppress this warning
-# as soon as WebRTC compiles without it.
 config("no_global_constructors") {
   if (is_clang) {
     cflags = [ "-Wno-global-constructors" ]
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 8fb8193..ec59c43 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -316,10 +316,6 @@
       "../../webrtc_overrides/rtc_base/logging.h",
     ]
   } else {
-    configs += [
-      "..:no_exit_time_destructors",
-      "..:no_global_constructors",
-    ]
     sources = [
       "logging.cc",
       "logging.h",
diff --git a/rtc_base/logging.cc b/rtc_base/logging.cc
index 5061eae..4ebeebe 100644
--- a/rtc_base/logging.cc
+++ b/rtc_base/logging.cc
@@ -73,9 +73,10 @@
 }
 
 // Global lock for log subsystem, only needed to serialize access to streams_.
-// TODO(bugs.webrtc.org/11665): this is not currently constant initialized and
-// trivially destructible.
-webrtc::Mutex g_log_mutex_;
+webrtc::Mutex& GetLoggingLock() {
+  static webrtc::Mutex& mutex = *new webrtc::Mutex();
+  return mutex;
+}
 
 }  // namespace
 
@@ -89,7 +90,7 @@
 // Note: we explicitly do not clean this up, because of the uncertain ordering
 // of destructors at program exit.  Let the person who sets the stream trigger
 // cleanup by setting to null, or let it leak (safe at program exit).
-ABSL_CONST_INIT LogSink* LogMessage::streams_ RTC_GUARDED_BY(g_log_mutex_) =
+ABSL_CONST_INIT LogSink* LogMessage::streams_ RTC_GUARDED_BY(GetLoggingLock()) =
     nullptr;
 ABSL_CONST_INIT std::atomic<bool> LogMessage::streams_empty_ = {true};
 
@@ -202,7 +203,7 @@
 #endif
   }
 
-  webrtc::MutexLock lock(&g_log_mutex_);
+  webrtc::MutexLock lock(&GetLoggingLock());
   for (LogSink* entry = streams_; entry != nullptr; entry = entry->next_) {
     if (severity_ >= entry->min_severity_) {
 #if defined(WEBRTC_ANDROID)
@@ -251,7 +252,7 @@
 
 void LogMessage::LogToDebug(LoggingSeverity min_sev) {
   g_dbg_sev = min_sev;
-  webrtc::MutexLock lock(&g_log_mutex_);
+  webrtc::MutexLock lock(&GetLoggingLock());
   UpdateMinLogSeverity();
 }
 
@@ -260,7 +261,7 @@
 }
 
 int LogMessage::GetLogToStream(LogSink* stream) {
-  webrtc::MutexLock lock(&g_log_mutex_);
+  webrtc::MutexLock lock(&GetLoggingLock());
   LoggingSeverity sev = LS_NONE;
   for (LogSink* entry = streams_; entry != nullptr; entry = entry->next_) {
     if (stream == nullptr || stream == entry) {
@@ -271,7 +272,7 @@
 }
 
 void LogMessage::AddLogToStream(LogSink* stream, LoggingSeverity min_sev) {
-  webrtc::MutexLock lock(&g_log_mutex_);
+  webrtc::MutexLock lock(&GetLoggingLock());
   stream->min_severity_ = min_sev;
   stream->next_ = streams_;
   streams_ = stream;
@@ -280,7 +281,7 @@
 }
 
 void LogMessage::RemoveLogToStream(LogSink* stream) {
-  webrtc::MutexLock lock(&g_log_mutex_);
+  webrtc::MutexLock lock(&GetLoggingLock());
   for (LogSink** entry = &streams_; *entry != nullptr;
        entry = &(*entry)->next_) {
     if (*entry == stream) {
@@ -342,7 +343,7 @@
 }
 
 void LogMessage::UpdateMinLogSeverity()
-    RTC_EXCLUSIVE_LOCKS_REQUIRED(g_log_mutex_) {
+    RTC_EXCLUSIVE_LOCKS_REQUIRED(GetLoggingLock()) {
   LoggingSeverity min_sev = g_dbg_sev;
   for (LogSink* entry = streams_; entry != nullptr; entry = entry->next_) {
     min_sev = std::min(min_sev, entry->min_severity_);
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index b59e9ca..19e612e 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -860,10 +860,7 @@
         "audio_codecs",  # TODO(bugs.webrtc.org/8396): Remove.
         "default_task_queue",
       ]
-      configs += [
-        "..:no_exit_time_destructors",
-        "..:no_global_constructors",
-      ]
+      configs += [ "..:no_global_constructors" ]
       sources = [
         "objc/api/peerconnection/RTCAudioSource+Private.h",
         "objc/api/peerconnection/RTCAudioSource.h",
diff --git a/sdk/objc/api/peerconnection/RTCFieldTrials.mm b/sdk/objc/api/peerconnection/RTCFieldTrials.mm
index c52dfe4..8823328 100644
--- a/sdk/objc/api/peerconnection/RTCFieldTrials.mm
+++ b/sdk/objc/api/peerconnection/RTCFieldTrials.mm
@@ -28,7 +28,9 @@
 NSString *const kRTCFieldTrialUseNWPathMonitor = @"WebRTC-Network-UseNWPathMonitor";
 NSString * const kRTCFieldTrialEnabledValue = @"Enabled";
 
-static std::unique_ptr<char[]> gFieldTrialInitString;
+// InitFieldTrialsFromString stores the char*, so the char array must outlive
+// the application.
+static char *gFieldTrialInitString = nullptr;
 
 void RTCInitFieldTrialDictionary(NSDictionary<NSString *, NSString *> *fieldTrials) {
   if (!fieldTrials) {
@@ -43,12 +45,15 @@
     [fieldTrialInitString appendString:fieldTrialEntry];
   }
   size_t len = fieldTrialInitString.length + 1;
-  gFieldTrialInitString.reset(new char[len]);
-  if (![fieldTrialInitString getCString:gFieldTrialInitString.get()
+  if (gFieldTrialInitString != nullptr) {
+    delete[] gFieldTrialInitString;
+  }
+  gFieldTrialInitString = new char[len];
+  if (![fieldTrialInitString getCString:gFieldTrialInitString
                               maxLength:len
                                encoding:NSUTF8StringEncoding]) {
     RTCLogError(@"Failed to convert field trial string.");
     return;
   }
-  webrtc::field_trial::InitFieldTrialsFromString(gFieldTrialInitString.get());
+  webrtc::field_trial::InitFieldTrialsFromString(gFieldTrialInitString);
 }