Skip to content

Commit

Permalink
Roll abseil_revision 231c393a17..f3489c9ca6
Browse files Browse the repository at this point in the history
Change Log:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+log/231c393a17..f3489c9ca6
Full diff:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+/231c393a17..f3489c9ca6

Bug: None
Change-Id: I2a19ee77eb9ba6f6bee982d9e4dafa4a95ff71f8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3545065
Auto-Submit: Mirko Bonadei <mbonadei@chromium.org>
Reviewed-by: Danil Chapovalov <danilchap@chromium.org>
Commit-Queue: Danil Chapovalov <danilchap@chromium.org>
Cr-Commit-Position: refs/heads/main@{#984261}
  • Loading branch information
Mirko Bonadei authored and Chromium LUCI CQ committed Mar 23, 2022
1 parent 1bc0d96 commit ae9f8a5
Show file tree
Hide file tree
Showing 29 changed files with 582 additions and 199 deletions.
2 changes: 1 addition & 1 deletion third_party/abseil-cpp/README.chromium
Expand Up @@ -4,7 +4,7 @@ URL: https://github.com/abseil/abseil-cpp
License: Apache 2.0
License File: LICENSE
Version: 0
Revision: 231c393a170ce3c6d83e8456bc87fe917c333ecf
Revision: f3489c9ca64e0fad2a263e8560ee96718ac8b21b
Security Critical: yes

Description:
Expand Down
2 changes: 1 addition & 1 deletion third_party/abseil-cpp/absl/base/internal/direct_mmap.h
Expand Up @@ -20,7 +20,7 @@

#include "absl/base/config.h"

#if ABSL_HAVE_MMAP
#ifdef ABSL_HAVE_MMAP

#include <sys/mman.h>

Expand Down
Expand Up @@ -47,7 +47,7 @@
// The following platforms have an implementation of a hardware counter.
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \
defined(__powerpc__) || defined(__ppc__) || defined(__riscv) || \
defined(_M_IX86) || defined(_M_X64)
defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 1
#else
#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 0
Expand Down
3 changes: 2 additions & 1 deletion third_party/abseil-cpp/absl/container/internal/btree.h
Expand Up @@ -631,7 +631,8 @@ class btree_node {

// Compute how many values we can fit onto a leaf node taking into account
// padding.
constexpr static size_type NodeTargetSlots(const int begin, const int end) {
constexpr static size_type NodeTargetSlots(const size_type begin,
const size_type end) {
return begin == end ? begin
: SizeWithNSlots((begin + end) / 2 + 1) >
params_type::kTargetNodeSize
Expand Down
Expand Up @@ -23,6 +23,8 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {

// A single block of empty control bytes for tables without any slots allocated.
// This enables removing a branch in the hot path of find().
alignas(16) ABSL_CONST_INIT ABSL_DLL const ctrl_t kEmptyGroup[16] = {
ctrl_t::kSentinel, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty,
ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty,
Expand Down
434 changes: 325 additions & 109 deletions third_party/abseil-cpp/absl/container/internal/raw_hash_set.h

Large diffs are not rendered by default.

210 changes: 155 additions & 55 deletions third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc
Expand Up @@ -20,7 +20,13 @@
#include <unistd.h>
#endif

#ifdef __APPLE__
#include "absl/base/config.h"

#ifdef ABSL_HAVE_MMAP
#include <sys/mman.h>
#endif

#if defined(__linux__) || defined(__APPLE__)
#include <sys/ucontext.h>
#endif

Expand All @@ -38,7 +44,102 @@ ABSL_NAMESPACE_BEGIN
namespace debugging_internal {

namespace {
constexpr int kDefaultDumpStackFramesLimit = 64;
// The %p field width for printf() functions is two characters per byte,
// and two extra for the leading "0x".
constexpr int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*);

ABSL_CONST_INIT SymbolizeUrlEmitter debug_stack_trace_hook = nullptr;

// Async-signal safe mmap allocator.
void* Allocate(size_t num_bytes) {
#ifdef ABSL_HAVE_MMAP
void* p = ::mmap(nullptr, num_bytes, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
return p == MAP_FAILED ? nullptr : p;
#else
(void)num_bytes;
return nullptr;
#endif // ABSL_HAVE_MMAP
}

void Deallocate(void* p, size_t size) {
#ifdef ABSL_HAVE_MMAP
::munmap(p, size);
#else
(void)p;
(void)size;
#endif // ABSL_HAVE_MMAP
}

// Print a program counter only.
void DumpPC(OutputWriter* writer, void* writer_arg, void* const pc,
const char* const prefix) {
char buf[100];
snprintf(buf, sizeof(buf), "%s@ %*p\n", prefix, kPrintfPointerFieldWidth, pc);
writer(buf, writer_arg);
}

// Print a program counter and the corresponding stack frame size.
void DumpPCAndFrameSize(OutputWriter* writer, void* writer_arg, void* const pc,
int framesize, const char* const prefix) {
char buf[100];
if (framesize <= 0) {
snprintf(buf, sizeof(buf), "%s@ %*p (unknown)\n", prefix,
kPrintfPointerFieldWidth, pc);
} else {
snprintf(buf, sizeof(buf), "%s@ %*p %9d\n", prefix,
kPrintfPointerFieldWidth, pc, framesize);
}
writer(buf, writer_arg);
}

// Print a program counter and the corresponding symbol.
void DumpPCAndSymbol(OutputWriter* writer, void* writer_arg, void* const pc,
const char* const prefix) {
char tmp[1024];
const char* symbol = "(unknown)";
// Symbolizes the previous address of pc because pc may be in the
// next function. The overrun happens when the function ends with
// a call to a function annotated noreturn (e.g. CHECK).
// If symbolization of pc-1 fails, also try pc on the off-chance
// that we crashed on the first instruction of a function (that
// actually happens very often for e.g. __restore_rt).
const uintptr_t prev_pc = reinterpret_cast<uintptr_t>(pc) - 1;
if (absl::Symbolize(reinterpret_cast<const char*>(prev_pc), tmp,
sizeof(tmp)) ||
absl::Symbolize(pc, tmp, sizeof(tmp))) {
symbol = tmp;
}
char buf[1024];
snprintf(buf, sizeof(buf), "%s@ %*p %s\n", prefix, kPrintfPointerFieldWidth,
pc, symbol);
writer(buf, writer_arg);
}

// Print a program counter, its stack frame size, and its symbol name.
// Note that there is a separate symbolize_pc argument. Return addresses may be
// at the end of the function, and this allows the caller to back up from pc if
// appropriate.
void DumpPCAndFrameSizeAndSymbol(OutputWriter* writer, void* writer_arg,
void* const pc, void* const symbolize_pc,
int framesize, const char* const prefix) {
char tmp[1024];
const char* symbol = "(unknown)";
if (absl::Symbolize(symbolize_pc, tmp, sizeof(tmp))) {
symbol = tmp;
}
char buf[1024];
if (framesize <= 0) {
snprintf(buf, sizeof(buf), "%s@ %*p (unknown) %s\n", prefix,
kPrintfPointerFieldWidth, pc, symbol);
} else {
snprintf(buf, sizeof(buf), "%s@ %*p %9d %s\n", prefix,
kPrintfPointerFieldWidth, pc, framesize, symbol);
}
writer(buf, writer_arg);
}

} // namespace

void RegisterDebugStackTraceHook(SymbolizeUrlEmitter hook) {
Expand All @@ -50,7 +151,7 @@ SymbolizeUrlEmitter GetDebugStackTraceHook() { return debug_stack_trace_hook; }
// Returns the program counter from signal context, nullptr if
// unknown. vuc is a ucontext_t*. We use void* to avoid the use of
// ucontext_t on non-POSIX systems.
void* GetProgramCounter(void* vuc) {
void* GetProgramCounter(void* const vuc) {
#ifdef __linux__
if (vuc != nullptr) {
ucontext_t* context = reinterpret_cast<ucontext_t*>(vuc);
Expand Down Expand Up @@ -132,59 +233,17 @@ void* GetProgramCounter(void* vuc) {
return nullptr;
}

// The %p field width for printf() functions is two characters per byte,
// and two extra for the leading "0x".
static constexpr int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*);

// Print a program counter, its stack frame size, and its symbol name.
// Note that there is a separate symbolize_pc argument. Return addresses may be
// at the end of the function, and this allows the caller to back up from pc if
// appropriate.
static void DumpPCAndFrameSizeAndSymbol(void (*writerfn)(const char*, void*),
void* writerfn_arg, void* pc,
void* symbolize_pc, int framesize,
const char* const prefix) {
char tmp[1024];
const char* symbol = "(unknown)";
if (absl::Symbolize(symbolize_pc, tmp, sizeof(tmp))) {
symbol = tmp;
}
char buf[1024];
if (framesize <= 0) {
snprintf(buf, sizeof(buf), "%s@ %*p (unknown) %s\n", prefix,
kPrintfPointerFieldWidth, pc, symbol);
} else {
snprintf(buf, sizeof(buf), "%s@ %*p %9d %s\n", prefix,
kPrintfPointerFieldWidth, pc, framesize, symbol);
}
writerfn(buf, writerfn_arg);
}

// Print a program counter and the corresponding stack frame size.
static void DumpPCAndFrameSize(void (*writerfn)(const char*, void*),
void* writerfn_arg, void* pc, int framesize,
const char* const prefix) {
char buf[100];
if (framesize <= 0) {
snprintf(buf, sizeof(buf), "%s@ %*p (unknown)\n", prefix,
kPrintfPointerFieldWidth, pc);
} else {
snprintf(buf, sizeof(buf), "%s@ %*p %9d\n", prefix,
kPrintfPointerFieldWidth, pc, framesize);
}
writerfn(buf, writerfn_arg);
}

void DumpPCAndFrameSizesAndStackTrace(
void* pc, void* const stack[], int frame_sizes[], int depth,
int min_dropped_frames, bool symbolize_stacktrace,
void (*writerfn)(const char*, void*), void* writerfn_arg) {
void DumpPCAndFrameSizesAndStackTrace(void* const pc, void* const stack[],
int frame_sizes[], int depth,
int min_dropped_frames,
bool symbolize_stacktrace,
OutputWriter* writer, void* writer_arg) {
if (pc != nullptr) {
// We don't know the stack frame size for PC, use 0.
if (symbolize_stacktrace) {
DumpPCAndFrameSizeAndSymbol(writerfn, writerfn_arg, pc, pc, 0, "PC: ");
DumpPCAndFrameSizeAndSymbol(writer, writer_arg, pc, pc, 0, "PC: ");
} else {
DumpPCAndFrameSize(writerfn, writerfn_arg, pc, 0, "PC: ");
DumpPCAndFrameSize(writer, writer_arg, pc, 0, "PC: ");
}
}
for (int i = 0; i < depth; i++) {
Expand All @@ -194,22 +253,63 @@ void DumpPCAndFrameSizesAndStackTrace(
// call to a function annotated noreturn (e.g. CHECK). Note that we don't
// do this for pc above, as the adjustment is only correct for return
// addresses.
DumpPCAndFrameSizeAndSymbol(writerfn, writerfn_arg, stack[i],
DumpPCAndFrameSizeAndSymbol(writer, writer_arg, stack[i],
reinterpret_cast<char*>(stack[i]) - 1,
frame_sizes[i], " ");
} else {
DumpPCAndFrameSize(writerfn, writerfn_arg, stack[i], frame_sizes[i],
" ");
DumpPCAndFrameSize(writer, writer_arg, stack[i], frame_sizes[i], " ");
}
}
if (min_dropped_frames > 0) {
char buf[100];
snprintf(buf, sizeof(buf), " @ ... and at least %d more frames\n",
min_dropped_frames);
writerfn(buf, writerfn_arg);
writer(buf, writer_arg);
}
}

// Dump current stack trace as directed by writer.
// Make sure this function is not inlined to avoid skipping too many top frames.
ABSL_ATTRIBUTE_NOINLINE
void DumpStackTrace(int min_dropped_frames, int max_num_frames,
bool symbolize_stacktrace, OutputWriter* writer,
void* writer_arg) {
// Print stack trace
void* stack_buf[kDefaultDumpStackFramesLimit];
void** stack = stack_buf;
int num_stack = kDefaultDumpStackFramesLimit;
int allocated_bytes = 0;

if (num_stack >= max_num_frames) {
// User requested fewer frames than we already have space for.
num_stack = max_num_frames;
} else {
const size_t needed_bytes = max_num_frames * sizeof(stack[0]);
void* p = Allocate(needed_bytes);
if (p != nullptr) { // We got the space.
num_stack = max_num_frames;
stack = reinterpret_cast<void**>(p);
allocated_bytes = needed_bytes;
}
}

size_t depth = absl::GetStackTrace(stack, num_stack, min_dropped_frames + 1);
for (size_t i = 0; i < depth; i++) {
if (symbolize_stacktrace) {
DumpPCAndSymbol(writer, writer_arg, stack[i], " ");
} else {
DumpPC(writer, writer_arg, stack[i], " ");
}
}

auto hook = GetDebugStackTraceHook();
if (hook != nullptr) {
(*hook)(stack, depth, writer, writer_arg);
}

if (allocated_bytes != 0) Deallocate(stack, allocated_bytes);
}

} // namespace debugging_internal
ABSL_NAMESPACE_END
} // namespace absl
21 changes: 14 additions & 7 deletions third_party/abseil-cpp/absl/debugging/internal/examine_stack.h
Expand Up @@ -31,7 +31,7 @@ typedef void OutputWriter(const char*, void*);
// `hook` that is called each time DumpStackTrace() is called.
// `hook` may be called from a signal handler.
typedef void (*SymbolizeUrlEmitter)(void* const stack[], int depth,
OutputWriter writer, void* writer_arg);
OutputWriter* writer, void* writer_arg);

// Registration of SymbolizeUrlEmitter for use inside of a signal handler.
// This is inherently unsafe and must be signal safe code.
Expand All @@ -41,14 +41,21 @@ SymbolizeUrlEmitter GetDebugStackTraceHook();
// Returns the program counter from signal context, or nullptr if
// unknown. `vuc` is a ucontext_t*. We use void* to avoid the use of
// ucontext_t on non-POSIX systems.
void* GetProgramCounter(void* vuc);
void* GetProgramCounter(void* const vuc);

// Uses `writerfn` to dump the program counter, stack trace, and stack
// Uses `writer` to dump the program counter, stack trace, and stack
// frame sizes.
void DumpPCAndFrameSizesAndStackTrace(
void* pc, void* const stack[], int frame_sizes[], int depth,
int min_dropped_frames, bool symbolize_stacktrace,
void (*writerfn)(const char*, void*), void* writerfn_arg);
void DumpPCAndFrameSizesAndStackTrace(void* const pc, void* const stack[],
int frame_sizes[], int depth,
int min_dropped_frames,
bool symbolize_stacktrace,
OutputWriter* writer, void* writer_arg);

// Dump current stack trace omitting the topmost `min_dropped_frames` stack
// frames.
void DumpStackTrace(int min_dropped_frames, int max_num_frames,
bool symbolize_stacktrace, OutputWriter* writer,
void* writer_arg);

} // namespace debugging_internal
ABSL_NAMESPACE_END
Expand Down
13 changes: 10 additions & 3 deletions third_party/abseil-cpp/absl/debugging/symbolize_test.cc
Expand Up @@ -483,7 +483,8 @@ void ABSL_ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() {
}
}

#if defined(__arm__) && ABSL_HAVE_ATTRIBUTE(target)
#if defined(__arm__) && ABSL_HAVE_ATTRIBUTE(target) && \
((__ARM_ARCH >= 7) || !defined(__ARM_PCS_VFP))
// Test that we correctly identify bounds of Thumb functions on ARM.
//
// Thumb functions have the lowest-order bit set in their addresses in the ELF
Expand All @@ -502,6 +503,10 @@ void ABSL_ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() {
// bit in the Thumb function's entry point. It will correctly compute the end of
// the Thumb function, it will find no overlap between the Thumb and ARM
// functions, and it will return the name of the ARM function.
//
// Unfortunately we cannot perform this test on armv6 or lower systems that use
// the hard float ABI because gcc refuses to compile thumb functions on such
// systems with a "sorry, unimplemented: Thumb-1 hard-float VFP ABI" error.

__attribute__((target("thumb"))) int ArmThumbOverlapThumb(int x) {
return x * x * x;
Expand All @@ -521,7 +526,8 @@ void ABSL_ATTRIBUTE_NOINLINE TestArmThumbOverlap() {
#endif
}

#endif // defined(__arm__) && ABSL_HAVE_ATTRIBUTE(target)
#endif // defined(__arm__) && ABSL_HAVE_ATTRIBUTE(target) && ((__ARM_ARCH >= 7)
// || !defined(__ARM_PCS_VFP))

#elif defined(_WIN32)
#if !defined(ABSL_CONSUME_DLL)
Expand Down Expand Up @@ -596,7 +602,8 @@ int main(int argc, char **argv) {
TestWithPCInsideInlineFunction();
TestWithPCInsideNonInlineFunction();
TestWithReturnAddress();
#if defined(__arm__) && ABSL_HAVE_ATTRIBUTE(target)
#if defined(__arm__) && ABSL_HAVE_ATTRIBUTE(target) && \
((__ARM_ARCH >= 7) || !defined(__ARM_PCS_VFP))
TestArmThumbOverlap();
#endif
#endif
Expand Down

0 comments on commit ae9f8a5

Please sign in to comment.