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}
This commit is contained in:
Byoungchan Lee 2021-11-19 19:03:49 +09:00 committed by WebRTC LUCI CQ
parent 9c4e89d302
commit 524a422ecd
5 changed files with 21 additions and 30 deletions

View File

@ -225,14 +225,6 @@ config("common_inherited_config") {
}
}
# 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") {

View File

@ -316,10 +316,6 @@ rtc_library("logging") {
"../../webrtc_overrides/rtc_base/logging.h",
]
} else {
configs += [
"..:no_exit_time_destructors",
"..:no_global_constructors",
]
sources = [
"logging.cc",
"logging.h",

View File

@ -73,9 +73,10 @@ const char* FilenameFromPath(const char* file) {
}
// 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 @@ bool LogMessage::log_to_stderr_ = true;
// 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 @@ LogMessage::~LogMessage() {
#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::LogTimestamps(bool on) {
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 @@ void LogMessage::SetLogToStderr(bool log_to_stderr) {
}
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 @@ int LogMessage::GetLogToStream(LogSink* stream) {
}
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::AddLogToStream(LogSink* stream, LoggingSeverity min_sev) {
}
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::ConfigureLogging(const char* params) {
}
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_);

View File

@ -860,10 +860,7 @@ if (is_ios || is_mac) {
"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",

View File

@ -28,7 +28,9 @@ NSString * const kRTCFieldTrialMinimizeResamplingOnMobileKey =
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 @@ void RTCInitFieldTrialDictionary(NSDictionary<NSString *, NSString *> *fieldTria
[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);
}