From 1fdbe1ea1b8c835c11ed6fbec4d4259ad104f765 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 23 Mar 2021 15:07:11 -0700 Subject: Export of internal Abseil changes -- 4b566a7deeba5db473c83f4924c1d182a002779f by Abseil Team : Add absl::LeakCheckerIsActive to check whether a leak checker is built into the target and enabled. For LeakSanitizer, it is by default enabled unless __lsan_is_turned_off() is defined and returns true. PiperOrigin-RevId: 364654465 -- 0a56ff5310b66f9d1ff5e5e2a053335ecfb5c75b by Abseil Team : Update absl::FromTM documentation to reflect implementation. PiperOrigin-RevId: 364388743 GitOrigin-RevId: 4b566a7deeba5db473c83f4924c1d182a002779f Change-Id: I8df35b761b532e79d620f484153083c3499ef55b --- absl/debugging/BUILD.bazel | 2 ++ absl/debugging/leak_check.cc | 15 +++++++++++++++ absl/debugging/leak_check.h | 6 ++++++ absl/debugging/leak_check_test.cc | 2 ++ absl/time/time.h | 14 +++++++++----- 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index e7fd1152..5385bcb6 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -260,6 +260,7 @@ cc_library( visibility = ["//visibility:private"], deps = [ "//absl/base:config", + "//absl/base:core_headers", ], ) @@ -273,6 +274,7 @@ cc_library( visibility = ["//visibility:private"], deps = [ "//absl/base:config", + "//absl/base:core_headers", ], ) diff --git a/absl/debugging/leak_check.cc b/absl/debugging/leak_check.cc index db9d5d09..764ca0ad 100644 --- a/absl/debugging/leak_check.cc +++ b/absl/debugging/leak_check.cc @@ -16,6 +16,7 @@ // When lsan is not linked in, these functions are not available, // therefore Abseil code which depends on these functions is conditioned on the // definition of LEAK_SANITIZER. +#include "absl/base/attributes.h" #include "absl/debugging/leak_check.h" #ifndef LEAK_SANITIZER @@ -23,6 +24,7 @@ namespace absl { ABSL_NAMESPACE_BEGIN bool HaveLeakSanitizer() { return false; } +bool LeakCheckerIsActive() { return false; } void DoIgnoreLeak(const void*) { } void RegisterLivePointers(const void*, size_t) { } void UnRegisterLivePointers(const void*, size_t) { } @@ -35,9 +37,22 @@ ABSL_NAMESPACE_END #include +#if ABSL_HAVE_ATTRIBUTE_WEAK +extern "C" ABSL_ATTRIBUTE_WEAK int __lsan_is_turned_off(); +#endif + namespace absl { ABSL_NAMESPACE_BEGIN bool HaveLeakSanitizer() { return true; } + +#if ABSL_HAVE_ATTRIBUTE_WEAK +bool LeakCheckerIsActive() { + return !(&__lsan_is_turned_off && __lsan_is_turned_off()); +} +#else +bool LeakCheckerIsActive() { return true; } +#endif + bool FindAndReportLeaks() { return __lsan_do_recoverable_leak_check(); } void DoIgnoreLeak(const void* ptr) { __lsan_ignore_object(ptr); } void RegisterLivePointers(const void* ptr, size_t size) { diff --git a/absl/debugging/leak_check.h b/absl/debugging/leak_check.h index 61c3216f..5fc2b052 100644 --- a/absl/debugging/leak_check.h +++ b/absl/debugging/leak_check.h @@ -43,6 +43,12 @@ ABSL_NAMESPACE_BEGIN // currently built into this target. bool HaveLeakSanitizer(); +// LeakCheckerIsActive() +// +// Returns true if a leak-checking sanitizer (either ASan or standalone LSan) is +// currently built into this target and is turned on. +bool LeakCheckerIsActive(); + // DoIgnoreLeak() // // Implements `IgnoreLeak()` below. This function should usually diff --git a/absl/debugging/leak_check_test.cc b/absl/debugging/leak_check_test.cc index b5cc4874..9fcfc8e5 100644 --- a/absl/debugging/leak_check_test.cc +++ b/absl/debugging/leak_check_test.cc @@ -23,8 +23,10 @@ namespace { TEST(LeakCheckTest, DetectLeakSanitizer) { #ifdef ABSL_EXPECT_LEAK_SANITIZER EXPECT_TRUE(absl::HaveLeakSanitizer()); + EXPECT_TRUE(absl::LeakCheckerIsActive()); #else EXPECT_FALSE(absl::HaveLeakSanitizer()); + EXPECT_FALSE(absl::LeakCheckerIsActive()); #endif } diff --git a/absl/time/time.h b/absl/time/time.h index d9ad1aed..2df68581 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -1180,11 +1180,15 @@ inline Time FromDateTime(int64_t year, int mon, int day, int hour, // // Converts the `tm_year`, `tm_mon`, `tm_mday`, `tm_hour`, `tm_min`, and // `tm_sec` fields to an `absl::Time` using the given time zone. See ctime(3) -// for a description of the expected values of the tm fields. If the indicated -// time instant is not unique (see `absl::TimeZone::At(absl::CivilSecond)` -// above), the `tm_isdst` field is consulted to select the desired instant -// (`tm_isdst` > 0 means DST, `tm_isdst` == 0 means no DST, `tm_isdst` < 0 -// means use the post-transition offset). +// for a description of the expected values of the tm fields. If the civil time +// is unique (see `absl::TimeZone::At(absl::CivilSecond)` above), the matching +// time instant is returned. Otherwise, the `tm_isdst` field is consulted to +// choose between the possible results. For a repeated civil time, `tm_isdst != +// 0` returns the matching DST instant, while `tm_isdst == 0` returns the +// matching non-DST instant. For a skipped civil time there is no matching +// instant, so `tm_isdst != 0` returns the DST instant, and `tm_isdst == 0` +// returns the non-DST instant, that would have matched if the transition never +// happened. Time FromTM(const struct tm& tm, TimeZone tz); // ToTM() -- cgit v1.2.3