diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/libwebrtc/rtc_base/checks.cc | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/rtc_base/checks.cc')
-rw-r--r-- | third_party/libwebrtc/rtc_base/checks.cc | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/checks.cc b/third_party/libwebrtc/rtc_base/checks.cc new file mode 100644 index 0000000000..e732a2659d --- /dev/null +++ b/third_party/libwebrtc/rtc_base/checks.cc @@ -0,0 +1,240 @@ +/* + * Copyright 2006 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// Most of this was borrowed (with minor modifications) from V8's and Chromium's +// src/base/logging.cc. + +#include <cstdarg> +#include <cstdio> +#include <cstdlib> + +#include "absl/strings/string_view.h" + +#if defined(WEBRTC_ANDROID) +#define RTC_LOG_TAG_ANDROID "rtc" +#include <android/log.h> // NOLINT +#endif + +#if defined(WEBRTC_WIN) +#include <windows.h> +#endif + +#if defined(WEBRTC_WIN) +#define LAST_SYSTEM_ERROR (::GetLastError()) +#elif defined(__native_client__) && __native_client__ +#define LAST_SYSTEM_ERROR (0) +#elif defined(WEBRTC_POSIX) +#include <errno.h> +#define LAST_SYSTEM_ERROR (errno) +#endif // WEBRTC_WIN + +#include "rtc_base/checks.h" + +namespace { + +#if defined(__GNUC__) +__attribute__((__format__(__printf__, 2, 3))) +#endif +void AppendFormat(std::string* s, const char* fmt, ...) { + va_list args, copy; + va_start(args, fmt); + va_copy(copy, args); + const int predicted_length = std::vsnprintf(nullptr, 0, fmt, copy); + va_end(copy); + + if (predicted_length > 0) { + const size_t size = s->size(); + s->resize(size + predicted_length); + // Pass "+ 1" to vsnprintf to include space for the '\0'. + std::vsnprintf(&((*s)[size]), predicted_length + 1, fmt, args); + } + va_end(args); +} +} // namespace + +namespace rtc { +namespace webrtc_checks_impl { + +#if !defined(WEBRTC_CHROMIUM_BUILD) +RTC_NORETURN void WriteFatalLog(absl::string_view output) { +#if defined(WEBRTC_ANDROID) + std::string output_str(output); + __android_log_print(ANDROID_LOG_ERROR, RTC_LOG_TAG_ANDROID, "%s\n", + output_str.c_str()); +#endif + fflush(stdout); + fwrite(output.data(), output.size(), 1, stderr); + fflush(stderr); +#if defined(WEBRTC_WIN) + DebugBreak(); +#endif + abort(); +} + +RTC_NORETURN void WriteFatalLog(const char* file, + int line, + absl::string_view output) { + WriteFatalLog(output); +} + +#endif // !defined(WEBRTC_CHROMIUM_BUILD) + +#if RTC_CHECK_MSG_ENABLED +// Reads one argument from args, appends it to s and advances fmt. +// Returns true iff an argument was sucessfully parsed. +bool ParseArg(va_list* args, const CheckArgType** fmt, std::string* s) { + if (**fmt == CheckArgType::kEnd) + return false; + + switch (**fmt) { + case CheckArgType::kInt: + AppendFormat(s, "%d", va_arg(*args, int)); + break; + case CheckArgType::kLong: + AppendFormat(s, "%ld", va_arg(*args, long)); + break; + case CheckArgType::kLongLong: + AppendFormat(s, "%lld", va_arg(*args, long long)); + break; + case CheckArgType::kUInt: + AppendFormat(s, "%u", va_arg(*args, unsigned)); + break; + case CheckArgType::kULong: + AppendFormat(s, "%lu", va_arg(*args, unsigned long)); + break; + case CheckArgType::kULongLong: + AppendFormat(s, "%llu", va_arg(*args, unsigned long long)); + break; + case CheckArgType::kDouble: + AppendFormat(s, "%g", va_arg(*args, double)); + break; + case CheckArgType::kLongDouble: + AppendFormat(s, "%Lg", va_arg(*args, long double)); + break; + case CheckArgType::kCharP: + s->append(va_arg(*args, const char*)); + break; + case CheckArgType::kStdString: + s->append(*va_arg(*args, const std::string*)); + break; + case CheckArgType::kStringView: { + const absl::string_view sv = *va_arg(*args, const absl::string_view*); + s->append(sv.data(), sv.size()); + break; + } + case CheckArgType::kVoidP: + AppendFormat(s, "%p", va_arg(*args, const void*)); + break; + default: + s->append("[Invalid CheckArgType]"); + return false; + } + (*fmt)++; + return true; +} + +RTC_NORETURN void FatalLog(const char* file, + int line, + const char* message, + const CheckArgType* fmt, + ...) { + va_list args; + va_start(args, fmt); + + std::string s; + AppendFormat(&s, + "\n\n" + "#\n" + "# Fatal error in: %s, line %d\n" + "# last system error: %u\n" + "# Check failed: %s", + file, line, LAST_SYSTEM_ERROR, message); + + if (*fmt == CheckArgType::kCheckOp) { + // This log message was generated by RTC_CHECK_OP, so we have to complete + // the error message using the operands that have been passed as the first + // two arguments. + fmt++; + + std::string s1, s2; + if (ParseArg(&args, &fmt, &s1) && ParseArg(&args, &fmt, &s2)) + AppendFormat(&s, " (%s vs. %s)\n# ", s1.c_str(), s2.c_str()); + } else { + s.append("\n# "); + } + + // Append all the user-supplied arguments to the message. + while (ParseArg(&args, &fmt, &s)) + ; + + va_end(args); + + WriteFatalLog(file, line, s); +} +#else // RTC_CHECK_MSG_ENABLED +RTC_NORETURN void FatalLog(const char* file, int line) { + std::string s; + AppendFormat(&s, + "\n\n" + "#\n" + "# Fatal error in: %s, line %d\n" + "# last system error: %u\n" + "# Check failed.\n" + "# ", + file, line, LAST_SYSTEM_ERROR); + WriteFatalLog(file, line, s); +} +#endif // RTC_CHECK_MSG_ENABLED + +#if RTC_DCHECK_IS_ON + +RTC_NORETURN void UnreachableCodeReached(const char* file, int line) { + std::string s; + AppendFormat(&s, + "\n\n" + "#\n" + "# Unreachable code reached: %s, line %d\n" + "# last system error: %u\n" + "# ", + file, line, LAST_SYSTEM_ERROR); + WriteFatalLog(file, line, s); +} + +#else // !RTC_DCHECK_IS_ON + +RTC_NORETURN void UnreachableCodeReached() { + std::string s; + AppendFormat(&s, + "\n\n" + "#\n" + "# Unreachable code reached (file and line unknown)\n" + "# last system error: %u\n" + "# ", + LAST_SYSTEM_ERROR); + WriteFatalLog(s); +} + +#endif // !RTC_DCHECK_IS_ON + +} // namespace webrtc_checks_impl +} // namespace rtc + +// Function to call from the C version of the RTC_CHECK and RTC_DCHECK macros. +RTC_NORETURN void rtc_FatalMessage(const char* file, + int line, + const char* msg) { +#if RTC_CHECK_MSG_ENABLED + static constexpr rtc::webrtc_checks_impl::CheckArgType t[] = { + rtc::webrtc_checks_impl::CheckArgType::kEnd}; + rtc::webrtc_checks_impl::FatalLog(file, line, msg, t); +#else + rtc::webrtc_checks_impl::FatalLog(file, line); +#endif +} |