diff options
Diffstat (limited to 'absl/debugging')
37 files changed, 314 insertions, 169 deletions
diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index 913cfafb..8f521bec 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -14,6 +14,7 @@ # limitations under the License. # +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") load( "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", @@ -30,6 +31,14 @@ licenses(["notice"]) # Apache 2.0 cc_library( name = "stacktrace", srcs = [ + "internal/stacktrace_aarch64-inl.inc", + "internal/stacktrace_arm-inl.inc", + "internal/stacktrace_config.h", + "internal/stacktrace_generic-inl.inc", + "internal/stacktrace_powerpc-inl.inc", + "internal/stacktrace_unimplemented-inl.inc", + "internal/stacktrace_win32-inl.inc", + "internal/stacktrace_x86-inl.inc", "stacktrace.cc", ], hdrs = ["stacktrace.h"], @@ -37,7 +46,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":debugging_internal", - "//absl/base", + "//absl/base:config", "//absl/base:core_headers", ], ) @@ -55,27 +64,39 @@ cc_library( "symbolize.h", ], copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, + linkopts = ABSL_DEFAULT_LINKOPTS + select({ + "//absl:windows": ["-DEFAULTLIB:dbghelp.lib"], + "//conditions:default": [], + }), deps = [ ":debugging_internal", ":demangle_internal", "//absl/base", + "//absl/base:config", "//absl/base:core_headers", "//absl/base:dynamic_annotations", "//absl/base:malloc_internal", + "//absl/base:raw_logging_internal", ], ) cc_test( name = "symbolize_test", srcs = ["symbolize_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, + copts = ABSL_TEST_COPTS + select({ + "//absl:windows": ["/Z7"], + "//conditions:default": [], + }), + linkopts = ABSL_DEFAULT_LINKOPTS + select({ + "//absl:windows": ["/DEBUG"], + "//conditions:default": [], + }), deps = [ ":stack_consumption", ":symbolize", "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/memory", "@com_google_googletest//:gtest", ], @@ -95,8 +116,9 @@ cc_library( deps = [ ":stacktrace", ":symbolize", - "//absl/base", + "//absl/base:config", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", ], ) @@ -112,6 +134,8 @@ cc_library( "//absl/base", "//absl/base:config", "//absl/base:core_headers", + "//absl/base:errno_saver", + "//absl/base:raw_logging_internal", ], ) @@ -127,7 +151,7 @@ cc_test( ":failure_signal_handler", ":stacktrace", ":symbolize", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/strings", "@com_google_googletest//:gtest", ], @@ -143,22 +167,16 @@ cc_library( hdrs = [ "internal/address_is_readable.h", "internal/elf_mem_image.h", - "internal/stacktrace_aarch64-inl.inc", - "internal/stacktrace_arm-inl.inc", - "internal/stacktrace_config.h", - "internal/stacktrace_generic-inl.inc", - "internal/stacktrace_powerpc-inl.inc", - "internal/stacktrace_unimplemented-inl.inc", - "internal/stacktrace_win32-inl.inc", - "internal/stacktrace_x86-inl.inc", "internal/vdso_support.h", ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ - "//absl/base", + "//absl/base:config", "//absl/base:core_headers", "//absl/base:dynamic_annotations", + "//absl/base:errno_saver", + "//absl/base:raw_logging_internal", ], ) @@ -169,6 +187,7 @@ cc_library( copts = ABSL_DEFAULT_COPTS, deps = [ "//absl/base", + "//absl/base:config", "//absl/base:core_headers", ], ) @@ -181,8 +200,8 @@ cc_test( deps = [ ":demangle_internal", ":stack_consumption", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/memory", "@com_google_googletest//:gtest_main", ], @@ -193,7 +212,10 @@ cc_library( srcs = ["leak_check.cc"], hdrs = ["leak_check.h"], linkopts = ABSL_DEFAULT_LINKOPTS, - deps = ["//absl/base:core_headers"], + deps = [ + "//absl/base:config", + "//absl/base:core_headers", + ], ) # Adding a dependency to leak_check_disable will disable @@ -204,6 +226,7 @@ cc_library( srcs = ["leak_check_disable.cc"], linkopts = ABSL_DEFAULT_LINKOPTS, linkstatic = 1, + deps = ["//absl/base:config"], alwayslink = 1, ) @@ -225,6 +248,9 @@ cc_library( }), linkopts = ABSL_DEFAULT_LINKOPTS, visibility = ["//visibility:private"], + deps = [ + "//absl/base:config", + ], ) cc_library( @@ -235,6 +261,9 @@ cc_library( copts = ["-ULEAK_SANITIZER"], linkopts = ABSL_DEFAULT_LINKOPTS, visibility = ["//visibility:private"], + deps = [ + "//absl/base:config", + ], ) cc_test( @@ -292,8 +321,9 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, visibility = ["//visibility:private"], deps = [ - "//absl/base", + "//absl/base:config", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", ], ) @@ -304,8 +334,8 @@ cc_test( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":stack_consumption", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "@com_google_googletest//:gtest_main", ], ) diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index 001e2727..77336159 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt @@ -19,13 +19,21 @@ absl_cc_library( stacktrace HDRS "stacktrace.h" + "internal/stacktrace_aarch64-inl.inc" + "internal/stacktrace_arm-inl.inc" + "internal/stacktrace_config.h" + "internal/stacktrace_generic-inl.inc" + "internal/stacktrace_powerpc-inl.inc" + "internal/stacktrace_unimplemented-inl.inc" + "internal/stacktrace_win32-inl.inc" + "internal/stacktrace_x86-inl.inc" SRCS "stacktrace.cc" COPTS ${ABSL_DEFAULT_COPTS} DEPS absl::debugging_internal - absl::base + absl::config absl::core_headers PUBLIC ) @@ -45,13 +53,16 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} + $<$<BOOL:${MINGW}>:"dbghelp"> DEPS absl::debugging_internal absl::demangle_internal absl::base + absl::config absl::core_headers absl::dynamic_annotations absl::malloc_internal + absl::raw_logging_internal PUBLIC ) @@ -62,12 +73,16 @@ absl_cc_test( "symbolize_test.cc" COPTS ${ABSL_TEST_COPTS} + $<$<BOOL:${MSVC}>:-Z7> + LINKOPTS + $<$<BOOL:${MSVC}>:-DEBUG> DEPS absl::stack_consumption absl::symbolize absl::base absl::core_headers absl::memory + absl::raw_logging_internal gmock ) @@ -83,8 +98,9 @@ absl_cc_library( DEPS absl::stacktrace absl::symbolize - absl::base + absl::config absl::core_headers + absl::raw_logging_internal ) absl_cc_library( @@ -102,6 +118,8 @@ absl_cc_library( absl::base absl::config absl::core_headers + absl::errno_saver + absl::raw_logging_internal PUBLIC ) @@ -116,8 +134,8 @@ absl_cc_test( absl::failure_signal_handler absl::stacktrace absl::symbolize - absl::base absl::strings + absl::raw_logging_internal Threads::Threads gmock ) @@ -128,14 +146,6 @@ absl_cc_library( HDRS "internal/address_is_readable.h" "internal/elf_mem_image.h" - "internal/stacktrace_aarch64-inl.inc" - "internal/stacktrace_arm-inl.inc" - "internal/stacktrace_config.h" - "internal/stacktrace_generic-inl.inc" - "internal/stacktrace_powerpc-inl.inc" - "internal/stacktrace_unimplemented-inl.inc" - "internal/stacktrace_win32-inl.inc" - "internal/stacktrace_x86-inl.inc" "internal/vdso_support.h" SRCS "internal/address_is_readable.cc" @@ -144,9 +154,11 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS - absl::base absl::core_headers + absl::config absl::dynamic_annotations + absl::errno_saver + absl::raw_logging_internal ) absl_cc_library( @@ -174,9 +186,9 @@ absl_cc_test( DEPS absl::demangle_internal absl::stack_consumption - absl::base absl::core_headers absl::memory + absl::raw_logging_internal gmock_main ) @@ -190,6 +202,7 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS + absl::config absl::core_headers PUBLIC ) @@ -236,7 +249,7 @@ absl_cc_test( SRCS "leak_check_test.cc" COPTS - ${ABSL_DEFAULT_COPTS} + ${ABSL_TEST_COPTS} "$<$<BOOL:${ABSL_HAVE_LSAN}>:-DABSL_EXPECT_LEAK_SANITIZER>" LINKOPTS "${ABSL_LSAN_LINKOPTS}" @@ -273,6 +286,7 @@ absl_cc_test( absl::leak_check_api_enabled_for_testing absl::leak_check_disable absl::base + absl::raw_logging_internal gmock_main ) @@ -286,8 +300,9 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS - absl::base + absl::config absl::core_headers + absl::raw_logging_internal TESTONLY ) @@ -300,8 +315,8 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::stack_consumption - absl::base absl::core_headers + absl::raw_logging_internal gmock_main ) diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc index af651c72..1f69bfa8 100644 --- a/absl/debugging/failure_signal_handler.cc +++ b/absl/debugging/failure_signal_handler.cc @@ -24,6 +24,10 @@ #include <unistd.h> #endif +#ifdef __APPLE__ +#include <TargetConditionals.h> +#endif + #ifdef ABSL_HAVE_MMAP #include <sys/mman.h> #endif @@ -37,6 +41,7 @@ #include <ctime> #include "absl/base/attributes.h" +#include "absl/base/internal/errno_saver.h" #include "absl/base/internal/raw_logging.h" #include "absl/base/internal/sysinfo.h" #include "absl/debugging/internal/examine_stack.h" @@ -44,10 +49,15 @@ #ifndef _WIN32 #define ABSL_HAVE_SIGACTION +// Apple WatchOS and TVOS don't allow sigaltstack +#if !(defined(TARGET_OS_WATCH) && TARGET_OS_WATCH) && \ + !(defined(TARGET_OS_TV) && TARGET_OS_TV) +#define ABSL_HAVE_SIGALTSTACK +#endif #endif namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN ABSL_CONST_INIT static FailureSignalHandlerOptions fsh_options; @@ -117,7 +127,7 @@ const char* FailureSignalToString(int signo) { } // namespace debugging_internal -#ifndef _WIN32 +#ifdef ABSL_HAVE_SIGALTSTACK static bool SetupAlternateStackOnce() { #if defined(__wasm__) || defined (__asjms__) @@ -169,7 +179,7 @@ static bool SetupAlternateStackOnce() { // Returns the appropriate flag for sig_action.sa_flags // if the system supports using an alternate stack. static int MaybeSetupAlternateStack() { -#ifndef _WIN32 +#ifdef ABSL_HAVE_SIGALTSTACK ABSL_ATTRIBUTE_UNUSED static const bool kOnce = SetupAlternateStackOnce(); return SA_ONSTACK; #else @@ -205,9 +215,8 @@ static void InstallOneFailureHandler(FailureSignalData* data, #endif static void WriteToStderr(const char* data) { - int old_errno = errno; + absl::base_internal::ErrnoSaver errno_saver; absl::raw_logging_internal::SafeWriteToStderr(data, strlen(data)); - errno = old_errno; } static void WriteSignalMessage(int signo, void (*writerfn)(const char*)) { @@ -357,5 +366,5 @@ void InstallFailureSignalHandler(const FailureSignalHandlerOptions& options) { } } -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/failure_signal_handler.h b/absl/debugging/failure_signal_handler.h index 87b202b0..f5a83962 100644 --- a/absl/debugging/failure_signal_handler.h +++ b/absl/debugging/failure_signal_handler.h @@ -44,8 +44,10 @@ #ifndef ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ #define ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ +#include "absl/base/config.h" + namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN // FailureSignalHandlerOptions // @@ -113,7 +115,7 @@ namespace debugging_internal { const char* FailureSignalToString(int signo); } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ diff --git a/absl/debugging/failure_signal_handler_test.cc b/absl/debugging/failure_signal_handler_test.cc index bb2cc48e..863fb514 100644 --- a/absl/debugging/failure_signal_handler_test.cc +++ b/absl/debugging/failure_signal_handler_test.cc @@ -23,6 +23,7 @@ #include <fstream> #include "gtest/gtest.h" +#include "gmock/gmock.h" #include "absl/base/internal/raw_logging.h" #include "absl/debugging/stacktrace.h" #include "absl/debugging/symbolize.h" @@ -31,6 +32,8 @@ namespace { +using testing::StartsWith; + #if GTEST_HAS_DEATH_TEST // For the parameterized death tests. GetParam() returns the signal number. @@ -113,15 +116,15 @@ TEST_P(FailureSignalHandlerDeathTest, AbslFatalSignalsWithWriterFn) { ASSERT_TRUE(error_output.is_open()) << file; std::string error_line; std::getline(error_output, error_line); - EXPECT_TRUE(absl::StartsWith( + EXPECT_THAT( error_line, - absl::StrCat("*** ", - absl::debugging_internal::FailureSignalToString(signo), - " received at "))); + StartsWith(absl::StrCat( + "*** ", absl::debugging_internal::FailureSignalToString(signo), + " received at "))); if (absl::debugging_internal::StackTraceWorksForTest()) { std::getline(error_output, error_line); - EXPECT_TRUE(absl::StartsWith(error_line, "PC: ")); + EXPECT_THAT(error_line, StartsWith("PC: ")); } } diff --git a/absl/debugging/internal/address_is_readable.cc b/absl/debugging/internal/address_is_readable.cc index 64dd285b..65376063 100644 --- a/absl/debugging/internal/address_is_readable.cc +++ b/absl/debugging/internal/address_is_readable.cc @@ -20,14 +20,14 @@ #if !defined(__linux__) || defined(__ANDROID__) namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // On platforms other than Linux, just return true. bool AddressIsReadable(const void* /* addr */) { return true; } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #else @@ -35,14 +35,16 @@ bool AddressIsReadable(const void* /* addr */) { return true; } #include <fcntl.h> #include <sys/syscall.h> #include <unistd.h> + #include <atomic> #include <cerrno> #include <cstdint> +#include "absl/base/internal/errno_saver.h" #include "absl/base/internal/raw_logging.h" namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Pack a pid and two file descriptors into a 64-bit word, @@ -67,7 +69,7 @@ static void Unpack(uint64_t x, int *pid, int *read_fd, int *write_fd) { // 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) { - int save_errno = errno; + absl::base_internal::ErrnoSaver errno_saver; // We test whether a byte is readable by using write(). Normally, this would // be done via a cached file descriptor to /dev/null, but linux fails to // check whether the byte is readable when the destination is /dev/null, so @@ -126,12 +128,11 @@ bool AddressIsReadable(const void *addr) { std::memory_order_relaxed); } } while (errno == EBADF); - errno = save_errno; return bytes_written == 1; } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif diff --git a/absl/debugging/internal/address_is_readable.h b/absl/debugging/internal/address_is_readable.h index dc626e5b..4bbaf4d6 100644 --- a/absl/debugging/internal/address_is_readable.h +++ b/absl/debugging/internal/address_is_readable.h @@ -15,8 +15,10 @@ #ifndef ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ #define ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ +#include "absl/base/config.h" + namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Return whether the byte at *addr is readable, without faulting. @@ -24,7 +26,7 @@ namespace debugging_internal { bool AddressIsReadable(const void *addr); } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 976e47a6..fc615c3f 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -24,7 +24,7 @@ #include <limits> namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { typedef struct { @@ -94,6 +94,8 @@ static const AbbrevPair kOperatorList[] = { }; // List of builtin types from Itanium C++ ABI. +// +// Invariant: only one- or two-character type abbreviations here. static const AbbrevPair kBuiltinTypeList[] = { {"v", "void", 0}, {"w", "wchar_t", 0}, @@ -116,6 +118,16 @@ static const AbbrevPair kBuiltinTypeList[] = { {"e", "long double", 0}, {"g", "__float128", 0}, {"z", "ellipsis", 0}, + + {"De", "decimal128", 0}, // IEEE 754r decimal floating point (128 bits) + {"Dd", "decimal64", 0}, // IEEE 754r decimal floating point (64 bits) + {"Dc", "decltype(auto)", 0}, + {"Da", "auto", 0}, + {"Dn", "std::nullptr_t", 0}, // i.e., decltype(nullptr) + {"Df", "decimal32", 0}, // IEEE 754r decimal floating point (32 bits) + {"Di", "char32_t", 0}, + {"Ds", "char16_t", 0}, + {"Dh", "float16", 0}, // IEEE 754r half-precision float (16 bits) {nullptr, nullptr, 0}, }; @@ -1169,12 +1181,6 @@ static bool ParseType(State *state) { } state->parse_state = copy; - // nullptr_t, i.e. decltype(nullptr). - if (ParseTwoCharToken(state, "Dn")) { - return true; - } - state->parse_state = copy; - if (ParseOneCharToken(state, 'U') && ParseSourceName(state) && ParseType(state)) { return true; @@ -1215,16 +1221,26 @@ static bool ParseCVQualifiers(State *state) { return num_cv_qualifiers > 0; } -// <builtin-type> ::= v, etc. +// <builtin-type> ::= v, etc. # single-character builtin types // ::= u <source-name> +// ::= Dd, etc. # two-character builtin types +// +// Not supported: +// ::= DF <number> _ # _FloatN (N bits) +// static bool ParseBuiltinType(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; const AbbrevPair *p; for (p = kBuiltinTypeList; p->abbrev != nullptr; ++p) { - if (RemainingInput(state)[0] == p->abbrev[0]) { + // Guaranteed only 1- or 2-character strings in kBuiltinTypeList. + if (p->abbrev[1] == '\0') { + if (ParseOneCharToken(state, p->abbrev[0])) { + MaybeAppend(state, p->real_name); + return true; + } + } else if (p->abbrev[2] == '\0' && ParseTwoCharToken(state, p->abbrev)) { MaybeAppend(state, p->real_name); - ++state->parse_state.mangled_idx; return true; } } @@ -1875,5 +1891,5 @@ bool Demangle(const char *mangled, char *out, int out_size) { } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/internal/demangle.h b/absl/debugging/internal/demangle.h index 20adbe9c..c314d9bc 100644 --- a/absl/debugging/internal/demangle.h +++ b/absl/debugging/internal/demangle.h @@ -53,8 +53,10 @@ #ifndef ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ #define ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ +#include "absl/base/config.h" + namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Demangle `mangled`. On success, return true and write the @@ -63,7 +65,7 @@ namespace debugging_internal { bool Demangle(const char *mangled, char *out, int out_size); } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index 7c50fe3a..c6f1ce18 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -23,7 +23,7 @@ #include "absl/memory/memory.h" namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { namespace { @@ -191,5 +191,5 @@ TEST(DemangleRegression, DeeplyNestedArrayType) { } // namespace } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/internal/elf_mem_image.cc b/absl/debugging/internal/elf_mem_image.cc index a795117a..24cc0130 100644 --- a/absl/debugging/internal/elf_mem_image.cc +++ b/absl/debugging/internal/elf_mem_image.cc @@ -38,7 +38,7 @@ #define VERSYM_VERSION 0x7fff namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { namespace { @@ -376,7 +376,7 @@ void ElfMemImage::SymbolIterator::Update(int increment) { } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_ELF_MEM_IMAGE diff --git a/absl/debugging/internal/elf_mem_image.h b/absl/debugging/internal/elf_mem_image.h index fcd32afe..46bfade3 100644 --- a/absl/debugging/internal/elf_mem_image.h +++ b/absl/debugging/internal/elf_mem_image.h @@ -23,6 +23,8 @@ // used. #include <climits> +#include "absl/base/config.h" + // Maybe one day we can rewrite this file not to require the elf // symbol extensions in glibc, but for right now we need them. #ifdef ABSL_HAVE_ELF_MEM_IMAGE @@ -39,7 +41,7 @@ #include <link.h> // for ElfW namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // An in-memory ELF image (may not exist on disk). @@ -124,7 +126,7 @@ class ElfMemImage { }; } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_ELF_MEM_IMAGE diff --git a/absl/debugging/internal/examine_stack.cc b/absl/debugging/internal/examine_stack.cc index 4739fbc5..a3dd893a 100644 --- a/absl/debugging/internal/examine_stack.cc +++ b/absl/debugging/internal/examine_stack.cc @@ -30,7 +30,7 @@ #include "absl/debugging/symbolize.h" namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Returns the program counter from signal context, nullptr if @@ -53,6 +53,8 @@ void* GetProgramCounter(void* vuc) { return reinterpret_cast<void*>(context->uc_mcontext.gp_regs[32]); #elif defined(__powerpc__) return reinterpret_cast<void*>(context->uc_mcontext.regs->nip); +#elif defined(__riscv) + return reinterpret_cast<void*>(context->uc_mcontext.__gregs[REG_PC]); #elif defined(__s390__) && !defined(__s390x__) return reinterpret_cast<void*>(context->uc_mcontext.psw.addr & 0x7fffffff); #elif defined(__s390__) && defined(__s390x__) @@ -151,5 +153,5 @@ void DumpPCAndFrameSizesAndStackTrace( } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/internal/examine_stack.h b/absl/debugging/internal/examine_stack.h index 861db75d..39336913 100644 --- a/absl/debugging/internal/examine_stack.h +++ b/absl/debugging/internal/examine_stack.h @@ -17,8 +17,10 @@ #ifndef ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ #define ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ +#include "absl/base/config.h" + namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Returns the program counter from signal context, or nullptr if @@ -34,7 +36,7 @@ void DumpPCAndFrameSizesAndStackTrace( void (*writerfn)(const char*, void*), void* writerfn_arg); } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ diff --git a/absl/debugging/internal/stack_consumption.cc b/absl/debugging/internal/stack_consumption.cc index 8dfd94aa..875ca6d9 100644 --- a/absl/debugging/internal/stack_consumption.cc +++ b/absl/debugging/internal/stack_consumption.cc @@ -27,7 +27,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { namespace { @@ -116,10 +116,11 @@ int GetSignalHandlerStackConsumption(void (*signal_handler)(int)) { // Set up the alt-signal-stack (and save the older one). stack_t sigstk; memset(&sigstk, 0, sizeof(sigstk)); - stack_t old_sigstk; sigstk.ss_sp = altstack; sigstk.ss_size = kAlternateStackSize; sigstk.ss_flags = 0; + stack_t old_sigstk; + memset(&old_sigstk, 0, sizeof(old_sigstk)); ABSL_RAW_CHECK(sigaltstack(&sigstk, &old_sigstk) == 0, "sigaltstack() failed"); @@ -153,6 +154,15 @@ int GetSignalHandlerStackConsumption(void (*signal_handler)(int)) { int signal_handler_stack_consumption = GetStackConsumption(altstack); // Now restore the old alt-signal-stack and signal handlers. + if (old_sigstk.ss_sp == nullptr && old_sigstk.ss_size == 0 && + (old_sigstk.ss_flags & SS_DISABLE)) { + // https://git.musl-libc.org/cgit/musl/commit/src/signal/sigaltstack.c?id=7829f42a2c8944555439380498ab8b924d0f2070 + // The original stack has ss_size==0 and ss_flags==SS_DISABLE, but some + // versions of musl have a bug that rejects ss_size==0. Work around this by + // setting ss_size to MINSIGSTKSZ, which should be ignored by the kernel + // when SS_DISABLE is set. + old_sigstk.ss_size = MINSIGSTKSZ; + } ABSL_RAW_CHECK(sigaltstack(&old_sigstk, nullptr) == 0, "sigaltstack() failed"); ABSL_RAW_CHECK(sigaction(SIGUSR1, &old_sa1, nullptr) == 0, @@ -168,7 +178,7 @@ int GetSignalHandlerStackConsumption(void (*signal_handler)(int)) { } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION diff --git a/absl/debugging/internal/stack_consumption.h b/absl/debugging/internal/stack_consumption.h index 1eb37eef..5e60ec42 100644 --- a/absl/debugging/internal/stack_consumption.h +++ b/absl/debugging/internal/stack_consumption.h @@ -18,6 +18,8 @@ #ifndef ABSL_DEBUGGING_INTERNAL_STACK_CONSUMPTION_H_ #define ABSL_DEBUGGING_INTERNAL_STACK_CONSUMPTION_H_ +#include "absl/base/config.h" + // The code in this module is not portable. // Use this feature test macro to detect its availability. #ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION @@ -27,7 +29,7 @@ #define ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION 1 namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Returns the stack consumption in bytes for the code exercised by @@ -39,7 +41,7 @@ namespace debugging_internal { int GetSignalHandlerStackConsumption(void (*signal_handler)(int)); } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION diff --git a/absl/debugging/internal/stack_consumption_test.cc b/absl/debugging/internal/stack_consumption_test.cc index 1c82d18a..80445bf4 100644 --- a/absl/debugging/internal/stack_consumption_test.cc +++ b/absl/debugging/internal/stack_consumption_test.cc @@ -23,7 +23,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { namespace { @@ -44,7 +44,7 @@ TEST(SignalHandlerStackConsumptionTest, MeasuresStackConsumption) { } // namespace } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION diff --git a/absl/debugging/internal/stacktrace_aarch64-inl.inc b/absl/debugging/internal/stacktrace_aarch64-inl.inc index 14b6e6b0..411ea308 100644 --- a/absl/debugging/internal/stacktrace_aarch64-inl.inc +++ b/absl/debugging/internal/stacktrace_aarch64-inl.inc @@ -180,13 +180,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_AARCH64_INL_H_ diff --git a/absl/debugging/internal/stacktrace_arm-inl.inc b/absl/debugging/internal/stacktrace_arm-inl.inc index 4f51d180..fffda968 100644 --- a/absl/debugging/internal/stacktrace_arm-inl.inc +++ b/absl/debugging/internal/stacktrace_arm-inl.inc @@ -113,13 +113,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return false; } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_ARM_INL_H_ diff --git a/absl/debugging/internal/stacktrace_generic-inl.inc b/absl/debugging/internal/stacktrace_generic-inl.inc index 39c47866..ac034c9f 100644 --- a/absl/debugging/internal/stacktrace_generic-inl.inc +++ b/absl/debugging/internal/stacktrace_generic-inl.inc @@ -16,6 +16,7 @@ #include <cstring> #include "absl/debugging/stacktrace.h" +#include "absl/base/attributes.h" // Sometimes, we can try to get a stack trace from within a stack // trace, because we don't block signals inside this code (which would be too @@ -35,7 +36,7 @@ static __thread int recursive = 0; static std::atomic<bool> disable_stacktraces(true); // Disabled until healthy. // Waiting until static initializers run seems to be late enough. // This file is included into stacktrace.cc so this will only run once. -static int stacktraces_enabler = []() { +ABSL_ATTRIBUTE_UNUSED static int stacktraces_enabler = []() { void* unused_stack[1]; // Force the first backtrace to happen early to get the one-time shared lib // loading (allocation) out of the way. After the first call it is much safer @@ -86,13 +87,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_GENERIC_INL_H_ diff --git a/absl/debugging/internal/stacktrace_powerpc-inl.inc b/absl/debugging/internal/stacktrace_powerpc-inl.inc index ee6b38ff..2e7c2f40 100644 --- a/absl/debugging/internal/stacktrace_powerpc-inl.inc +++ b/absl/debugging/internal/stacktrace_powerpc-inl.inc @@ -236,13 +236,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_ diff --git a/absl/debugging/internal/stacktrace_unimplemented-inl.inc b/absl/debugging/internal/stacktrace_unimplemented-inl.inc index b49a929a..5b8fb191 100644 --- a/absl/debugging/internal/stacktrace_unimplemented-inl.inc +++ b/absl/debugging/internal/stacktrace_unimplemented-inl.inc @@ -12,13 +12,13 @@ static int UnwindImpl(void** /* result */, int* /* sizes */, } namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return false; } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_UNIMPLEMENTED_INL_H_ diff --git a/absl/debugging/internal/stacktrace_win32-inl.inc b/absl/debugging/internal/stacktrace_win32-inl.inc index 0cd8c339..9c2c5580 100644 --- a/absl/debugging/internal/stacktrace_win32-inl.inc +++ b/absl/debugging/internal/stacktrace_win32-inl.inc @@ -54,7 +54,7 @@ static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn = template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, - const void *ucp, int *min_dropped_frames) { + const void*, int* min_dropped_frames) { int n = 0; if (!RtlCaptureStackBackTrace_fn) { // can't find a stacktrace with no function to call @@ -73,13 +73,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return false; } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_WIN32_INL_H_ diff --git a/absl/debugging/internal/stacktrace_x86-inl.inc b/absl/debugging/internal/stacktrace_x86-inl.inc index ff0fd31f..bc320ff7 100644 --- a/absl/debugging/internal/stacktrace_x86-inl.inc +++ b/absl/debugging/internal/stacktrace_x86-inl.inc @@ -36,6 +36,8 @@ #include "absl/base/internal/raw_logging.h" +using absl::debugging_internal::AddressIsReadable; + #if defined(__linux__) && defined(__i386__) // Count "push %reg" instructions in VDSO __kernel_vsyscall(), // preceeding "syscall" or "sysenter". @@ -81,7 +83,7 @@ static int CountPushInstructions(const unsigned char *const addr) { // "mov reg,reg" if (addr[i + 1] == 0xE5) { // Found "mov %esp,%ebp". - return 0; + return 0; } ++i; // Skip register encoding byte. } else if (addr[i] == 0x0F && @@ -171,6 +173,7 @@ static void **NextStackFrame(void **old_fp, const void *uc) { static const unsigned char *kernel_rt_sigreturn_address = nullptr; static const unsigned char *kernel_vsyscall_address = nullptr; if (num_push_instructions == -1) { +#ifdef ABSL_HAVE_VDSO_SUPPORT absl::debugging_internal::VDSOSupport vdso; if (vdso.IsPresent()) { absl::debugging_internal::VDSOSupport::SymbolInfo @@ -199,6 +202,9 @@ static void **NextStackFrame(void **old_fp, const void *uc) { } else { num_push_instructions = 0; } +#else // ABSL_HAVE_VDSO_SUPPORT + num_push_instructions = 0; +#endif // ABSL_HAVE_VDSO_SUPPORT } if (num_push_instructions != 0 && kernel_rt_sigreturn_address != nullptr && old_fp[1] == kernel_rt_sigreturn_address) { @@ -222,7 +228,7 @@ static void **NextStackFrame(void **old_fp, const void *uc) { // "double fault" in case we hit the first fault due to e.g. stack // corruption. void *const reg_esp2 = reg_esp[num_push_instructions - 1]; - if (absl::debugging_internal::AddressIsReadable(reg_esp2)) { + if (AddressIsReadable(reg_esp2)) { // Alleged %esp is readable, use it for further unwinding. new_fp = reinterpret_cast<void **>(reg_esp2); } @@ -274,7 +280,7 @@ static void **NextStackFrame(void **old_fp, const void *uc) { // Note: NextStackFrame<false>() is only called while the program // is already on its last leg, so it's ok to be slow here. - if (!absl::debugging_internal::AddressIsReadable(new_fp)) { + if (!AddressIsReadable(new_fp)) { return nullptr; } } @@ -328,13 +334,13 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, } namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_X86_INL_INC_ diff --git a/absl/debugging/internal/symbolize.h b/absl/debugging/internal/symbolize.h index 151bc77c..5d0858b5 100644 --- a/absl/debugging/internal/symbolize.h +++ b/absl/debugging/internal/symbolize.h @@ -21,6 +21,8 @@ #include <cstddef> #include <cstdint> +#include "absl/base/config.h" + #ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE #error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set #elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) && \ @@ -33,7 +35,7 @@ #include <string> namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Iterates over all sections, invoking callback on each with the section name @@ -52,13 +54,13 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, ElfW(Shdr) *out); } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { struct SymbolDecoratorArgs { @@ -120,7 +122,7 @@ bool GetFileMappingHint(const void** start, const char** filename); } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ diff --git a/absl/debugging/internal/vdso_support.cc b/absl/debugging/internal/vdso_support.cc index fa88e1d8..1e8a78ac 100644 --- a/absl/debugging/internal/vdso_support.cc +++ b/absl/debugging/internal/vdso_support.cc @@ -38,7 +38,7 @@ #endif namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { ABSL_CONST_INIT @@ -188,7 +188,7 @@ static class VDSOInitHelper { } vdso_init_helper; } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_VDSO_SUPPORT diff --git a/absl/debugging/internal/vdso_support.h b/absl/debugging/internal/vdso_support.h index bc5fdb11..6562c6c2 100644 --- a/absl/debugging/internal/vdso_support.h +++ b/absl/debugging/internal/vdso_support.h @@ -53,7 +53,7 @@ #endif namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // NOTE: this class may be used from within tcmalloc, and can not @@ -150,7 +150,7 @@ class VDSOSupport { int GetCPU(); } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_ELF_MEM_IMAGE diff --git a/absl/debugging/leak_check.cc b/absl/debugging/leak_check.cc index 63e54ffa..ff904955 100644 --- a/absl/debugging/leak_check.cc +++ b/absl/debugging/leak_check.cc @@ -21,14 +21,14 @@ #ifndef LEAK_SANITIZER namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN bool HaveLeakSanitizer() { return false; } void DoIgnoreLeak(const void*) { } void RegisterLivePointers(const void*, size_t) { } void UnRegisterLivePointers(const void*, size_t) { } LeakCheckDisabler::LeakCheckDisabler() { } LeakCheckDisabler::~LeakCheckDisabler() { } -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #else @@ -36,7 +36,7 @@ LeakCheckDisabler::~LeakCheckDisabler() { } #include <sanitizer/lsan_interface.h> namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN bool HaveLeakSanitizer() { return true; } void DoIgnoreLeak(const void* ptr) { __lsan_ignore_object(ptr); } void RegisterLivePointers(const void* ptr, size_t size) { @@ -47,7 +47,7 @@ void UnRegisterLivePointers(const void* ptr, size_t size) { } LeakCheckDisabler::LeakCheckDisabler() { __lsan_disable(); } LeakCheckDisabler::~LeakCheckDisabler() { __lsan_enable(); } -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // LEAK_SANITIZER diff --git a/absl/debugging/leak_check.h b/absl/debugging/leak_check.h index e1215e38..7a5a22dd 100644 --- a/absl/debugging/leak_check.h +++ b/absl/debugging/leak_check.h @@ -32,8 +32,10 @@ #include <cstddef> +#include "absl/base/config.h" + namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN // HaveLeakSanitizer() // @@ -105,7 +107,7 @@ void RegisterLivePointers(const void* ptr, size_t size); // `RegisterLivePointers()`, enabling leak checking of those pointers. void UnRegisterLivePointers(const void* ptr, size_t size); -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_LEAK_CHECK_H_ diff --git a/absl/debugging/stacktrace.cc b/absl/debugging/stacktrace.cc index 3052fb97..1f7c7d82 100644 --- a/absl/debugging/stacktrace.cc +++ b/absl/debugging/stacktrace.cc @@ -57,7 +57,7 @@ #endif namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace { typedef int (*Unwinder)(void**, int*, int, int, const void*, int*); @@ -136,5 +136,5 @@ int DefaultStackUnwinder(void** pcs, int* sizes, int depth, int skip, return n; } -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/stacktrace.h b/absl/debugging/stacktrace.h index d7565aa4..0ec0ffda 100644 --- a/absl/debugging/stacktrace.h +++ b/absl/debugging/stacktrace.h @@ -31,16 +31,18 @@ #ifndef ABSL_DEBUGGING_STACKTRACE_H_ #define ABSL_DEBUGGING_STACKTRACE_H_ +#include "absl/base/config.h" + namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN // GetStackFrames() // // Records program counter values for up to `max_depth` frames, skipping the -// most recent `skip_count` stack frames, and stores their corresponding values -// and sizes in `results` and `sizes` buffers. (Note that the frame generated -// for the `absl::GetStackFrames()` routine itself is also skipped.) -// routine itself. +// most recent `skip_count` stack frames, stores their corresponding values +// and sizes in `results` and `sizes` buffers, and returns the number of frames +// stored. (Note that the frame generated for the `absl::GetStackFrames()` +// routine itself is also skipped.) // // Example: // @@ -55,8 +57,8 @@ inline namespace lts_2019_08_08 { // The current stack frame would consist of three function calls: `bar()`, // `foo()`, and then `main()`; however, since the `GetStackFrames()` call sets // `skip_count` to `1`, it will skip the frame for `bar()`, the most recently -// invoked function call. It will therefore return two program counters and will -// produce values that map to the following function calls: +// invoked function call. It will therefore return 2 and fill `result` with +// program counters within the following functions: // // result[0] foo() // result[1] main() @@ -83,9 +85,10 @@ extern int GetStackFrames(void** result, int* sizes, int max_depth, // // Records program counter values obtained from a signal handler. Records // program counter values for up to `max_depth` frames, skipping the most recent -// `skip_count` stack frames, and stores their corresponding values and sizes in -// `results` and `sizes` buffers. (Note that the frame generated for the -// `absl::GetStackFramesWithContext()` routine itself is also skipped.) +// `skip_count` stack frames, stores their corresponding values and sizes in +// `results` and `sizes` buffers, and returns the number of frames stored. (Note +// that the frame generated for the `absl::GetStackFramesWithContext()` routine +// itself is also skipped.) // // The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value // passed to a signal handler registered via the `sa_sigaction` field of a @@ -106,8 +109,9 @@ extern int GetStackFramesWithContext(void** result, int* sizes, int max_depth, // GetStackTrace() // // Records program counter values for up to `max_depth` frames, skipping the -// most recent `skip_count` stack frames, and stores their corresponding values -// in `results`. Note that this function is similar to `absl::GetStackFrames()` +// most recent `skip_count` stack frames, stores their corresponding values +// in `results`, and returns the number of frames +// stored. Note that this function is similar to `absl::GetStackFrames()` // except that it returns the stack trace only, and not stack frame sizes. // // Example: @@ -132,9 +136,9 @@ extern int GetStackTrace(void** result, int max_depth, int skip_count); // // Records program counter values obtained from a signal handler. Records // program counter values for up to `max_depth` frames, skipping the most recent -// `skip_count` stack frames, and stores their corresponding values in -// `results`. (Note that the frame generated for the -// `absl::GetStackFramesWithContext()` routine itself is also skipped.) +// `skip_count` stack frames, stores their corresponding values in `results`, +// and returns the number of frames stored. (Note that the frame generated for +// the `absl::GetStackFramesWithContext()` routine itself is also skipped.) // // The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value // passed to a signal handler registered via the `sa_sigaction` field of a @@ -221,7 +225,7 @@ namespace debugging_internal { // working. extern bool StackTraceWorksForTest(); } // namespace debugging_internal -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_STACKTRACE_H_ diff --git a/absl/debugging/symbolize.cc b/absl/debugging/symbolize.cc index 24e3a7f0..54ed9700 100644 --- a/absl/debugging/symbolize.cc +++ b/absl/debugging/symbolize.cc @@ -16,12 +16,9 @@ #if defined(ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE) #include "absl/debugging/symbolize_elf.inc" -#elif defined(_WIN32) && defined(_DEBUG) -// The Windows Symbolizer only works in debug mode. Note that _DEBUG -// is the macro that defines whether or not MS C-Runtime debug info is -// available. Note that the PDB files containing the debug info must -// also be available to the program at runtime for the symbolizer to -// work. +#elif defined(_WIN32) +// The Windows Symbolizer only works if PDB files containing the debug info +// are available to the program at runtime. #include "absl/debugging/symbolize_win32.inc" #else #include "absl/debugging/symbolize_unimplemented.inc" diff --git a/absl/debugging/symbolize.h b/absl/debugging/symbolize.h index ab5447c4..43d93a86 100644 --- a/absl/debugging/symbolize.h +++ b/absl/debugging/symbolize.h @@ -55,7 +55,7 @@ #include "absl/debugging/internal/symbolize.h" namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN // InitializeSymbolizer() // @@ -71,7 +71,7 @@ inline namespace lts_2019_08_08 { // // Now you can use the symbolizer // } void InitializeSymbolizer(const char* argv0); - +// // Symbolize() // // Symbolizes a program counter (instruction pointer value) `pc` and, on @@ -89,11 +89,11 @@ void InitializeSymbolizer(const char* argv0); // if (absl::Symbolize(pc, tmp, sizeof(tmp))) { // symbol = tmp; // } -// absl::PrintF("%*p %s\n", pc, symbol); +// absl::PrintF("%p %s\n", pc, symbol); // } bool Symbolize(const void *pc, char *out, int out_size); -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_SYMBOLIZE_H_ diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc index 2bd7659f..c371635f 100644 --- a/absl/debugging/symbolize_elf.inc +++ b/absl/debugging/symbolize_elf.inc @@ -76,7 +76,7 @@ #include "absl/debugging/internal/vdso_support.h" namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN // Value of argv[0]. Used by MaybeInitializeObjFile(). static char *argv0_value = nullptr; @@ -625,6 +625,13 @@ static bool InSection(const void *address, const ElfW(Shdr) * section) { return start <= address && address < (start + size); } +static const char *ComputeOffset(const char *base, ptrdiff_t offset) { + // Note: cast to uintptr_t to avoid undefined behavior when base evaluates to + // zero and offset is non-zero. + return reinterpret_cast<const char *>( + reinterpret_cast<uintptr_t>(base) + offset); +} + // Read a symbol table and look for the symbol containing the // pc. Iterate over symbols in a symbol table and look for the symbol // containing "pc". If the symbol is found, and its name fits in @@ -677,7 +684,8 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( // We keep the original address for opd redirection below. const char *const original_start_address = reinterpret_cast<const char *>(symbol.st_value); - const char *start_address = original_start_address + relocation; + const char *start_address = + ComputeOffset(original_start_address, relocation); if (deref_function_descriptor_pointer && InSection(original_start_address, opd)) { @@ -689,8 +697,7 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( // If pc is inside the .opd section, it points to a function descriptor. const size_t size = pc_in_opd ? kFunctionDescriptorSize : symbol.st_size; - const void *const end_address = - reinterpret_cast<const char *>(start_address) + size; + const void *const end_address = ComputeOffset(start_address, size); if (symbol.st_value != 0 && // Skip null value symbols. symbol.st_shndx != 0 && // Skip undefined symbols. #ifdef STT_TLS @@ -1469,5 +1476,5 @@ bool Symbolize(const void *pc, char *out, int out_size) { return ok; } -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc index 08068c30..a1d03aab 100644 --- a/absl/debugging/symbolize_test.cc +++ b/absl/debugging/symbolize_test.cc @@ -35,10 +35,29 @@ using testing::Contains; +#ifdef _WIN32 +#define ABSL_SYMBOLIZE_TEST_NOINLINE __declspec(noinline) +#else +#define ABSL_SYMBOLIZE_TEST_NOINLINE ABSL_ATTRIBUTE_NOINLINE +#endif + // Functions to symbolize. Use C linkage to avoid mangled names. extern "C" { -void nonstatic_func() { ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); } -static void static_func() { ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); } +ABSL_SYMBOLIZE_TEST_NOINLINE void nonstatic_func() { + // The next line makes this a unique function to prevent the compiler from + // folding identical functions together. + volatile int x = __LINE__; + static_cast<void>(x); + ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); +} + +ABSL_SYMBOLIZE_TEST_NOINLINE static void static_func() { + // The next line makes this a unique function to prevent the compiler from + // folding identical functions together. + volatile int x = __LINE__; + static_cast<void>(x); + ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); +} } // extern "C" struct Foo { @@ -46,7 +65,11 @@ struct Foo { }; // A C++ method that should have a mangled name. -void ABSL_ATTRIBUTE_NOINLINE Foo::func(int) { +ABSL_SYMBOLIZE_TEST_NOINLINE void Foo::func(int) { + // The next line makes this a unique function to prevent the compiler from + // folding identical functions together. + volatile int x = __LINE__; + static_cast<void>(x); ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); } @@ -80,6 +103,7 @@ static ABSL_PER_THREAD_TLS_KEYWORD char symbolize_test_thread_big[2 * 1024 * 1024]; #endif +#if !defined(__EMSCRIPTEN__) // Used below to hopefully inhibit some compiler/linker optimizations // that may remove kHpageTextPadding, kPadding0, and kPadding1 from // the binary. @@ -89,6 +113,7 @@ static volatile bool volatile_bool = false; static constexpr size_t kHpageSize = 1 << 21; const char kHpageTextPadding[kHpageSize * 4] ABSL_ATTRIBUTE_SECTION_VARIABLE( .text) = ""; +#endif // !defined(__EMSCRIPTEN__) static char try_symbolize_buffer[4096]; @@ -447,14 +472,15 @@ void ABSL_ATTRIBUTE_NOINLINE TestWithReturnAddress() { #endif } -#elif defined(_WIN32) && defined(_DEBUG) +#elif defined(_WIN32) +#if !defined(ABSL_CONSUME_DLL) TEST(Symbolize, Basics) { EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func))); // The name of an internal linkage symbol is not specified; allow either a // mangled or an unmangled name here. - const char* static_func_symbol = TrySymbolize((void *)(&static_func)); + const char *static_func_symbol = TrySymbolize((void *)(&static_func)); ASSERT_TRUE(static_func_symbol != nullptr); EXPECT_TRUE(strstr(static_func_symbol, "static_func") != nullptr); @@ -481,11 +507,12 @@ TEST(Symbolize, Truncation) { } TEST(Symbolize, SymbolizeWithDemangling) { - const char* result = TrySymbolize((void *)(&Foo::func)); + const char *result = TrySymbolize((void *)(&Foo::func)); ASSERT_TRUE(result != nullptr); EXPECT_TRUE(strstr(result, "Foo::func") != nullptr) << result; } +#endif // !defined(ABSL_CONSUME_DLL) #else // Symbolizer unimplemented TEST(Symbolize, Unimplemented) { @@ -498,10 +525,12 @@ TEST(Symbolize, Unimplemented) { #endif int main(int argc, char **argv) { +#if !defined(__EMSCRIPTEN__) // Make sure kHpageTextPadding is linked into the binary. if (volatile_bool) { ABSL_RAW_LOG(INFO, "%s", kHpageTextPadding); } +#endif // !defined(__EMSCRIPTEN__) #if ABSL_PER_THREAD_TLS // Touch the per-thread variables. diff --git a/absl/debugging/symbolize_unimplemented.inc b/absl/debugging/symbolize_unimplemented.inc index 0c1c1951..db24456b 100644 --- a/absl/debugging/symbolize_unimplemented.inc +++ b/absl/debugging/symbolize_unimplemented.inc @@ -17,7 +17,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { @@ -36,5 +36,5 @@ bool GetFileMappingHint(const void **, const void **, uint64_t *, const char **) void InitializeSymbolizer(const char*) {} bool Symbolize(const void *, char *, int) { return false; } -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/symbolize_win32.inc b/absl/debugging/symbolize_win32.inc index 498ca2db..c3df46f6 100644 --- a/absl/debugging/symbolize_win32.inc +++ b/absl/debugging/symbolize_win32.inc @@ -17,10 +17,10 @@ #include <windows.h> -// MSVC header DbgHelp.h has a warning for an ignored typedef. +// MSVC header dbghelp.h has a warning for an ignored typedef. #pragma warning(push) #pragma warning(disable:4091) -#include <DbgHelp.h> +#include <dbghelp.h> #pragma warning(pop) #pragma comment(lib, "dbghelp.lib") @@ -31,11 +31,11 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN static HANDLE process = NULL; -void InitializeSymbolizer(const char *argv0) { +void InitializeSymbolizer(const char*) { if (process != nullptr) { return; } @@ -54,13 +54,12 @@ void InitializeSymbolizer(const char *argv0) { } } -bool Symbolize(const void *pc, char *out, int out_size) { +bool Symbolize(const void* pc, char* out, int out_size) { if (out_size <= 0) { return false; } - std::aligned_storage<sizeof(SYMBOL_INFO) + MAX_SYM_NAME, - alignof(SYMBOL_INFO)>::type buf; - SYMBOL_INFO *symbol = reinterpret_cast<SYMBOL_INFO *>(&buf); + alignas(SYMBOL_INFO) char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; + SYMBOL_INFO* symbol = reinterpret_cast<SYMBOL_INFO*>(buf); symbol->SizeOfStruct = sizeof(SYMBOL_INFO); symbol->MaxNameLen = MAX_SYM_NAME; if (!SymFromAddr(process, reinterpret_cast<DWORD64>(pc), nullptr, symbol)) { @@ -78,5 +77,5 @@ bool Symbolize(const void *pc, char *out, int out_size) { return true; } -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl |