merge(3p/absl): subtree merge of Abseil up to e19260f

... notably, this includes Abseil's own StatusOr type, which
conflicted with our implementation (that was taken from TensorFlow).

Change-Id: Ie7d6764b64055caaeb8dc7b6b9d066291e6b538f
This commit is contained in:
Vincent Ambo 2020-11-21 14:43:54 +01:00
parent cc27324d02
commit 082c006c04
854 changed files with 11260 additions and 5296 deletions

View file

@ -68,6 +68,7 @@ static void Unpack(uint64_t x, int *pid, int *read_fd, int *write_fd) {
// unimplemented.
// This is a namespace-scoped variable for correct zero-initialization.
static std::atomic<uint64_t> pid_and_fds; // initially 0, an invalid pid.
bool AddressIsReadable(const void *addr) {
absl::base_internal::ErrnoSaver errno_saver;
// We test whether a byte is readable by using write(). Normally, this would
@ -86,7 +87,7 @@ bool AddressIsReadable(const void *addr) {
int pid;
int read_fd;
int write_fd;
uint64_t local_pid_and_fds = pid_and_fds.load(std::memory_order_relaxed);
uint64_t local_pid_and_fds = pid_and_fds.load(std::memory_order_acquire);
Unpack(local_pid_and_fds, &pid, &read_fd, &write_fd);
while (current_pid != pid) {
int p[2];
@ -98,13 +99,13 @@ bool AddressIsReadable(const void *addr) {
fcntl(p[1], F_SETFD, FD_CLOEXEC);
uint64_t new_pid_and_fds = Pack(current_pid, p[0], p[1]);
if (pid_and_fds.compare_exchange_strong(
local_pid_and_fds, new_pid_and_fds, std::memory_order_relaxed,
local_pid_and_fds, new_pid_and_fds, std::memory_order_release,
std::memory_order_relaxed)) {
local_pid_and_fds = new_pid_and_fds; // fds exposed to other threads
} else { // fds not exposed to other threads; we can close them.
close(p[0]);
close(p[1]);
local_pid_and_fds = pid_and_fds.load(std::memory_order_relaxed);
local_pid_and_fds = pid_and_fds.load(std::memory_order_acquire);
}
Unpack(local_pid_and_fds, &pid, &read_fd, &write_fd);
}
@ -124,7 +125,7 @@ bool AddressIsReadable(const void *addr) {
// If pid_and_fds contains the problematic file descriptors we just used,
// this call will forget them, and the loop will try again.
pid_and_fds.compare_exchange_strong(local_pid_and_fds, 0,
std::memory_order_relaxed,
std::memory_order_release,
std::memory_order_relaxed);
}
} while (errno == EBADF);

View file

@ -126,6 +126,7 @@ static const AbbrevPair kBuiltinTypeList[] = {
{"Dn", "std::nullptr_t", 0}, // i.e., decltype(nullptr)
{"Df", "decimal32", 0}, // IEEE 754r decimal floating point (32 bits)
{"Di", "char32_t", 0},
{"Du", "char8_t", 0},
{"Ds", "char16_t", 0},
{"Dh", "float16", 0}, // IEEE 754r half-precision float (16 bits)
{nullptr, nullptr, 0},
@ -409,6 +410,7 @@ static bool IsFunctionCloneSuffix(const char *str) {
static bool EndsWith(State *state, const char chr) {
return state->parse_state.out_cur_idx > 0 &&
state->parse_state.out_cur_idx < state->out_end_idx &&
chr == state->out[state->parse_state.out_cur_idx - 1];
}
@ -421,8 +423,10 @@ static void MaybeAppendWithLength(State *state, const char *const str,
if (str[0] == '<' && EndsWith(state, '<')) {
Append(state, " ", 1);
}
// Remember the last identifier name for ctors/dtors.
if (IsAlpha(str[0]) || str[0] == '_') {
// Remember the last identifier name for ctors/dtors,
// but only if we haven't yet overflown the buffer.
if (state->parse_state.out_cur_idx < state->out_end_idx &&
(IsAlpha(str[0]) || str[0] == '_')) {
state->parse_state.prev_name_idx = state->parse_state.out_cur_idx;
state->parse_state.prev_name_length = length;
}
@ -962,6 +966,7 @@ static bool ParseOperatorName(State *state, int *arity) {
// ::= TT <type>
// ::= TI <type>
// ::= TS <type>
// ::= TH <type> # thread-local
// ::= Tc <call-offset> <call-offset> <(base) encoding>
// ::= GV <(object) name>
// ::= T <call-offset> <(base) encoding>
@ -980,7 +985,7 @@ static bool ParseSpecialName(State *state) {
ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false;
ParseState copy = state->parse_state;
if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "VTIS") &&
if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "VTISH") &&
ParseType(state)) {
return true;
}
@ -1077,20 +1082,28 @@ static bool ParseVOffset(State *state) {
return false;
}
// <ctor-dtor-name> ::= C1 | C2 | C3
// <ctor-dtor-name> ::= C1 | C2 | C3 | CI1 <base-class-type> | CI2
// <base-class-type>
// ::= D0 | D1 | D2
// # GCC extensions: "unified" constructor/destructor. See
// # https://github.com/gcc-mirror/gcc/blob/7ad17b583c3643bd4557f29b8391ca7ef08391f5/gcc/cp/mangle.c#L1847
// #
// https://github.com/gcc-mirror/gcc/blob/7ad17b583c3643bd4557f29b8391ca7ef08391f5/gcc/cp/mangle.c#L1847
// ::= C4 | D4
static bool ParseCtorDtorName(State *state) {
ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false;
ParseState copy = state->parse_state;
if (ParseOneCharToken(state, 'C') && ParseCharClass(state, "1234")) {
const char *const prev_name = state->out + state->parse_state.prev_name_idx;
MaybeAppendWithLength(state, prev_name,
state->parse_state.prev_name_length);
return true;
if (ParseOneCharToken(state, 'C')) {
if (ParseCharClass(state, "1234")) {
const char *const prev_name =
state->out + state->parse_state.prev_name_idx;
MaybeAppendWithLength(state, prev_name,
state->parse_state.prev_name_length);
return true;
} else if (ParseOneCharToken(state, 'I') && ParseCharClass(state, "12") &&
ParseClassEnumType(state)) {
return true;
}
}
state->parse_state = copy;
@ -1139,6 +1152,7 @@ static bool ParseDecltype(State *state) {
// ::= <decltype>
// ::= <substitution>
// ::= Dp <type> # pack expansion of (C++0x)
// ::= Dv <num-elems> _ # GNU vector extension
//
static bool ParseType(State *state) {
ComplexityGuard guard(state);
@ -1205,6 +1219,12 @@ static bool ParseType(State *state) {
return true;
}
if (ParseTwoCharToken(state, "Dv") && ParseNumber(state, nullptr) &&
ParseOneCharToken(state, '_')) {
return true;
}
state->parse_state = copy;
return false;
}
@ -1253,13 +1273,42 @@ static bool ParseBuiltinType(State *state) {
return false;
}
// <function-type> ::= F [Y] <bare-function-type> E
// <exception-spec> ::= Do # non-throwing
// exception-specification (e.g.,
// noexcept, throw())
// ::= DO <expression> E # computed (instantiation-dependent)
// noexcept
// ::= Dw <type>+ E # dynamic exception specification
// with instantiation-dependent types
static bool ParseExceptionSpec(State *state) {
ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false;
if (ParseTwoCharToken(state, "Do")) return true;
ParseState copy = state->parse_state;
if (ParseTwoCharToken(state, "DO") && ParseExpression(state) &&
ParseOneCharToken(state, 'E')) {
return true;
}
state->parse_state = copy;
if (ParseTwoCharToken(state, "Dw") && OneOrMore(ParseType, state) &&
ParseOneCharToken(state, 'E')) {
return true;
}
state->parse_state = copy;
return false;
}
// <function-type> ::= [exception-spec] F [Y] <bare-function-type> [O] E
static bool ParseFunctionType(State *state) {
ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false;
ParseState copy = state->parse_state;
if (ParseOneCharToken(state, 'F') &&
if (Optional(ParseExceptionSpec(state)) && ParseOneCharToken(state, 'F') &&
Optional(ParseOneCharToken(state, 'Y')) && ParseBareFunctionType(state) &&
Optional(ParseOneCharToken(state, 'O')) &&
ParseOneCharToken(state, 'E')) {
return true;
}
@ -1887,7 +1936,8 @@ static bool Overflowed(const State *state) {
bool Demangle(const char *mangled, char *out, int out_size) {
State state;
InitState(&state, mangled, out, out_size);
return ParseTopLevelMangledName(&state) && !Overflowed(&state);
return ParseTopLevelMangledName(&state) && !Overflowed(&state) &&
state.parse_state.out_cur_idx > 0;
}
} // namespace debugging_internal

View file

@ -18,6 +18,7 @@
#include <string>
#include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/debugging/internal/stack_consumption.h"
#include "absl/memory/memory.h"
@ -82,9 +83,10 @@ TEST(Demangle, Clones) {
// Tests that verify that Demangle footprint is within some limit.
// They are not to be run under sanitizers as the sanitizers increase
// stack consumption by about 4x.
#if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) && \
!defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \
!defined(THREAD_SANITIZER)
#if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) && \
!defined(ABSL_HAVE_ADDRESS_SANITIZER) && \
!defined(ABSL_HAVE_MEMORY_SANITIZER) && \
!defined(ABSL_HAVE_THREAD_SANITIZER)
static const char *g_mangled;
static char g_demangle_buffer[4096];

View file

@ -42,7 +42,8 @@ namespace {
// one of them is null, the results of p<q, p>q, p<=q, and p>=q are
// unspecified. Therefore, instead we hardcode the direction of the
// stack on platforms we know about.
#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__)
#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || \
defined(__aarch64__)
constexpr bool kStackGrowsDown = true;
#else
#error Need to define kStackGrowsDown

View file

@ -24,8 +24,9 @@
// 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) && \
(defined(__i386__) || defined(__x86_64__) || defined(__ppc__))
#elif !defined(__APPLE__) && !defined(_WIN32) && \
(defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || \
defined(__aarch64__))
#define ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION 1
namespace absl {

View file

@ -37,8 +37,11 @@ static const unsigned char* GetKernelRtSigreturnAddress() {
absl::debugging_internal::VDSOSupport vdso;
if (vdso.IsPresent()) {
absl::debugging_internal::VDSOSupport::SymbolInfo symbol_info;
if (!vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_2.6.39", STT_FUNC,
&symbol_info) ||
auto lookup = [&](int type) {
return vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_2.6.39", type,
&symbol_info);
};
if ((!lookup(STT_FUNC) && !lookup(STT_NOTYPE)) ||
symbol_info.address == nullptr) {
// Unexpected: VDSO is present, yet the expected symbol is missing
// or null.

View file

@ -44,48 +44,46 @@
!(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_generic-inl.inc"
#else
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_unimplemented-inl.inc"
#endif
#elif defined(__linux__) && !defined(__ANDROID__)
#if !defined(NO_FRAME_POINTER)
# if defined(__i386__) || defined(__x86_64__)
#if defined(NO_FRAME_POINTER) && \
(defined(__i386__) || defined(__x86_64__) || defined(__aarch64__))
// Note: The libunwind-based implementation is not available to open-source
// users.
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_x86-inl.inc"
# elif defined(__ppc__) || defined(__PPC__)
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_powerpc-inl.inc"
# elif defined(__aarch64__)
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_aarch64-inl.inc"
#elif defined(__arm__) && defined(__GLIBC__)
"absl/debugging/internal/stacktrace_libunwind-inl.inc"
#define STACKTRACE_USES_LIBUNWIND 1
#elif defined(NO_FRAME_POINTER) && defined(__has_include)
#if __has_include(<execinfo.h>)
// Note: When using glibc this may require -funwind-tables to function properly.
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_generic-inl.inc"
# else
#endif
#elif defined(__i386__) || defined(__x86_64__)
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_unimplemented-inl.inc"
# endif
#else // defined(NO_FRAME_POINTER)
# if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
"absl/debugging/internal/stacktrace_x86-inl.inc"
#elif defined(__ppc__) || defined(__PPC__)
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_generic-inl.inc"
# elif defined(__ppc__) || defined(__PPC__)
"absl/debugging/internal/stacktrace_powerpc-inl.inc"
#elif defined(__aarch64__)
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_generic-inl.inc"
# else
"absl/debugging/internal/stacktrace_aarch64-inl.inc"
#elif defined(__has_include)
#if __has_include(<execinfo.h>)
// Note: When using glibc this may require -funwind-tables to function properly.
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_unimplemented-inl.inc"
# endif
#endif // NO_FRAME_POINTER
#else
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_unimplemented-inl.inc"
"absl/debugging/internal/stacktrace_generic-inl.inc"
#endif
#endif
#endif
// Fallback to the empty implementation.
#if !defined(ABSL_STACKTRACE_INL_HEADER)
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_unimplemented-inl.inc"
#endif
#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_

View file

@ -18,6 +18,8 @@
#ifndef ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_
#define ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_
#ifdef __cplusplus
#include <cstddef>
#include <cstdint>
@ -116,20 +118,30 @@ bool RemoveAllSymbolDecorators(void);
// filename != nullptr
//
// Returns true if the file was successfully registered.
bool RegisterFileMappingHint(
const void* start, const void* end, uint64_t offset, const char* filename);
bool RegisterFileMappingHint(const void* start, const void* end,
uint64_t offset, const char* filename);
// Looks up the file mapping registered by RegisterFileMappingHint for an
// address range. If there is one, the file name is stored in *filename and
// *start and *end are modified to reflect the registered mapping. Returns
// whether any hint was found.
bool GetFileMappingHint(const void** start,
const void** end,
uint64_t * offset,
bool GetFileMappingHint(const void** start, const void** end, uint64_t* offset,
const char** filename);
} // namespace debugging_internal
ABSL_NAMESPACE_END
} // namespace absl
#endif // __cplusplus
#include <stdbool.h>
#ifdef __cplusplus
extern "C"
#endif // __cplusplus
bool
AbslInternalGetFileMappingHint(const void** start, const void** end,
uint64_t* offset, const char** filename);
#endif // ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_

View file

@ -76,15 +76,6 @@ const void *VDSOSupport::Init() {
}
#endif // __GLIBC_PREREQ(2, 16)
if (vdso_base_.load(std::memory_order_relaxed) == kInvalidBase) {
// Valgrind zaps AT_SYSINFO_EHDR and friends from the auxv[]
// on stack, and so glibc works as if VDSO was not present.
// But going directly to kernel via /proc/self/auxv below bypasses
// Valgrind zapping. So we check for Valgrind separately.
if (RunningOnValgrind()) {
vdso_base_.store(nullptr, std::memory_order_relaxed);
getcpu_fn_.store(&GetCPUViaSyscall, std::memory_order_relaxed);
return nullptr;
}
int fd = open("/proc/self/auxv", O_RDONLY);
if (fd == -1) {
// Kernel too old to have a VDSO.
@ -175,18 +166,6 @@ int GetCPU() {
return ret_code == 0 ? cpu : ret_code;
}
// We need to make sure VDSOSupport::Init() is called before
// InitGoogle() does any setuid or chroot calls. If VDSOSupport
// is used in any global constructor, this will happen, since
// VDSOSupport's constructor calls Init. But if not, we need to
// ensure it here, with a global constructor of our own. This
// is an allowed exception to the normal rule against non-trivial
// global constructors.
static class VDSOInitHelper {
public:
VDSOInitHelper() { VDSOSupport::Init(); }
} vdso_init_helper;
} // namespace debugging_internal
ABSL_NAMESPACE_END
} // namespace absl