diff options
author | thegeorg <[email protected]> | 2025-02-18 20:09:48 +0300 |
---|---|---|
committer | thegeorg <[email protected]> | 2025-02-18 21:09:39 +0300 |
commit | 7fed694a0b014cec505a8117fc4be52cbf9792aa (patch) | |
tree | 692c98667a66eb325a063ac1718d8b64e401c430 /contrib/restricted/abseil-cpp/absl/debugging | |
parent | add906303b66ed6c98751c33c4806d398662be2f (diff) |
Update contrib/restricted/abseil-cpp to 20250127.0
commit_hash:cb84f6cd1a663877e7f59ac994d08e04a1e76205
Diffstat (limited to 'contrib/restricted/abseil-cpp/absl/debugging')
10 files changed, 121 insertions, 28 deletions
diff --git a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc index 570d1e504d8..d31f5a1f4e2 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc @@ -21,6 +21,7 @@ #ifdef _WIN32 #include <windows.h> #else +#include <pthread.h> #include <sched.h> #include <unistd.h> #endif @@ -65,6 +66,23 @@ #endif #endif +// ABSL_HAVE_PTHREAD_CPU_NUMBER_NP +// +// Checks whether pthread_cpu_number_np is available. +#ifdef ABSL_HAVE_PTHREAD_CPU_NUMBER_NP +#error ABSL_HAVE_PTHREAD_CPU_NUMBER_NP cannot be directly set +#elif defined(__APPLE__) && defined(__has_include) && \ + ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 140200) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 70100) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 140200)) +#define ABSL_HAVE_PTHREAD_CPU_NUMBER_NP 1 +#endif + namespace absl { ABSL_NAMESPACE_BEGIN @@ -330,6 +348,20 @@ static void ImmediateAbortSignalHandler(int) { RaiseToDefaultHandler(SIGABRT); } using GetTidType = decltype(absl::base_internal::GetTID()); ABSL_CONST_INIT static std::atomic<GetTidType> failed_tid(0); +static int GetCpuNumber() { +#ifdef ABSL_HAVE_SCHED_GETCPU + return sched_getcpu(); +#elif defined(ABSL_HAVE_PTHREAD_CPU_NUMBER_NP) + size_t cpu_num; + if (pthread_cpu_number_np(&cpu_num) == 0) { + return static_cast<int>(cpu_num); + } + return -1; +#else + return -1; +#endif +} + #ifndef ABSL_HAVE_SIGACTION static void AbslFailureSignalHandler(int signo) { void* ucontext = nullptr; @@ -360,10 +392,7 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) { // Increase the chance that the CPU we report was the same CPU on which the // signal was received by doing this as early as possible, i.e. after // verifying that this is not a recursive signal handler invocation. - int my_cpu = -1; -#ifdef ABSL_HAVE_SCHED_GETCPU - my_cpu = sched_getcpu(); -#endif + int my_cpu = GetCpuNumber(); #ifdef ABSL_HAVE_ALARM // Set an alarm to abort the program in case this code hangs or deadlocks. diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h index 19c4952e2f7..1fac29c52b0 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h @@ -35,7 +35,7 @@ #if defined(__ELF__) && !defined(__OpenBSD__) && !defined(__QNX__) && \ !defined(__native_client__) && !defined(__asmjs__) && \ !defined(__wasm__) && !defined(__HAIKU__) && !defined(__sun) && \ - !defined(__VXWORKS__) && !defined(__hexagon__) + !defined(__VXWORKS__) && !defined(__hexagon__) && !defined(__XTENSA__) #define ABSL_HAVE_ELF_MEM_IMAGE 1 #endif diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h index f41b64c39df..f5ba5575d1b 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h @@ -24,7 +24,7 @@ // Use this feature test macro to detect its availability. #ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION #error ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION cannot be set directly -#elif !defined(__APPLE__) && !defined(_WIN32) && \ +#elif !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \ (defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || \ defined(__aarch64__) || defined(__riscv)) #define ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION 1 diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc index b123479b1ae..4490c4e13ca 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc @@ -178,6 +178,20 @@ static void **NextStackFrame(void **old_frame_pointer, const void *uc, return new_frame_pointer; } +// When PAC-RET (-mbranch-protection=pac-ret) is enabled, return addresses +// stored on the stack will be signed, which means that pointer bits outside of +// the VA range are potentially set. Since the stacktrace code is expected to +// return normal code pointers, this function clears those bits. +inline void* ClearPacBits(void* ptr) { + register void* x30 __asm__("x30") = ptr; + // The normal instruction for clearing PAC bits is XPACI, but for + // compatibility with ARM platforms that do not support pointer + // authentication, we use the hint space instruction XPACLRI instead. Hint + // space instructions behave as NOPs on unsupported platforms. + asm("xpaclri" : "+r"(x30)); + return x30; +} + template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> // We count on the bottom frame being this one. See the comment // at prev_return_address @@ -219,7 +233,7 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, if (skip_count > 0) { skip_count--; } else { - result[n] = prev_return_address; + result[n] = ClearPacBits(prev_return_address); if (IS_STACK_FRAMES) { sizes[n] = static_cast<int>( ComputeStackFrameSize(prev_frame_pointer, frame_pointer)); diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h index 3929b1b7349..88949fe9740 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h @@ -42,6 +42,13 @@ #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_emscripten-inl.inc" +#elif defined(__ANDROID__) && __ANDROID_API__ >= 33 + +// Use the generic implementation for Android 33+ (Android T+). This is the +// first version of Android for which <execinfo.h> implements backtrace(). +#define ABSL_STACKTRACE_INL_HEADER \ + "absl/debugging/internal/stacktrace_generic-inl.inc" + #elif defined(__linux__) && !defined(__ANDROID__) #if defined(NO_FRAME_POINTER) && \ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc index 20183fa3213..3f9e12407ab 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc @@ -36,15 +36,16 @@ #include "absl/base/attributes.h" #include "absl/debugging/stacktrace.h" -static const uintptr_t kUnknownFrameSize = 0; +static constexpr ptrdiff_t kUnknownFrameSize = 0; // Compute the size of a stack frame in [low..high). We assume that low < high. // Return size of kUnknownFrameSize. template <typename T> -static inline uintptr_t ComputeStackFrameSize(const T *low, const T *high) { +static inline ptrdiff_t ComputeStackFrameSize(const T *low, const T *high) { const char *low_char_ptr = reinterpret_cast<const char *>(low); const char *high_char_ptr = reinterpret_cast<const char *>(high); - return low < high ? high_char_ptr - low_char_ptr : kUnknownFrameSize; + return low < high ? static_cast<ptrdiff_t>(high_char_ptr - low_char_ptr) + : kUnknownFrameSize; } // Given a pointer to a stack frame, locate and return the calling stackframe, @@ -93,8 +94,8 @@ static void ** NextStackFrame(void **old_frame_pointer, const void *uc, // Check frame size. In strict mode, we assume frames to be under 100,000 // bytes. In non-strict mode, we relax the limit to 1MB. - const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000; - const uintptr_t frame_size = + const ptrdiff_t max_size = STRICT_UNWINDING ? 100000 : 1000000; + const ptrdiff_t frame_size = ComputeStackFrameSize(old_frame_pointer, new_frame_pointer); if (frame_size == kUnknownFrameSize) { if (STRICT_UNWINDING) @@ -151,7 +152,9 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, } else { result[n] = return_address; if (IS_STACK_FRAMES) { - sizes[n] = ComputeStackFrameSize(frame_pointer, next_frame_pointer); + // NextStackFrame() has already checked that frame size fits to int + sizes[n] = static_cast<int>(ComputeStackFrameSize(frame_pointer, + next_frame_pointer)); } n++; } diff --git a/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc b/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc index fdb8798b814..1370bcc4559 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc @@ -28,7 +28,7 @@ #include <sanitizer/lsan_interface.h> #if ABSL_HAVE_ATTRIBUTE_WEAK -extern "C" ABSL_ATTRIBUTE_WEAK int __lsan_is_turned_off(); +extern "C" ABSL_ATTRIBUTE_WEAK int __lsan_is_turned_off() { return 0; } #endif namespace absl { @@ -37,13 +37,13 @@ bool HaveLeakSanitizer() { return true; } #if ABSL_HAVE_ATTRIBUTE_WEAK bool LeakCheckerIsActive() { - return !(&__lsan_is_turned_off && __lsan_is_turned_off()); + return __lsan_is_turned_off() == 0; } #else bool LeakCheckerIsActive() { return true; } #endif -bool FindAndReportLeaks() { return __lsan_do_recoverable_leak_check(); } +bool FindAndReportLeaks() { return __lsan_do_recoverable_leak_check() != 0; } void DoIgnoreLeak(const void* ptr) { __lsan_ignore_object(ptr); } void RegisterLivePointers(const void* ptr, size_t size) { __lsan_register_root_region(ptr, size); diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc index 638d3954aec..344436f9d10 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +// SKIP_ABSL_INLINE_NAMESPACE_CHECK + #include "absl/debugging/symbolize.h" #ifdef _WIN32 #include <winapifamily.h> -#if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) || \ - WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) // UWP doesn't have access to win32 APIs. #define ABSL_INTERNAL_HAVE_SYMBOLIZE_WIN32 #endif diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc index ae75cd4153d..a98ca81d175 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc @@ -52,6 +52,7 @@ #include <elf.h> #include <fcntl.h> #include <link.h> // For ElfW() macro. +#include <sys/resource.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> @@ -376,6 +377,46 @@ class Symbolizer { SymbolCacheLine symbol_cache_[SYMBOL_CACHE_LINES]; }; +// Protect against client code closing low-valued file descriptors it doesn't +// actually own. +int OpenReadOnlyWithHighFD(const char *fname) { + static int high_fd = [] { + struct rlimit rlim{}; + const int rc = getrlimit(RLIMIT_NOFILE, &rlim); + if (rc == 0 && rlim.rlim_cur >= 2000) { + const int max_fd = static_cast<int>(rlim.rlim_cur); + + // This will return 2000 on reasonably-configured systems. + return std::min<int>(2000, max_fd - 1000); + } + ABSL_RAW_LOG(WARNING, "Unable to get high fd: rc=%d, limit=%ld", // + rc, static_cast<long>(rlim.rlim_cur)); + return -1; + }(); + constexpr int kOpenFlags = O_RDONLY | O_CLOEXEC; + if (high_fd >= 1000) { + const int fd = open(fname, kOpenFlags); + if (fd != -1 && fd < high_fd) { + // Try to relocate fd to high range. + static_assert(kOpenFlags & O_CLOEXEC, + "F_DUPFD_CLOEXEC assumes O_CLOEXEC"); + const int fd2 = fcntl(fd, F_DUPFD_CLOEXEC, high_fd); + if (fd2 != -1) { + // Successfully obtained high fd. Use it. + close(fd); + return fd2; + } else { + ABSL_RAW_LOG(WARNING, "Unable to dup fd=%d above %d, errno=%d", fd, + high_fd, errno); + } + } + // Either open failed and fd==-1, or fd is already above high_fd, or fcntl + // failed and fd is valid (but low). + return fd; + } + return open(fname, kOpenFlags); +} + static std::atomic<Symbolizer *> g_cached_symbolizer; } // namespace @@ -541,11 +582,9 @@ static ABSL_ATTRIBUTE_NOINLINE bool GetSectionHeaderByType( (buf_bytes > num_bytes_left) ? num_bytes_left : buf_bytes; const off_t offset = sh_offset + static_cast<off_t>(i * sizeof(buf[0])); const ssize_t len = file->ReadFromOffset(buf, num_bytes_to_read, offset); - if (len < 0) { - ABSL_RAW_LOG( - WARNING, - "Reading %zu bytes from offset %ju returned %zd which is negative.", - num_bytes_to_read, static_cast<intmax_t>(offset), len); + if (len <= 0) { + ABSL_RAW_LOG(WARNING, "Reading %zu bytes from offset %ju returned %zd.", + num_bytes_to_read, static_cast<intmax_t>(offset), len); return false; } if (static_cast<size_t>(len) % sizeof(buf[0]) != 0) { @@ -1066,7 +1105,7 @@ static ABSL_ATTRIBUTE_NOINLINE bool ReadAddrMap( snprintf(maps_path, sizeof(maps_path), "/proc/self/task/%d/maps", getpid()); int maps_fd; - NO_INTR(maps_fd = open(maps_path, O_RDONLY)); + NO_INTR(maps_fd = OpenReadOnlyWithHighFD(maps_path)); FileDescriptor wrapped_maps_fd(maps_fd); if (wrapped_maps_fd.get() < 0) { ABSL_RAW_LOG(WARNING, "%s: errno=%d", maps_path, errno); @@ -1340,7 +1379,7 @@ static void MaybeOpenFdFromSelfExe(ObjFile *obj) { if (memcmp(obj->start_addr, ELFMAG, SELFMAG) != 0) { return; } - int fd = open("/proc/self/exe", O_RDONLY); + int fd = OpenReadOnlyWithHighFD("/proc/self/exe"); if (fd == -1) { return; } @@ -1364,7 +1403,7 @@ static void MaybeOpenFdFromSelfExe(ObjFile *obj) { static bool MaybeInitializeObjFile(ObjFile *obj) { if (obj->fd < 0) { - obj->fd = open(obj->filename, O_RDONLY); + obj->fd = OpenReadOnlyWithHighFD(obj->filename); if (obj->fd < 0) { // Getting /proc/self/exe here means that we were hinted. @@ -1372,7 +1411,7 @@ static bool MaybeInitializeObjFile(ObjFile *obj) { // /proc/self/exe may be inaccessible (due to setuid, etc.), so try // accessing the binary via argv0. if (argv0_value != nullptr) { - obj->fd = open(argv0_value, O_RDONLY); + obj->fd = OpenReadOnlyWithHighFD(argv0_value); } } else { MaybeOpenFdFromSelfExe(obj); diff --git a/contrib/restricted/abseil-cpp/absl/debugging/ya.make b/contrib/restricted/abseil-cpp/absl/debugging/ya.make index 3c3aa2d8bc9..cff58f5fc82 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/ya.make +++ b/contrib/restricted/abseil-cpp/absl/debugging/ya.make @@ -6,7 +6,7 @@ LICENSE(Apache-2.0) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -VERSION(20240722.1) +VERSION(20250127.0) PEERDIR( contrib/restricted/abseil-cpp/absl/base |