Squashed 'third_party/abseil/' changes from ddf8e52a2..384af0e91
384af0e91 Export of internal Abseil changes
e7ca23aca Export of internal Abseil changes
4611a601a Export of internal Abseil changes
8a9ef3c5d Export of internal Abseil changes
9f8b87b71 Add missing word 'library' in the 'status' description (#868)
e2b1bab19 Export of internal Abseil changes
1bae23e32 Export of internal Abseil changes
6df644c56 Include the status library into the main README. (#863)
68f1ad932 Export of internal Abseil changes
52acfe6fc Export of internal Abseil changes
1918ad2ae Export of internal Abseil changes
938fd0f4e Export of internal Abseil changes
fbdff6f3a Export of internal Abseil changes
acf3390ca Export of internal Abseil changes
592924480 Export of internal Abseil changes
e80c0b353 Export of internal Abseil changes
5d8fc9192 Export of internal Abseil changes
e19260fd7 Export of internal Abseil changes
4fd9a1ec5 Export of internal Abseil changes
4ae673067 Export of internal Abseil changes
1b465af3b Export of internal Abseil changes
6b03bf543 fix build dll (#797)
0bbebc85c Export of internal Abseil changes
0453e1653 Export of internal Abseil changes
a4798817e Export of internal Abseil changes
e96d49687 Export of internal Abseil changes
731852f10 Fix stacktrace on aarch64 architecture. Fixes #805 (#827)
2e5f2bcfd moved deleted functions to public for better compiler errors. (#828)
e9e9b9fc7 Export of internal Abseil changes
b8e890f95 Export of internal Abseil changes
c9894d1dc Export of internal Abseil changes
e9b9e38f6 Export of internal Abseil changes
962b06754 Export of internal Abseil changes
5bf048b84 Export of internal Abseil changes
1e3d25b26 Export of internal Abseil changes
eb317a701 Export of internal Abseil changes
4b915e709 Export of internal Abseil changes
8f1c34a77 Export of internal Abseil changes
60d00a582 Export of internal Abseil changes
f3f785ab5 Export of internal Abseil changes
4b2fbb4ad Export of internal Abseil changes
e493d6acb fix compile fails with asan and -Wredundant-decls (#801)
e63a5a610 Export of internal Abseil changes
c678d6c6b Export of internal Abseil changes
4b4f9aae7 Export of internal Abseil changes
887d0eee6 Export of internal Abseil changes
b978fc02f Export of internal Abseil changes
093cc2760 Export of internal Abseil changes
40fdb59d3 btree: fix sign-compare warnings (#800)
1fd58b69c Export of internal Abseil changes
d1de75bf5 Export of internal Abseil changes
cad3f30b4 Export of internal Abseil changes
9927a0989 Export of internal Abseil changes
7680a5f8e Added missing asserts for seq.index() < capacity_ and unified their usage based on has_element(). (#781)
d3614de61 Export of internal Abseil changes
20feb1cdb Export of internal Abseil changes
c1ae0a497 Export of internal Abseil changes
6af91b351 Export of internal Abseil changes
f2c9c663d Export of internal Abseil changes
3c8b5d758 Export of internal Abseil changes
7ba8cdb56 Export of internal Abseil changes
930fbec75 Export of internal Abseil changes
0e9921b75 Export of internal Abseil changes
a4cbb5f69 Export of internal Abseil changes
4d2ff381a Export of internal Abseil changes
c03c18e7f Export of internal Abseil changes
b321ad86c Export of internal Abseil changes
fbf0fdab6 Export of internal Abseil changes
dc969f34a Export of internal Abseil changes
d0c433455 Export of internal Abseil changes
c6b3f2cf5 Export of internal Abseil changes
1beb3191c Export of internal Abseil changes
1b7e751e5 Export of internal Abseil changes
ce4bc9277 Export of internal Abseil changes
f72cc3516 Export of internal Abseil changes
f66bc7492 Export of internal Abseil changes
1995c6a3c Export of internal Abseil changes
184cf2524 Export of internal Abseil changes
82302f1e0 Export of internal Abseil changes
dea76486c Export of internal Abseil changes
d39fe6cd6 Export of internal Abseil changes
2c8a5b0d8 Export of internal Abseil changes
41a6263fd Export of internal Abseil changes
3c2bed2e7 Export of internal Abseil changes
ea8a689cf fix build on P9 (#739)
672d9e0ae Export of internal Abseil changes
f624790b7 Export of internal Abseil changes
55c04eb92 Export of internal Abseil changes
302b250e1 Disable pthread for standalone wasm build support (#721)
61d8bc057 Merge branch 'master' of https://github.com/abseil/abseil-cpp into master
4b5b25a28 cmake: remove unneeded enable_testing() cmd (#736)
63f2c695e cmake: flag conformance_testing as TESTONLY (#737)
d5269a8b6 Export of internal Abseil changes
23f1f9cf6 Typo in comment (#733)
259301a52 Fix CMake path for INSTALL_INCLUDEDIR (#723)
dc464c1dc Allow overriding Abseil IDE folder (#724)
bf655de09 Export of internal Abseil changes
38db52adb Export of internal Abseil changes
81f34df83 Export of internal Abseil changes
b86fff162 Export of internal Abseil changes
10cb35e45 Export of internal Abseil changes
4ccc0fce0 Export of internal Abseil changes
4a851046a Export of internal Abseil changes
ccdbb5941 Export of internal Abseil changes
01f5f81f9 Export of internal Abseil changes
2c92bdc7c Export of internal Abseil changes
e7ebf9803 Export of internal Abseil changes
2eba343b5 Export of internal Abseil changes
a8b03d90e Export of internal Abseil changes
1d31b5c36 Export of internal Abseil changes
da3a87690 Export of internal Abseil changes
8faf20461 Exclude empty directories (#697)
2069dc796 Export of internal Abseil changes
4832bf6bf Added a BUILD file in root to expose license. (#695)
af8f994af Export of internal Abseil changes
33caf1097 Export of internal Abseil changes
cf1a02e2d Export of internal Abseil changes
768eb2ca2 Export of internal Abseil changes
3f347c462 Fix build on riscv32 (#675)
62cf6a704 Export of internal Abseil changes
d118d4bb1 Export of internal Abseil changes
f2bc9d11e Fix public target name of the random library (#684)
0fecf0e63 Export of internal Abseil changes
cbfd0f0fe Export of internal Abseil changes
c45d1c09d Export of internal Abseil changes
a35ef8a62 Export of internal Abseil changes
bd317cae3 Export of internal Abseil changes
b11574465 fix MSVC warning 4245: conversion signed => unsigned during initialization (#678)
d85783fd0 Export of internal Abseil changes
a1d668990 Export of internal Abseil changes
ca9856cab Export of internal Abseil changes
6e18c7115 Export of internal Abseil changes
3f48ce1c4 init (#673)
cde2e2410 Export of internal Abseil changes
68494aae9 Fix CMake Threads dependency issue
902909a43 Export of internal Abseil changes
cb52b05ea Export of internal Abseil changes
1a02b7a20 Use "-lrt" instead of the resolved find_library result when linking librt (#665)
df60c82df Export of internal Abseil changes
b35973e3e Export of internal Abseil changes
db5773a72 Export of internal Abseil changes
71079e42c Export of internal Abseil changes
2946ac0de Use base_internal::AtomicHook instead of std::atomic (#661)
567bee2f7 Fix ABSL_RANDOM_RANDEN_COPTS setting on FreeBSD (#664)
bf6166a63 Export of internal Abseil changes
111260963 Export of internal Abseil changes
73ea9a957 Export of internal Abseil changes
c01b9916e Add option to use an externally provided GoogleTest target (for usage of abseil as add_subdirectory target) (#647)
d43b7997c Export of internal Abseil changes
62f05b1f5 Export of internal Abseil changes
fba8a316c Export of internal Abseil changes
79e0dc115 Export of internal Abseil changes
132d791b4 bazel: Add missing load statements for cc_binary (#645)
518f17501 Export of internal Abseil changes
092ed9793 Export of internal Abseil changes
2d2a8aea2 Export of internal Abseil changes
7853a7586 Export of internal Abseil changes
c6954897f Export of internal Abseil changes
b92f35f65 Fix CompressedTuple move constructor on MSVC (#637)
a877af1f2 Export of internal Abseil changes
d936052d3 Export of internal Abseil changes
238b9a59c Skip the .exe suffix in the helpshort filter on Windows (#629)
417ea99cb UWP doesn't allow reading regkeys (#594)
40a0e58eb Export of internal Abseil changes
cf3a1998e Export of internal Abseil changes
b19ba9676 Export of internal Abseil changes
06f0e767d BuildBreak: UWP apps can't call GetModuleHandle (#596)
bcefbdcdf Export of internal Abseil changes
0033c9ea9 Fix build on FreeBSD/powerpc (#616)
0d5ce2797 Export of internal Abseil changes
b69c7d880 Export of internal Abseil changes
2a5633fc0 Merge "Export of internal Abseil changes"
f9b3d6e49 Add RISCV support to GetProgramCounter() (#621)
914ff4451 Export of internal Abseil changes
0232c87f2 Add missing ABSL_HAVE_VDSO_SUPPORT conditional (#622)
3c8141051 Export of internal Abseil changes
c44657f55 Export of internal Abseil changes
98eb410c9 Export of internal Abseil changes
bf78e9773 Export of internal Abseil changes
d95d15671 Export of internal Abseil changes
24713a703 Export of internal Abseil changes
72382c21f Export of internal Abseil changes
08a7e7bf9 Export of internal Abseil changes
36bcd9599 Fix pointer format specifier in documentation (#614)
0f86336b6 Export of internal Abseil changes
c512f118d Export of internal Abseil changes
37dd2562e Export of internal Abseil changes
444277026 fix: Add support for more ARM processors detection (#608)
159bf2bf6 Export of internal Abseil changes
a2e6adecc Use https links. (#586)
564001ae5 Export of internal Abseil changes
b3aaac8a3 Export of internal Abseil changes
63ee2f887 Export of internal Abseil changes
a048203a8 Export of internal Abseil changes
1de016636 Export of internal Abseil changes
ad904b6cd Export of internal Abseil changes
7bd1935dc cmake: Fix x86_64 check on Windows for random copts (#518)
292351391 Export of internal Abseil changes
bf86cfe16 Export of internal Abseil changes
12bc53e03 Export of internal Abseil changes
1e39f8626 Export of internal Abseil changes
77f87009a Export of internal Abseil changes
d659fe54b Export of internal Abseil changes
a4b757b5d Export of internal Abseil changes
0514227d2 Export of internal Abseil changes
7f4fe64af Export of internal Abseil changes
16d9fd58a Export of internal Abseil changes
bcaae6009 Export of internal Abseil changes
8ba96a824 Export of internal Abseil changes
2103fd9ac Export of internal Abseil changes
3df7b52a6 Export of internal Abseil changes
fa8c75182 Export of internal Abseil changes
85092b4b6 Fix Conan builds (#400)
e96ae2203 Export of internal Abseil changes
20de2db74 Export of internal Abseil changes
846e5dbed Export of internal Abseil changes
83880e3d8 Merge branch 'master' of https://github.com/abseil/abseil-cpp
8207907f4 Export of internal Abseil changes
39d68a422 docs: fix typo (#397)
078b89b3c Export of internal Abseil changes
19b021cb3 Export of internal Abseil changes
ecc0033b5 Always enable proper symbolize implementation on Windows (#257)
2796d500a Export of internal Abseil changes
e4c8d0eb8 Export of internal Abseil changes
a15364ce4 Export of internal Abseil changes
ab3552a18 Export of internal Abseil changes
e9f9000c7 Fix ABSL_WAITER_MODE detection for mingw (#342)
abea769b5 Fix ABSL_HAVE_ALARM check on mingw (#341)
25597bdfc Export of internal Abseil changes
aad33fefa Export of internal Abseil changes
8fe7214fe Export of internal Abseil changes
debac94cf Export of internal Abseil changes
882b3501a Fix spelling errors (#384)
502efe6d7 Export of internal Abseil changes
ccdd1d57b Export of internal Abseil changes
Change-Id: I59864a0053f6e03d88cc9d5e2a92757039a05484
git-subtree-dir: third_party/abseil
git-subtree-split: 384af0e9141283172e2bff3210dae79fb7130d9c
diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel
index b87c55a..cd6e454 100644
--- a/absl/debugging/BUILD.bazel
+++ b/absl/debugging/BUILD.bazel
@@ -26,11 +26,19 @@
default_visibility = ["//visibility:public"],
)
-licenses(["notice"]) # Apache 2.0
+licenses(["notice"])
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"],
@@ -38,6 +46,7 @@
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":debugging_internal",
+ "//absl/base:config",
"//absl/base:core_headers",
],
)
@@ -46,6 +55,7 @@
name = "symbolize",
srcs = [
"symbolize.cc",
+ "symbolize_darwin.inc",
"symbolize_elf.inc",
"symbolize_unimplemented.inc",
"symbolize_win32.inc",
@@ -55,30 +65,43 @@
"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",
+ "//absl/strings",
],
)
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:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
"//absl/memory",
+ "//absl/strings",
"@com_google_googletest//:gtest",
],
)
@@ -97,6 +120,7 @@
deps = [
":stacktrace",
":symbolize",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
],
@@ -114,6 +138,7 @@
"//absl/base",
"//absl/base:config",
"//absl/base:core_headers",
+ "//absl/base:errno_saver",
"//absl/base:raw_logging_internal",
],
)
@@ -124,6 +149,7 @@
copts = ABSL_TEST_COPTS,
linkopts = select({
"//absl:windows": [],
+ "//absl:wasm": [],
"//conditions:default": ["-pthread"],
}) + ABSL_DEFAULT_LINKOPTS,
deps = [
@@ -146,21 +172,15 @@
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:config",
"//absl/base:core_headers",
"//absl/base:dynamic_annotations",
+ "//absl/base:errno_saver",
"//absl/base:raw_logging_internal",
],
)
@@ -172,6 +192,7 @@
copts = ABSL_DEFAULT_COPTS,
deps = [
"//absl/base",
+ "//absl/base:config",
"//absl/base:core_headers",
],
)
@@ -184,6 +205,7 @@
deps = [
":demangle_internal",
":stack_consumption",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
"//absl/memory",
@@ -196,7 +218,10 @@
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
@@ -207,13 +232,14 @@
srcs = ["leak_check_disable.cc"],
linkopts = ABSL_DEFAULT_LINKOPTS,
linkstatic = 1,
+ deps = ["//absl/base:config"],
alwayslink = 1,
)
# These targets exists for use in tests only, explicitly configuring the
# LEAK_SANITIZER macro. It must be linked with -fsanitize=leak for lsan.
ABSL_LSAN_LINKOPTS = select({
- "//absl:llvm_compiler": ["-fsanitize=leak"],
+ "//absl:clang_compiler": ["-fsanitize=leak"],
"//conditions:default": [],
})
@@ -223,11 +249,14 @@
srcs = ["leak_check.cc"],
hdrs = ["leak_check.h"],
copts = select({
- "//absl:llvm_compiler": ["-DLEAK_SANITIZER"],
+ "//absl:clang_compiler": ["-DLEAK_SANITIZER"],
"//conditions:default": [],
}),
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = ["//visibility:private"],
+ deps = [
+ "//absl/base:config",
+ ],
)
cc_library(
@@ -238,13 +267,16 @@
copts = ["-ULEAK_SANITIZER"],
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = ["//visibility:private"],
+ deps = [
+ "//absl/base:config",
+ ],
)
cc_test(
name = "leak_check_test",
srcs = ["leak_check_test.cc"],
copts = select({
- "//absl:llvm_compiler": ["-DABSL_EXPECT_LEAK_SANITIZER"],
+ "//absl:clang_compiler": ["-DABSL_EXPECT_LEAK_SANITIZER"],
"//conditions:default": [],
}),
linkopts = ABSL_LSAN_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
@@ -295,6 +327,7 @@
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = ["//visibility:private"],
deps = [
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
],
diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt
index c409e33..074b44c 100644
--- a/absl/debugging/CMakeLists.txt
+++ b/absl/debugging/CMakeLists.txt
@@ -19,12 +19,21 @@
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::config
absl::core_headers
PUBLIC
)
@@ -37,6 +46,7 @@
"internal/symbolize.h"
SRCS
"symbolize.cc"
+ "symbolize_darwin.inc"
"symbolize_elf.inc"
"symbolize_unimplemented.inc"
"symbolize_win32.inc"
@@ -44,14 +54,17 @@
${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
+ absl::strings
PUBLIC
)
@@ -62,13 +75,18 @@
"symbolize_test.cc"
COPTS
${ABSL_TEST_COPTS}
+ $<$<BOOL:${MSVC}>:-Z7>
+ LINKOPTS
+ $<$<BOOL:${MSVC}>:-DEBUG>
DEPS
absl::stack_consumption
absl::symbolize
absl::base
+ absl::config
absl::core_headers
absl::memory
absl::raw_logging_internal
+ absl::strings
gmock
)
@@ -84,6 +102,7 @@
DEPS
absl::stacktrace
absl::symbolize
+ absl::config
absl::core_headers
absl::raw_logging_internal
)
@@ -103,6 +122,7 @@
absl::base
absl::config
absl::core_headers
+ absl::errno_saver
absl::raw_logging_internal
PUBLIC
)
@@ -130,14 +150,6 @@
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"
@@ -147,7 +159,9 @@
${ABSL_DEFAULT_COPTS}
DEPS
absl::core_headers
+ absl::config
absl::dynamic_annotations
+ absl::errno_saver
absl::raw_logging_internal
)
@@ -176,6 +190,7 @@
DEPS
absl::demangle_internal
absl::stack_consumption
+ absl::config
absl::core_headers
absl::memory
absl::raw_logging_internal
@@ -192,6 +207,7 @@
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
+ absl::config
absl::core_headers
PUBLIC
)
@@ -238,7 +254,7 @@
SRCS
"leak_check_test.cc"
COPTS
- ${ABSL_DEFAULT_COPTS}
+ ${ABSL_TEST_COPTS}
"$<$<BOOL:${ABSL_HAVE_LSAN}>:-DABSL_EXPECT_LEAK_SANITIZER>"
LINKOPTS
"${ABSL_LSAN_LINKOPTS}"
@@ -289,6 +305,7 @@
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
+ absl::config
absl::core_headers
absl::raw_logging_internal
TESTONLY
diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc
index c6a4d96..5d13bdb 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,9 +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 {
+ABSL_NAMESPACE_BEGIN
ABSL_CONST_INIT static FailureSignalHandlerOptions fsh_options;
@@ -116,7 +127,7 @@
} // namespace debugging_internal
-#ifndef _WIN32
+#ifdef ABSL_HAVE_SIGALTSTACK
static bool SetupAlternateStackOnce() {
#if defined(__wasm__) || defined (__asjms__)
@@ -125,8 +136,8 @@
const size_t page_mask = sysconf(_SC_PAGESIZE) - 1;
#endif
size_t stack_size = (std::max(SIGSTKSZ, 65536) + page_mask) & ~page_mask;
-#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
- defined(THREAD_SANITIZER)
+#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
+ defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
// Account for sanitizer instrumentation requiring additional stack space.
stack_size *= 5;
#endif
@@ -168,7 +179,7 @@
// 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
@@ -204,9 +215,8 @@
#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*)) {
@@ -356,4 +366,5 @@
}
}
+ABSL_NAMESPACE_END
} // namespace absl
diff --git a/absl/debugging/failure_signal_handler.h b/absl/debugging/failure_signal_handler.h
index 1beb78b..0c0f585 100644
--- a/absl/debugging/failure_signal_handler.h
+++ b/absl/debugging/failure_signal_handler.h
@@ -44,7 +44,10 @@
#ifndef ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_
#define ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_
+#include "absl/base/config.h"
+
namespace absl {
+ABSL_NAMESPACE_BEGIN
// FailureSignalHandlerOptions
//
@@ -85,7 +88,7 @@
bool call_previous_handler = false;
// If non-null, indicates a pointer to a callback function that will be called
- // upon failure, with a std::string argument containing failure data. This function
+ // upon failure, with a string argument containing failure data. This function
// may be used as a hook to write failure data to a secondary location, such
// as a log file. This function may also be called with null data, as a hint
// to flush any buffered data before the program may be terminated. Consider
@@ -112,6 +115,7 @@
const char* FailureSignalToString(int signo);
} // namespace debugging_internal
+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 bb2cc48..d8283b2 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.
@@ -52,7 +55,7 @@
exit_regex);
#else
// Windows doesn't have testing::KilledBySignal().
- EXPECT_DEATH(InstallHandlerAndRaise(signo), exit_regex);
+ EXPECT_DEATH_IF_SUPPORTED(InstallHandlerAndRaise(signo), exit_regex);
#endif
}
@@ -104,8 +107,8 @@
testing::KilledBySignal(signo), exit_regex);
#else
// Windows doesn't have testing::KilledBySignal().
- EXPECT_DEATH(InstallHandlerWithWriteToFileAndRaise(file.c_str(), signo),
- exit_regex);
+ EXPECT_DEATH_IF_SUPPORTED(
+ InstallHandlerWithWriteToFileAndRaise(file.c_str(), signo), exit_regex);
#endif
// Open the file in this process and check its contents.
@@ -113,15 +116,15 @@
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 99c4c64..329c285 100644
--- a/absl/debugging/internal/address_is_readable.cc
+++ b/absl/debugging/internal/address_is_readable.cc
@@ -20,12 +20,14 @@
#if !defined(__linux__) || defined(__ANDROID__)
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
// On platforms other than Linux, just return true.
bool AddressIsReadable(const void* /* addr */) { return true; }
} // namespace debugging_internal
+ABSL_NAMESPACE_END
} // namespace absl
#else
@@ -33,13 +35,16 @@
#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 {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
// Pack a pid and two file descriptors into a 64-bit word,
@@ -63,8 +68,9 @@
// 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) {
- 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
@@ -81,7 +87,7 @@
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];
@@ -93,13 +99,13 @@
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);
}
@@ -119,15 +125,15 @@
// 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);
- errno = save_errno;
return bytes_written == 1;
}
} // namespace debugging_internal
+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 ca8003e..4bbaf4d 100644
--- a/absl/debugging/internal/address_is_readable.h
+++ b/absl/debugging/internal/address_is_readable.h
@@ -15,7 +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 {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
// Return whether the byte at *addr is readable, without faulting.
@@ -23,6 +26,7 @@
bool AddressIsReadable(const void *addr);
} // namespace debugging_internal
+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 52a553f..46cdb67 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -24,6 +24,7 @@
#include <limits>
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
typedef struct {
@@ -93,6 +94,8 @@
};
// 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},
@@ -115,6 +118,17 @@
{"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},
+ {"Du", "char8_t", 0},
+ {"Ds", "char16_t", 0},
+ {"Dh", "float16", 0}, // IEEE 754r half-precision float (16 bits)
{nullptr, nullptr, 0},
};
@@ -138,7 +152,7 @@
// frame, so every byte counts.
typedef struct {
int mangled_idx; // Cursor of mangled name.
- int out_cur_idx; // Cursor of output std::string.
+ int out_cur_idx; // Cursor of output string.
int prev_name_idx; // For constructors/destructors.
signed int prev_name_length : 16; // For constructors/destructors.
signed int nest_level : 15; // For nested names.
@@ -159,8 +173,8 @@
// Only one copy of this exists for each call to Demangle, so the size of this
// struct is nearly inconsequential.
typedef struct {
- const char *mangled_begin; // Beginning of input std::string.
- char *out; // Beginning of output std::string.
+ const char *mangled_begin; // Beginning of input string.
+ char *out; // Beginning of output string.
int out_end_idx; // One past last allowed output character.
int recursion_depth; // For stack exhaustion prevention.
int steps; // Cap how much work we'll do, regardless of depth.
@@ -396,6 +410,7 @@
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];
}
@@ -408,8 +423,10 @@
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;
}
@@ -949,6 +966,7 @@
// ::= 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>
@@ -967,7 +985,7 @@
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;
}
@@ -1064,20 +1082,28 @@
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;
@@ -1126,6 +1152,7 @@
// ::= <decltype>
// ::= <substitution>
// ::= Dp <type> # pack expansion of (C++0x)
+// ::= Dv <num-elems> _ # GNU vector extension
//
static bool ParseType(State *state) {
ComplexityGuard guard(state);
@@ -1168,12 +1195,6 @@
}
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;
@@ -1198,6 +1219,12 @@
return true;
}
+ if (ParseTwoCharToken(state, "Dv") && ParseNumber(state, nullptr) &&
+ ParseOneCharToken(state, '_')) {
+ return true;
+ }
+ state->parse_state = copy;
+
return false;
}
@@ -1214,16 +1241,26 @@
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;
}
}
@@ -1236,13 +1273,42 @@
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;
}
@@ -1870,8 +1936,10 @@
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
+ABSL_NAMESPACE_END
} // namespace absl
diff --git a/absl/debugging/internal/demangle.h b/absl/debugging/internal/demangle.h
index 81bb0df..c314d9b 100644
--- a/absl/debugging/internal/demangle.h
+++ b/absl/debugging/internal/demangle.h
@@ -53,7 +53,10 @@
#ifndef ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_
#define ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_
+#include "absl/base/config.h"
+
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
// Demangle `mangled`. On success, return true and write the
@@ -62,6 +65,7 @@
bool Demangle(const char *mangled, char *out, int out_size);
} // namespace debugging_internal
+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 a68ce32..0bed735 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -18,11 +18,13 @@
#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"
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
namespace {
@@ -81,9 +83,10 @@
// 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];
@@ -190,4 +193,5 @@
} // namespace
} // namespace debugging_internal
+ABSL_NAMESPACE_END
} // namespace absl
diff --git a/absl/debugging/internal/elf_mem_image.cc b/absl/debugging/internal/elf_mem_image.cc
index e7408bc..24cc013 100644
--- a/absl/debugging/internal/elf_mem_image.cc
+++ b/absl/debugging/internal/elf_mem_image.cc
@@ -38,6 +38,7 @@
#define VERSYM_VERSION 0x7fff
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
namespace {
@@ -375,6 +376,7 @@
}
} // namespace debugging_internal
+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 d84200d..46bfade 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,6 +41,7 @@
#include <link.h> // for ElfW
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
// An in-memory ELF image (may not exist on disk).
@@ -123,6 +126,7 @@
};
} // namespace debugging_internal
+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 1ebc788..6e5ff1f 100644
--- a/absl/debugging/internal/examine_stack.cc
+++ b/absl/debugging/internal/examine_stack.cc
@@ -20,6 +20,10 @@
#include <unistd.h>
#endif
+#ifdef __APPLE__
+#include <sys/ucontext.h>
+#endif
+
#include <csignal>
#include <cstdio>
@@ -30,6 +34,7 @@
#include "absl/debugging/symbolize.h"
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
// Returns the program counter from signal context, nullptr if
@@ -52,6 +57,8 @@
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__)
@@ -63,6 +70,32 @@
#error "Undefined Architecture."
#endif
}
+#elif defined(__APPLE__)
+ if (vuc != nullptr) {
+ ucontext_t* signal_ucontext = reinterpret_cast<ucontext_t*>(vuc);
+#if defined(__aarch64__)
+ return reinterpret_cast<void*>(
+ __darwin_arm_thread_state64_get_pc(signal_ucontext->uc_mcontext->__ss));
+#elif defined(__arm__)
+#if __DARWIN_UNIX03
+ return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->__ss.__pc);
+#else
+ return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->ss.pc);
+#endif
+#elif defined(__i386__)
+#if __DARWIN_UNIX03
+ return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->__ss.__eip);
+#else
+ return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->ss.eip);
+#endif
+#elif defined(__x86_64__)
+#if __DARWIN_UNIX03
+ return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->__ss.__rip);
+#else
+ return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->ss.rip);
+#endif
+#endif
+ }
#elif defined(__akaros__)
auto* ctx = reinterpret_cast<struct user_context*>(vuc);
return reinterpret_cast<void*>(get_user_ctx_pc(ctx));
@@ -150,4 +183,5 @@
}
} // namespace debugging_internal
+ABSL_NAMESPACE_END
} // namespace absl
diff --git a/absl/debugging/internal/examine_stack.h b/absl/debugging/internal/examine_stack.h
index 56c9763..3933691 100644
--- a/absl/debugging/internal/examine_stack.h
+++ b/absl/debugging/internal/examine_stack.h
@@ -17,7 +17,10 @@
#ifndef ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_
#define ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_
+#include "absl/base/config.h"
+
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
// Returns the program counter from signal context, or nullptr if
@@ -33,6 +36,7 @@
void (*writerfn)(const char*, void*), void* writerfn_arg);
} // namespace debugging_internal
+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 4b05f49..e3dd51c 100644
--- a/absl/debugging/internal/stack_consumption.cc
+++ b/absl/debugging/internal/stack_consumption.cc
@@ -27,6 +27,7 @@
#include "absl/base/internal/raw_logging.h"
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
namespace {
@@ -41,7 +42,8 @@
// 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
@@ -115,10 +117,11 @@
// 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");
@@ -152,6 +155,15 @@
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,
@@ -167,6 +179,7 @@
}
} // namespace debugging_internal
+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 b860a3c..2b5e715 100644
--- a/absl/debugging/internal/stack_consumption.h
+++ b/absl/debugging/internal/stack_consumption.h
@@ -18,15 +18,19 @@
#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
#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 {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
// Returns the stack consumption in bytes for the code exercised by
@@ -38,6 +42,7 @@
int GetSignalHandlerStackConsumption(void (*signal_handler)(int));
} // namespace debugging_internal
+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 68bfa12..80445bf 100644
--- a/absl/debugging/internal/stack_consumption_test.cc
+++ b/absl/debugging/internal/stack_consumption_test.cc
@@ -23,6 +23,7 @@
#include "absl/base/internal/raw_logging.h"
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
namespace {
@@ -43,6 +44,7 @@
} // namespace
} // namespace debugging_internal
+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 7ed6b3e..f4859d7 100644
--- a/absl/debugging/internal/stacktrace_aarch64-inl.inc
+++ b/absl/debugging/internal/stacktrace_aarch64-inl.inc
@@ -37,8 +37,11 @@
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.
@@ -74,6 +77,8 @@
// checks (the strictness of which is controlled by the boolean parameter
// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
template<bool STRICT_UNWINDING, bool WITH_CONTEXT>
+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack.
+ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack.
static void **NextStackFrame(void **old_frame_pointer, const void *uc) {
void **new_frame_pointer = reinterpret_cast<void**>(*old_frame_pointer);
bool check_frame_size = true;
@@ -123,6 +128,8 @@
}
template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack.
+ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack.
static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
const void *ucp, int *min_dropped_frames) {
#ifdef __GNUC__
@@ -180,11 +187,13 @@
}
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
bool StackTraceWorksForTest() {
return true;
}
} // namespace debugging_internal
+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 c840833..2a1bf2e 100644
--- a/absl/debugging/internal/stacktrace_arm-inl.inc
+++ b/absl/debugging/internal/stacktrace_arm-inl.inc
@@ -1,9 +1,18 @@
-// Copyright 2011 and onwards Google Inc.
-// All rights reserved.
+// Copyright 2017 The Abseil Authors.
//
-// Author: Doug Kwan
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
// This is inspired by Craig Silverstein's PowerPC stacktrace code.
-//
#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_ARM_INL_H_
#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_ARM_INL_H_
@@ -113,11 +122,13 @@
}
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
bool StackTraceWorksForTest() {
return false;
}
} // namespace debugging_internal
+ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_ARM_INL_H_
diff --git a/absl/debugging/internal/stacktrace_config.h b/absl/debugging/internal/stacktrace_config.h
index d4e8480..cca410d 100644
--- a/absl/debugging/internal/stacktrace_config.h
+++ b/absl/debugging/internal/stacktrace_config.h
@@ -21,6 +21,8 @@
#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_
#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_
+#include "absl/base/config.h"
+
#if defined(ABSL_STACKTRACE_INL_HEADER)
#error ABSL_STACKTRACE_INL_HEADER cannot be directly set
@@ -28,43 +30,51 @@
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_win32-inl.inc"
+#elif defined(__APPLE__)
+#ifdef ABSL_HAVE_THREAD_LOCAL
+// Thread local support required for UnwindImpl.
+#define ABSL_STACKTRACE_INL_HEADER \
+ "absl/debugging/internal/stacktrace_generic-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__)
+ "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
+ "absl/debugging/internal/stacktrace_generic-inl.inc"
+#endif
+#endif
-#else
+#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_
diff --git a/absl/debugging/internal/stacktrace_generic-inl.inc b/absl/debugging/internal/stacktrace_generic-inl.inc
index 81a49ef..b2792a1 100644
--- a/absl/debugging/internal/stacktrace_generic-inl.inc
+++ b/absl/debugging/internal/stacktrace_generic-inl.inc
@@ -1,7 +1,16 @@
-// Copyright 2000 - 2007 Google Inc.
-// All rights reserved.
+// Copyright 2017 The Abseil Authors.
//
-// Author: Sanjay Ghemawat
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
//
// Portable implementation - just use glibc
//
@@ -87,11 +96,13 @@
}
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
bool StackTraceWorksForTest() {
return true;
}
} // namespace debugging_internal
+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 3a070ee..2e7c2f4 100644
--- a/absl/debugging/internal/stacktrace_powerpc-inl.inc
+++ b/absl/debugging/internal/stacktrace_powerpc-inl.inc
@@ -236,11 +236,13 @@
}
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
bool StackTraceWorksForTest() {
return true;
}
} // namespace debugging_internal
+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 e256fdd..5b8fb19 100644
--- a/absl/debugging/internal/stacktrace_unimplemented-inl.inc
+++ b/absl/debugging/internal/stacktrace_unimplemented-inl.inc
@@ -12,11 +12,13 @@
}
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
bool StackTraceWorksForTest() {
return false;
}
} // namespace debugging_internal
+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 b46491f..1c666c8 100644
--- a/absl/debugging/internal/stacktrace_win32-inl.inc
+++ b/absl/debugging/internal/stacktrace_win32-inl.inc
@@ -46,15 +46,23 @@
OUT PVOID *backtrace,
OUT PULONG backtrace_hash);
+// It is not possible to load RtlCaptureStackBackTrace at static init time in
+// UWP. CaptureStackBackTrace is the public version of RtlCaptureStackBackTrace
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
+ !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn =
+ &::CaptureStackBackTrace;
+#else
// Load the function we need at static init time, where we don't have
// to worry about someone else holding the loader's lock.
static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn =
- (RtlCaptureStackBackTrace_Function*)
- GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace");
+ (RtlCaptureStackBackTrace_Function*)GetProcAddress(
+ GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace");
+#endif // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP
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,11 +81,13 @@
}
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
bool StackTraceWorksForTest() {
return false;
}
} // namespace debugging_internal
+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 9494441..bc320ff 100644
--- a/absl/debugging/internal/stacktrace_x86-inl.inc
+++ b/absl/debugging/internal/stacktrace_x86-inl.inc
@@ -173,6 +173,7 @@
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
@@ -201,6 +202,9 @@
} 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) {
@@ -330,11 +334,13 @@
}
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
bool StackTraceWorksForTest() {
return true;
}
} // namespace debugging_internal
+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 3e53789..4f26130 100644
--- a/absl/debugging/internal/symbolize.h
+++ b/absl/debugging/internal/symbolize.h
@@ -18,9 +18,14 @@
#ifndef ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_
#define ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_
+#ifdef __cplusplus
+
#include <cstddef>
#include <cstdint>
+#include "absl/base/config.h"
+#include "absl/strings/string_view.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,6 +38,7 @@
#include <string>
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
// Iterates over all sections, invoking callback on each with the section name
@@ -42,7 +48,7 @@
//
// This is not async-signal-safe.
bool ForEachSection(int fd,
- const std::function<bool(const std::string& name,
+ const std::function<bool(absl::string_view name,
const ElfW(Shdr) &)>& callback);
// Gets the section header for the given name, if it exists. Returns true on
@@ -51,11 +57,19 @@
ElfW(Shdr) *out);
} // namespace debugging_internal
+ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE
+#ifdef ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE
+#error ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE cannot be directly set
+#elif defined(__APPLE__)
+#define ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE 1
+#endif
+
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
struct SymbolDecoratorArgs {
@@ -104,19 +118,30 @@
// 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_
diff --git a/absl/debugging/internal/vdso_support.cc b/absl/debugging/internal/vdso_support.cc
index d13ef25..6be16d9 100644
--- a/absl/debugging/internal/vdso_support.cc
+++ b/absl/debugging/internal/vdso_support.cc
@@ -38,6 +38,7 @@
#endif
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
ABSL_CONST_INIT
@@ -75,15 +76,6 @@
}
#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.
@@ -174,19 +166,8 @@
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
#endif // ABSL_HAVE_VDSO_SUPPORT
diff --git a/absl/debugging/internal/vdso_support.h b/absl/debugging/internal/vdso_support.h
index 9895b48..6562c6c 100644
--- a/absl/debugging/internal/vdso_support.h
+++ b/absl/debugging/internal/vdso_support.h
@@ -53,6 +53,7 @@
#endif
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
// NOTE: this class may be used from within tcmalloc, and can not
@@ -149,6 +150,7 @@
int GetCPU();
} // namespace debugging_internal
+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 ffe3d1b..ff90495 100644
--- a/absl/debugging/leak_check.cc
+++ b/absl/debugging/leak_check.cc
@@ -21,12 +21,14 @@
#ifndef LEAK_SANITIZER
namespace absl {
+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() { }
+ABSL_NAMESPACE_END
} // namespace absl
#else
@@ -34,6 +36,7 @@
#include <sanitizer/lsan_interface.h>
namespace absl {
+ABSL_NAMESPACE_BEGIN
bool HaveLeakSanitizer() { return true; }
void DoIgnoreLeak(const void* ptr) { __lsan_ignore_object(ptr); }
void RegisterLivePointers(const void* ptr, size_t size) {
@@ -44,6 +47,7 @@
}
LeakCheckDisabler::LeakCheckDisabler() { __lsan_disable(); }
LeakCheckDisabler::~LeakCheckDisabler() { __lsan_enable(); }
+ABSL_NAMESPACE_END
} // namespace absl
#endif // LEAK_SANITIZER
diff --git a/absl/debugging/leak_check.h b/absl/debugging/leak_check.h
index 4d489c5..b66a81c 100644
--- a/absl/debugging/leak_check.h
+++ b/absl/debugging/leak_check.h
@@ -32,7 +32,10 @@
#include <cstddef>
+#include "absl/base/config.h"
+
namespace absl {
+ABSL_NAMESPACE_BEGIN
// HaveLeakSanitizer()
//
@@ -59,7 +62,8 @@
//
// If the passed `ptr` does not point to an actively allocated object at the
// time `IgnoreLeak()` is called, the call is a no-op; if it is actively
-// allocated, the object must not get deallocated later.
+// allocated, leak sanitizer will assume this object is referenced even if
+// there is no actual reference in user memory.
//
template <typename T>
T* IgnoreLeak(T* ptr) {
@@ -104,6 +108,7 @@
// `RegisterLivePointers()`, enabling leak checking of those pointers.
void UnRegisterLivePointers(const void* ptr, size_t size);
+ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_DEBUGGING_LEAK_CHECK_H_
diff --git a/absl/debugging/leak_check_fail_test.cc b/absl/debugging/leak_check_fail_test.cc
index 2887cea..c49b81a 100644
--- a/absl/debugging/leak_check_fail_test.cc
+++ b/absl/debugging/leak_check_fail_test.cc
@@ -25,7 +25,7 @@
// failed exit code.
char* foo = strdup("lsan should complain about this leaked string");
- ABSL_RAW_LOG(INFO, "Should detect leaked std::string %s", foo);
+ ABSL_RAW_LOG(INFO, "Should detect leaked string %s", foo);
}
TEST(LeakCheckTest, LeakMemoryAfterDisablerScope) {
@@ -34,7 +34,7 @@
// failed exit code.
{ absl::LeakCheckDisabler disabler; }
char* foo = strdup("lsan should also complain about this leaked string");
- ABSL_RAW_LOG(INFO, "Re-enabled leak detection.Should detect leaked std::string %s",
+ ABSL_RAW_LOG(INFO, "Re-enabled leak detection.Should detect leaked string %s",
foo);
}
diff --git a/absl/debugging/leak_check_test.cc b/absl/debugging/leak_check_test.cc
index 93a7edd..b5cc487 100644
--- a/absl/debugging/leak_check_test.cc
+++ b/absl/debugging/leak_check_test.cc
@@ -30,13 +30,13 @@
TEST(LeakCheckTest, IgnoreLeakSuppressesLeakedMemoryErrors) {
auto foo = absl::IgnoreLeak(new std::string("some ignored leaked string"));
- ABSL_RAW_LOG(INFO, "Ignoring leaked std::string %s", foo->c_str());
+ ABSL_RAW_LOG(INFO, "Ignoring leaked string %s", foo->c_str());
}
TEST(LeakCheckTest, LeakCheckDisablerIgnoresLeak) {
absl::LeakCheckDisabler disabler;
- auto foo = new std::string("some std::string leaked while checks are disabled");
- ABSL_RAW_LOG(INFO, "Ignoring leaked std::string %s", foo->c_str());
+ auto foo = new std::string("some string leaked while checks are disabled");
+ ABSL_RAW_LOG(INFO, "Ignoring leaked string %s", foo->c_str());
}
} // namespace
diff --git a/absl/debugging/stacktrace.cc b/absl/debugging/stacktrace.cc
index 9de8782..1f7c7d8 100644
--- a/absl/debugging/stacktrace.cc
+++ b/absl/debugging/stacktrace.cc
@@ -57,6 +57,7 @@
#endif
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace {
typedef int (*Unwinder)(void**, int*, int, int, const void*, int*);
@@ -135,4 +136,5 @@
return n;
}
+ABSL_NAMESPACE_END
} // namespace absl
diff --git a/absl/debugging/stacktrace.h b/absl/debugging/stacktrace.h
index 3fc1c03..0ec0ffd 100644
--- a/absl/debugging/stacktrace.h
+++ b/absl/debugging/stacktrace.h
@@ -31,15 +31,18 @@
#ifndef ABSL_DEBUGGING_STACKTRACE_H_
#define ABSL_DEBUGGING_STACKTRACE_H_
+#include "absl/base/config.h"
+
namespace absl {
+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:
//
@@ -54,8 +57,8 @@
// 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()
@@ -82,9 +85,10 @@
//
// 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
@@ -105,8 +109,9 @@
// 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:
@@ -131,9 +136,9 @@
//
// 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
@@ -220,6 +225,7 @@
// working.
extern bool StackTraceWorksForTest();
} // namespace debugging_internal
+ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_DEBUGGING_STACKTRACE_H_
diff --git a/absl/debugging/symbolize.cc b/absl/debugging/symbolize.cc
index 24e3a7f..5e4a25d 100644
--- a/absl/debugging/symbolize.cc
+++ b/absl/debugging/symbolize.cc
@@ -14,15 +14,23 @@
#include "absl/debugging/symbolize.h"
+#ifdef _WIN32
+#include <winapifamily.h>
+#if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) || \
+ WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+// UWP doesn't have access to win32 APIs.
+#define ABSL_INTERNAL_HAVE_SYMBOLIZE_WIN32
+#endif
+#endif
+
#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(ABSL_INTERNAL_HAVE_SYMBOLIZE_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"
+#elif defined(__APPLE__)
+#include "absl/debugging/symbolize_darwin.inc"
#else
#include "absl/debugging/symbolize_unimplemented.inc"
#endif
diff --git a/absl/debugging/symbolize.h b/absl/debugging/symbolize.h
index a73dbd9..43d93a8 100644
--- a/absl/debugging/symbolize.h
+++ b/absl/debugging/symbolize.h
@@ -55,6 +55,7 @@
#include "absl/debugging/internal/symbolize.h"
namespace absl {
+ABSL_NAMESPACE_BEGIN
// InitializeSymbolizer()
//
@@ -70,7 +71,7 @@
// // Now you can use the symbolizer
// }
void InitializeSymbolizer(const char* argv0);
-
+//
// Symbolize()
//
// Symbolizes a program counter (instruction pointer value) `pc` and, on
@@ -88,10 +89,11 @@
// 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);
+ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_DEBUGGING_SYMBOLIZE_H_
diff --git a/absl/debugging/symbolize_darwin.inc b/absl/debugging/symbolize_darwin.inc
new file mode 100644
index 0000000..443ce9e
--- /dev/null
+++ b/absl/debugging/symbolize_darwin.inc
@@ -0,0 +1,101 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <cxxabi.h>
+#include <execinfo.h>
+
+#include <algorithm>
+#include <cstring>
+
+#include "absl/base/internal/raw_logging.h"
+#include "absl/debugging/internal/demangle.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+void InitializeSymbolizer(const char*) {}
+
+namespace debugging_internal {
+namespace {
+
+static std::string GetSymbolString(absl::string_view backtrace_line) {
+ // Example Backtrace lines:
+ // 0 libimaging_shared.dylib 0x018c152a
+ // _ZNSt11_Deque_baseIN3nik7mediadb4PageESaIS2_EE17_M_initialize_mapEm + 3478
+ //
+ // or
+ // 0 libimaging_shared.dylib 0x0000000001895c39
+ // _ZN3nik4util19register_shared_ptrINS_3gpu7TextureEEEvPKvS5_ + 39
+ //
+ // or
+ // 0 mysterious_app 0x0124000120120009 main + 17
+ auto address_pos = backtrace_line.find(" 0x");
+ if (address_pos == absl::string_view::npos) return std::string();
+ absl::string_view symbol_view = backtrace_line.substr(address_pos + 1);
+
+ auto space_pos = symbol_view.find(" ");
+ if (space_pos == absl::string_view::npos) return std::string();
+ symbol_view = symbol_view.substr(space_pos + 1); // to mangled symbol
+
+ auto plus_pos = symbol_view.find(" + ");
+ if (plus_pos == absl::string_view::npos) return std::string();
+ symbol_view = symbol_view.substr(0, plus_pos); // strip remainng
+
+ return std::string(symbol_view);
+}
+
+} // namespace
+} // namespace debugging_internal
+
+bool Symbolize(const void* pc, char* out, int out_size) {
+ if (out_size <= 0 || pc == nullptr) {
+ out = nullptr;
+ return false;
+ }
+
+ // This allocates a char* array.
+ char** frame_strings = backtrace_symbols(const_cast<void**>(&pc), 1);
+
+ if (frame_strings == nullptr) return false;
+
+ std::string symbol = debugging_internal::GetSymbolString(frame_strings[0]);
+ free(frame_strings);
+
+ char tmp_buf[1024];
+ if (debugging_internal::Demangle(symbol.c_str(), tmp_buf, sizeof(tmp_buf))) {
+ size_t len = strlen(tmp_buf);
+ if (len + 1 <= static_cast<size_t>(out_size)) { // +1 for '\0'
+ assert(len < sizeof(tmp_buf));
+ memmove(out, tmp_buf, len + 1);
+ }
+ } else {
+ strncpy(out, symbol.c_str(), out_size);
+ }
+
+ if (out[out_size - 1] != '\0') {
+ // strncpy() does not '\0' terminate when it truncates.
+ static constexpr char kEllipsis[] = "...";
+ int ellipsis_size = std::min<int>(sizeof(kEllipsis) - 1, out_size - 1);
+ memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size);
+ out[out_size - 1] = '\0';
+ }
+
+ return true;
+}
+
+ABSL_NAMESPACE_END
+} // namespace absl
diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc
index 14f0c97..f4d5727 100644
--- a/absl/debugging/symbolize_elf.inc
+++ b/absl/debugging/symbolize_elf.inc
@@ -57,6 +57,7 @@
#include <unistd.h>
#include <algorithm>
+#include <array>
#include <atomic>
#include <cerrno>
#include <cinttypes>
@@ -74,13 +75,21 @@
#include "absl/base/port.h"
#include "absl/debugging/internal/demangle.h"
#include "absl/debugging/internal/vdso_support.h"
+#include "absl/strings/string_view.h"
namespace absl {
+ABSL_NAMESPACE_BEGIN
// Value of argv[0]. Used by MaybeInitializeObjFile().
static char *argv0_value = nullptr;
void InitializeSymbolizer(const char *argv0) {
+#ifdef ABSL_HAVE_VDSO_SUPPORT
+ // We need to make sure VDSOSupport::Init() is called before any setuid or
+ // chroot calls, so InitializeSymbolizer() should be called very early in the
+ // life of a program.
+ absl::debugging_internal::VDSOSupport::Init();
+#endif
if (argv0_value != nullptr) {
free(argv0_value);
argv0_value = nullptr;
@@ -148,13 +157,15 @@
// Moreover, we are using only TryLock(), if the decorator list
// is being modified (is busy), we skip all decorators, and possibly
// loose some info. Sorry, that's the best we could do.
-base_internal::SpinLock g_decorators_mu(base_internal::kLinkerInitialized);
+ABSL_CONST_INIT absl::base_internal::SpinLock g_decorators_mu(
+ absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY);
const int kMaxFileMappingHints = 8;
int g_num_file_mapping_hints;
FileMappingHint g_file_mapping_hints[kMaxFileMappingHints];
// Protects g_file_mapping_hints.
-base_internal::SpinLock g_file_mapping_mu(base_internal::kLinkerInitialized);
+ABSL_CONST_INIT absl::base_internal::SpinLock g_file_mapping_mu(
+ absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY);
// Async-signal-safe function to zero a buffer.
// memset() is not guaranteed to be async-signal-safe.
@@ -174,6 +185,7 @@
fd(-1),
elf_type(-1) {
SafeMemZero(&elf_header, sizeof(elf_header));
+ SafeMemZero(&phdr[0], sizeof(phdr));
}
char *filename;
@@ -186,6 +198,10 @@
int fd;
int elf_type;
ElfW(Ehdr) elf_header;
+
+ // PT_LOAD program header describing executable code.
+ // Normally we expect just one, but SWIFT binaries have two.
+ std::array<ElfW(Phdr), 2> phdr;
};
// Build 4-way associative cache for symbols. Within each cache line, symbols
@@ -495,7 +511,7 @@
const int kMaxSectionNameLen = 64;
bool ForEachSection(int fd,
- const std::function<bool(const std::string &name,
+ const std::function<bool(absl::string_view name,
const ElfW(Shdr) &)> &callback) {
ElfW(Ehdr) elf_header;
if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
@@ -517,7 +533,7 @@
return false;
}
off_t name_offset = shstrtab.sh_offset + out.sh_name;
- char header_name[kMaxSectionNameLen + 1];
+ char header_name[kMaxSectionNameLen];
ssize_t n_read =
ReadFromOffset(fd, &header_name, kMaxSectionNameLen, name_offset);
if (n_read == -1) {
@@ -526,9 +542,8 @@
// Long read?
return false;
}
- header_name[n_read] = '\0';
- std::string name(header_name);
+ absl::string_view name(header_name, strnlen(header_name, n_read));
if (!callback(name, out)) {
break;
}
@@ -1263,6 +1278,36 @@
ABSL_RAW_LOG(WARNING, "%s: failed to read elf header", obj->filename);
return false;
}
+ const int phnum = obj->elf_header.e_phnum;
+ const int phentsize = obj->elf_header.e_phentsize;
+ size_t phoff = obj->elf_header.e_phoff;
+ size_t num_executable_load_segments = 0;
+ for (int j = 0; j < phnum; j++) {
+ ElfW(Phdr) phdr;
+ if (!ReadFromOffsetExact(obj->fd, &phdr, sizeof(phdr), phoff)) {
+ ABSL_RAW_LOG(WARNING, "%s: failed to read program header %d",
+ obj->filename, j);
+ return false;
+ }
+ phoff += phentsize;
+ constexpr int rx = PF_X | PF_R;
+ if (phdr.p_type != PT_LOAD || (phdr.p_flags & rx) != rx) {
+ // Not a LOAD segment, or not executable code.
+ continue;
+ }
+ if (num_executable_load_segments < obj->phdr.size()) {
+ memcpy(&obj->phdr[num_executable_load_segments++], &phdr, sizeof(phdr));
+ } else {
+ ABSL_RAW_LOG(WARNING, "%s: too many executable LOAD segments",
+ obj->filename);
+ break;
+ }
+ }
+ if (num_executable_load_segments == 0) {
+ // This object has no "r-x" LOAD segments. That's unexpected.
+ ABSL_RAW_LOG(WARNING, "%s: no executable LOAD segments", obj->filename);
+ return false;
+ }
}
return true;
}
@@ -1286,23 +1331,52 @@
int fd = -1;
if (obj != nullptr) {
if (MaybeInitializeObjFile(obj)) {
- if (obj->elf_type == ET_DYN &&
- reinterpret_cast<uint64_t>(obj->start_addr) >= obj->offset) {
+ const size_t start_addr = reinterpret_cast<size_t>(obj->start_addr);
+ if (obj->elf_type == ET_DYN && start_addr >= obj->offset) {
// This object was relocated.
//
// For obj->offset > 0, adjust the relocation since a mapping at offset
// X in the file will have a start address of [true relocation]+X.
- relocation = reinterpret_cast<ptrdiff_t>(obj->start_addr) - obj->offset;
+ relocation = start_addr - obj->offset;
+
+ // Note: some binaries have multiple "rx" LOAD segments. We must
+ // find the right one.
+ ElfW(Phdr) *phdr = nullptr;
+ for (size_t j = 0; j < obj->phdr.size(); j++) {
+ ElfW(Phdr) &p = obj->phdr[j];
+ if (p.p_type != PT_LOAD) {
+ // We only expect PT_LOADs. This must be PT_NULL that we didn't
+ // write over (i.e. we exhausted all interesting PT_LOADs).
+ ABSL_RAW_CHECK(p.p_type == PT_NULL, "unexpected p_type");
+ break;
+ }
+ if (pc < reinterpret_cast<void *>(start_addr + p.p_memsz)) {
+ phdr = &p;
+ break;
+ }
+ }
+ if (phdr == nullptr) {
+ // That's unexpected. Hope for the best.
+ ABSL_RAW_LOG(
+ WARNING,
+ "%s: unable to find LOAD segment for pc: %p, start_addr: %zx",
+ obj->filename, pc, start_addr);
+ } else {
+ // Adjust relocation in case phdr.p_vaddr != 0.
+ // This happens for binaries linked with `lld --rosegment`, and for
+ // binaries linked with BFD `ld -z separate-code`.
+ relocation -= phdr->p_vaddr - phdr->p_offset;
+ }
}
fd = obj->fd;
- }
- if (GetSymbolFromObjectFile(*obj, pc, relocation, symbol_buf_,
- sizeof(symbol_buf_), tmp_buf_,
- sizeof(tmp_buf_)) == SYMBOL_FOUND) {
- // Only try to demangle the symbol name if it fit into symbol_buf_.
- DemangleInplace(symbol_buf_, sizeof(symbol_buf_), tmp_buf_,
- sizeof(tmp_buf_));
+ if (GetSymbolFromObjectFile(*obj, pc, relocation, symbol_buf_,
+ sizeof(symbol_buf_), tmp_buf_,
+ sizeof(tmp_buf_)) == SYMBOL_FOUND) {
+ // Only try to demangle the symbol name if it fit into symbol_buf_.
+ DemangleInplace(symbol_buf_, sizeof(symbol_buf_), tmp_buf_,
+ sizeof(tmp_buf_));
+ }
}
} else {
#if ABSL_HAVE_VDSO_SUPPORT
@@ -1373,7 +1447,7 @@
if (!g_decorators_mu.TryLock()) {
// Someone else is using decorators. Get out.
- return false;
+ return -2;
}
int ret = ticket;
if (g_num_decorators >= kMaxDecorators) {
@@ -1401,7 +1475,7 @@
if (g_num_file_mapping_hints >= kMaxFileMappingHints) {
ret = false;
} else {
- // TODO(ckennelly): Move this into a std::string copy routine.
+ // TODO(ckennelly): Move this into a string copy routine.
int len = strlen(filename);
char *dst = static_cast<char *>(
base_internal::LowLevelAlloc::AllocWithArena(len + 1, SigSafeArena()));
@@ -1452,7 +1526,7 @@
bool Symbolize(const void *pc, char *out, int out_size) {
// Symbolization is very slow under tsan.
- ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
+ ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
SAFE_ASSERT(out_size >= 0);
debugging_internal::Symbolizer *s = debugging_internal::AllocateSymbolizer();
const char *name = s->GetSymbol(pc);
@@ -1471,8 +1545,16 @@
}
}
debugging_internal::FreeSymbolizer(s);
- ANNOTATE_IGNORE_READS_AND_WRITES_END();
+ ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END();
return ok;
}
+ABSL_NAMESPACE_END
} // namespace absl
+
+extern "C" bool AbslInternalGetFileMappingHint(const void **start,
+ const void **end, uint64_t *offset,
+ const char **filename) {
+ return absl::debugging_internal::GetFileMappingHint(start, end, offset,
+ filename);
+}
diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc
index 08068c3..a2dd495 100644
--- a/absl/debugging/symbolize_test.cc
+++ b/absl/debugging/symbolize_test.cc
@@ -27,18 +27,39 @@
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
#include "absl/base/casts.h"
+#include "absl/base/config.h"
#include "absl/base/internal/per_thread_tls.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/optimization.h"
#include "absl/debugging/internal/stack_consumption.h"
#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
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 +67,11 @@
};
// 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 +105,7 @@
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 +115,7 @@
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];
@@ -119,7 +146,8 @@
return TrySymbolizeWithLimit(pc, sizeof(try_symbolize_buffer));
}
-#ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE
+#if defined(ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE) || \
+ defined(ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE)
TEST(Symbolize, Cached) {
// Compilers should give us pointers to them.
@@ -193,8 +221,8 @@
static int GetStackConsumptionUpperLimit() {
// Symbolize stack consumption should be within 2kB.
int stack_consumption_upper_limit = 2048;
-#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
- defined(THREAD_SANITIZER)
+#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
+ defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
// Account for sanitizer instrumentation requiring additional stack space.
stack_consumption_upper_limit *= 5;
#endif
@@ -233,6 +261,7 @@
#endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION
+#ifndef ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE
// Use a 64K page size for PPC.
const size_t kPageSize = 64 << 10;
// We place a read-only symbols into the .text section and verify that we can
@@ -374,8 +403,8 @@
std::vector<std::string> sections;
ASSERT_TRUE(absl::debugging_internal::ForEachSection(
- fd, [§ions](const std::string &name, const ElfW(Shdr) &) {
- sections.push_back(name);
+ fd, [§ions](const absl::string_view name, const ElfW(Shdr) &) {
+ sections.emplace_back(name);
return true;
}));
@@ -388,6 +417,7 @@
close(fd);
}
+#endif // !ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE
// x86 specific tests. Uses some inline assembler.
extern "C" {
@@ -447,14 +477,15 @@
#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 +512,12 @@
}
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 +530,12 @@
#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.
@@ -512,7 +546,8 @@
absl::InitializeSymbolizer(argv[0]);
testing::InitGoogleTest(&argc, argv);
-#ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE
+#if defined(ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE) || \
+ defined(ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE)
TestWithPCInsideInlineFunction();
TestWithPCInsideNonInlineFunction();
TestWithReturnAddress();
diff --git a/absl/debugging/symbolize_unimplemented.inc b/absl/debugging/symbolize_unimplemented.inc
index 7c580fe..db24456 100644
--- a/absl/debugging/symbolize_unimplemented.inc
+++ b/absl/debugging/symbolize_unimplemented.inc
@@ -17,6 +17,7 @@
#include "absl/base/internal/raw_logging.h"
namespace absl {
+ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
@@ -35,4 +36,5 @@
void InitializeSymbolizer(const char*) {}
bool Symbolize(const void *, char *, int) { return false; }
+ABSL_NAMESPACE_END
} // namespace absl
diff --git a/absl/debugging/symbolize_win32.inc b/absl/debugging/symbolize_win32.inc
index 5a55f29..c3df46f 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,10 +31,11 @@
#include "absl/base/internal/raw_logging.h"
namespace absl {
+ABSL_NAMESPACE_BEGIN
static HANDLE process = NULL;
-void InitializeSymbolizer(const char *argv0) {
+void InitializeSymbolizer(const char*) {
if (process != nullptr) {
return;
}
@@ -53,13 +54,12 @@
}
}
-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)) {
@@ -77,4 +77,5 @@
return true;
}
+ABSL_NAMESPACE_END
} // namespace absl