aboutsummaryrefslogtreecommitdiff
path: root/lib/lsan
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-12-30 11:52:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-12-30 11:52:19 +0000
commit5c909fa013fc285f010a95e8d387e0ef3412da9c (patch)
tree1059d068ad281f4776ff44cd414574f99a460023 /lib/lsan
parentf31bcc68c72371a2bf63aead9f3373a1ff2053b6 (diff)
downloadsrc-5c909fa013fc285f010a95e8d387e0ef3412da9c.tar.gz
src-5c909fa013fc285f010a95e8d387e0ef3412da9c.zip
Vendor import of compiler-rt trunk r256633:vendor/compiler-rt/compiler-rt-trunk-r256633
Notes
Notes: svn path=/vendor/compiler-rt/dist/; revision=292925 svn path=/vendor/compiler-rt/compiler-rt-trunk-r256633/; revision=292926; tag=vendor/compiler-rt/compiler-rt-trunk-r256633
Diffstat (limited to 'lib/lsan')
-rw-r--r--lib/lsan/.clang-format1
-rw-r--r--lib/lsan/CMakeLists.txt8
-rw-r--r--lib/lsan/lsan.cc2
-rw-r--r--lib/lsan/lsan_allocator.cc14
-rw-r--r--lib/lsan/lsan_common.cc39
-rw-r--r--lib/lsan/lsan_common.h4
-rw-r--r--lib/lsan/lsan_common_linux.cc9
-rw-r--r--lib/lsan/lsan_flags.inc2
-rw-r--r--lib/lsan/lsan_interceptors.cc10
-rw-r--r--lib/lsan/lsan_thread.cc10
10 files changed, 53 insertions, 46 deletions
diff --git a/lib/lsan/.clang-format b/lib/lsan/.clang-format
new file mode 100644
index 000000000000..f6cb8ad931f5
--- /dev/null
+++ b/lib/lsan/.clang-format
@@ -0,0 +1 @@
+BasedOnStyle: Google
diff --git a/lib/lsan/CMakeLists.txt b/lib/lsan/CMakeLists.txt
index 37f794e2e11b..20e40932165c 100644
--- a/lib/lsan/CMakeLists.txt
+++ b/lib/lsan/CMakeLists.txt
@@ -26,14 +26,16 @@ add_compiler_rt_object_libraries(RTLSanCommon
if(COMPILER_RT_HAS_LSAN)
foreach(arch ${LSAN_SUPPORTED_ARCH})
- add_compiler_rt_runtime(clang_rt.lsan-${arch} ${arch} STATIC
+ add_compiler_rt_runtime(clang_rt.lsan
+ STATIC
+ ARCHS ${arch}
SOURCES ${LSAN_SOURCES}
$<TARGET_OBJECTS:RTInterception.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTLSanCommon.${arch}>
- CFLAGS ${LSAN_CFLAGS})
- add_dependencies(lsan clang_rt.lsan-${arch})
+ CFLAGS ${LSAN_CFLAGS}
+ PARENT_TARGET lsan)
endforeach()
endif()
diff --git a/lib/lsan/lsan.cc b/lib/lsan/lsan.cc
index 6018f7bf6f49..f3e6ad7c9cba 100644
--- a/lib/lsan/lsan.cc
+++ b/lib/lsan/lsan.cc
@@ -44,6 +44,7 @@ static void InitializeFlags() {
cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
cf.malloc_context_size = 30;
cf.detect_leaks = true;
+ cf.exitcode = 23;
OverrideCommonFlags(cf);
}
@@ -69,6 +70,7 @@ extern "C" void __lsan_init() {
return;
lsan_init_is_running = true;
SanitizerToolName = "LeakSanitizer";
+ CacheBinaryName();
InitializeFlags();
InitCommonLsan();
InitializeAllocator();
diff --git a/lib/lsan/lsan_allocator.cc b/lib/lsan/lsan_allocator.cc
index 67125dbb3e45..0a3678132ae1 100644
--- a/lib/lsan/lsan_allocator.cc
+++ b/lib/lsan/lsan_allocator.cc
@@ -26,13 +26,13 @@ extern "C" void *memset(void *ptr, int value, uptr num);
namespace __lsan {
struct ChunkMetadata {
- bool allocated : 8; // Must be first.
+ u8 allocated : 8; // Must be first.
ChunkTag tag : 2;
uptr requested_size : 54;
u32 stack_trace_id;
};
-#if defined(__mips64)
+#if defined(__mips64) || defined(__aarch64__)
static const uptr kMaxAllowedMallocSize = 4UL << 30;
static const uptr kRegionSizeLog = 20;
static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
@@ -91,7 +91,7 @@ void *Allocate(const StackTrace &stack, uptr size, uptr alignment,
size = 1;
if (size > kMaxAllowedMallocSize) {
Report("WARNING: LeakSanitizer failed to allocate %zu bytes\n", size);
- return 0;
+ return nullptr;
}
void *p = allocator.Allocate(&cache, size, alignment, false);
// Do not rely on the allocator to clear the memory (it's slow).
@@ -114,7 +114,7 @@ void *Reallocate(const StackTrace &stack, void *p, uptr new_size,
if (new_size > kMaxAllowedMallocSize) {
Report("WARNING: LeakSanitizer failed to allocate %zu bytes\n", new_size);
allocator.Deallocate(&cache, p);
- return 0;
+ return nullptr;
}
p = allocator.Reallocate(&cache, p, new_size, alignment);
RegisterAllocation(stack, p, new_size);
@@ -212,7 +212,7 @@ IgnoreObjectResult IgnoreObjectLocked(const void *p) {
return kIgnoreObjectInvalid;
}
}
-} // namespace __lsan
+} // namespace __lsan
using namespace __lsan;
@@ -241,10 +241,10 @@ SANITIZER_INTERFACE_ATTRIBUTE
uptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; }
SANITIZER_INTERFACE_ATTRIBUTE
-int __sanitizer_get_ownership(const void *p) { return Metadata(p) != 0; }
+int __sanitizer_get_ownership(const void *p) { return Metadata(p) != nullptr; }
SANITIZER_INTERFACE_ATTRIBUTE
uptr __sanitizer_get_allocated_size(const void *p) {
return GetMallocUsableSize(p);
}
-} // extern "C"
+} // extern "C"
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc
index 0ffba505cc70..1cffac44395c 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cc
@@ -119,6 +119,10 @@ static inline bool CanBeAHeapPointer(uptr p) {
return ((p >> 47) == 0);
#elif defined(__mips64)
return ((p >> 40) == 0);
+#elif defined(__aarch64__)
+ unsigned runtimeVMA =
+ (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);
+ return ((p >> runtimeVMA) == 0);
#else
return true;
#endif
@@ -243,8 +247,8 @@ static void ProcessRootRegion(Frontier *frontier, uptr root_begin,
MemoryMappingLayout proc_maps(/*cache_enabled*/true);
uptr begin, end, prot;
while (proc_maps.Next(&begin, &end,
- /*offset*/ 0, /*filename*/ 0, /*filename_size*/ 0,
- &prot)) {
+ /*offset*/ nullptr, /*filename*/ nullptr,
+ /*filename_size*/ 0, &prot)) {
uptr intersection_begin = Max(root_begin, begin);
uptr intersection_end = Min(end, root_end);
if (intersection_begin >= intersection_end) continue;
@@ -375,8 +379,8 @@ static void PrintMatchedSuppressions() {
Printf("Suppressions used:\n");
Printf(" count bytes template\n");
for (uptr i = 0; i < matched.size(); i++)
- Printf("%7zu %10zu %s\n", static_cast<uptr>(matched[i]->hit_count),
- matched[i]->weight, matched[i]->templ);
+ Printf("%7zu %10zu %s\n", static_cast<uptr>(atomic_load_relaxed(
+ &matched[i]->hit_count)), matched[i]->weight, matched[i]->templ);
Printf("%s\n\n", line);
}
@@ -444,10 +448,8 @@ void DoLeakCheck() {
if (!have_leaks) {
return;
}
- if (flags()->exitcode) {
- if (common_flags()->coverage)
- __sanitizer_cov_dump();
- internal__exit(flags()->exitcode);
+ if (common_flags()->exitcode) {
+ Die();
}
}
@@ -486,7 +488,7 @@ static Suppression *GetSuppressionForStack(u32 stack_trace_id) {
StackTrace::GetPreviousInstructionPc(stack.trace[i]));
if (s) return s;
}
- return 0;
+ return nullptr;
}
///// LeakReport implementation. /////
@@ -600,7 +602,8 @@ void LeakReport::ApplySuppressions() {
Suppression *s = GetSuppressionForStack(leaks_[i].stack_trace_id);
if (s) {
s->weight += leaks_[i].total_size;
- s->hit_count += leaks_[i].hit_count;
+ atomic_store_relaxed(&s->hit_count, atomic_load_relaxed(&s->hit_count) +
+ leaks_[i].hit_count);
leaks_[i].is_suppressed = true;
}
}
@@ -613,8 +616,8 @@ uptr LeakReport::UnsuppressedLeakCount() {
return result;
}
-} // namespace __lsan
-#endif // CAN_SANITIZE_LEAKS
+} // namespace __lsan
+#endif // CAN_SANITIZE_LEAKS
using namespace __lsan; // NOLINT
@@ -635,7 +638,7 @@ void __lsan_ignore_object(const void *p) {
"heap object at %p is already being ignored\n", p);
if (res == kIgnoreObjectSuccess)
VReport(1, "__lsan_ignore_object(): ignoring heap object at %p\n", p);
-#endif // CAN_SANITIZE_LEAKS
+#endif // CAN_SANITIZE_LEAKS
}
SANITIZER_INTERFACE_ATTRIBUTE
@@ -646,7 +649,7 @@ void __lsan_register_root_region(const void *begin, uptr size) {
RootRegion region = {begin, size};
root_regions->push_back(region);
VReport(1, "Registered root region at %p of size %llu\n", begin, size);
-#endif // CAN_SANITIZE_LEAKS
+#endif // CAN_SANITIZE_LEAKS
}
SANITIZER_INTERFACE_ATTRIBUTE
@@ -673,7 +676,7 @@ void __lsan_unregister_root_region(const void *begin, uptr size) {
begin, size);
Die();
}
-#endif // CAN_SANITIZE_LEAKS
+#endif // CAN_SANITIZE_LEAKS
}
SANITIZER_INTERFACE_ATTRIBUTE
@@ -699,7 +702,7 @@ void __lsan_do_leak_check() {
#if CAN_SANITIZE_LEAKS
if (common_flags()->detect_leaks)
__lsan::DoLeakCheck();
-#endif // CAN_SANITIZE_LEAKS
+#endif // CAN_SANITIZE_LEAKS
}
SANITIZER_INTERFACE_ATTRIBUTE
@@ -707,7 +710,7 @@ int __lsan_do_recoverable_leak_check() {
#if CAN_SANITIZE_LEAKS
if (common_flags()->detect_leaks)
return __lsan::DoRecoverableLeakCheck();
-#endif // CAN_SANITIZE_LEAKS
+#endif // CAN_SANITIZE_LEAKS
return 0;
}
@@ -717,4 +720,4 @@ int __lsan_is_turned_off() {
return 0;
}
#endif
-} // extern "C"
+} // extern "C"
diff --git a/lib/lsan/lsan_common.h b/lib/lsan/lsan_common.h
index 4f9d24fb3ab9..0dfd0d4c9890 100644
--- a/lib/lsan/lsan_common.h
+++ b/lib/lsan/lsan_common.h
@@ -22,8 +22,8 @@
#include "sanitizer_common/sanitizer_stoptheworld.h"
#include "sanitizer_common/sanitizer_symbolizer.h"
-#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips64)) \
- && (SANITIZER_WORDSIZE == 64)
+#if (SANITIZER_LINUX && !SANITIZER_ANDROID) && (SANITIZER_WORDSIZE == 64) \
+ && (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__))
#define CAN_SANITIZE_LEAKS 1
#else
#define CAN_SANITIZE_LEAKS 0
diff --git a/lib/lsan/lsan_common_linux.cc b/lib/lsan/lsan_common_linux.cc
index 2955343e1f0b..1dc0561dab71 100644
--- a/lib/lsan/lsan_common_linux.cc
+++ b/lib/lsan/lsan_common_linux.cc
@@ -29,7 +29,7 @@ static const char kLinkerName[] = "ld";
// We request 2 modules matching "ld", so we can print a warning if there's more
// than one match. But only the first one is actually used.
static char linker_placeholder[2 * sizeof(LoadedModule)] ALIGNED(64);
-static LoadedModule *linker = 0;
+static LoadedModule *linker = nullptr;
static bool IsLinker(const char* full_name) {
return LibraryNameIs(full_name, kLinkerName);
@@ -49,7 +49,7 @@ void InitializePlatformSpecificModules() {
else if (num_matches > 1)
VReport(1, "LeakSanitizer: Multiple modules match \"%s\". "
"TLS will not be handled correctly.\n", kLinkerName);
- linker = 0;
+ linker = nullptr;
}
static int ProcessGlobalRegionsCallback(struct dl_phdr_info *info, size_t size,
@@ -174,5 +174,6 @@ void DoStopTheWorld(StopTheWorldCallback callback, void *argument) {
dl_iterate_phdr(DoStopTheWorldCallback, &param);
}
-} // namespace __lsan
-#endif // CAN_SANITIZE_LEAKS && SANITIZER_LINUX
+} // namespace __lsan
+
+#endif // CAN_SANITIZE_LEAKS && SANITIZER_LINUX
diff --git a/lib/lsan/lsan_flags.inc b/lib/lsan/lsan_flags.inc
index b19b3452b2fc..c405005deed5 100644
--- a/lib/lsan/lsan_flags.inc
+++ b/lib/lsan/lsan_flags.inc
@@ -24,8 +24,6 @@ LSAN_FLAG(
"Aggregate two objects into one leak if this many stack frames match. If "
"zero, the entire stack trace must match.")
LSAN_FLAG(int, max_leaks, 0, "The number of leaks reported.")
-LSAN_FLAG(int, exitcode, 23,
- "If nonzero kill the process with this exit code upon finding leaks.")
// Flags controlling the root set of reachable memory.
LSAN_FLAG(bool, use_globals, true,
diff --git a/lib/lsan/lsan_interceptors.cc b/lib/lsan/lsan_interceptors.cc
index 61a92154d95e..be0d0ddc282e 100644
--- a/lib/lsan/lsan_interceptors.cc
+++ b/lib/lsan/lsan_interceptors.cc
@@ -71,7 +71,7 @@ INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
CHECK(allocated < kCallocPoolSize);
return mem;
}
- if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return 0;
+ if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return nullptr;
ENSURE_LSAN_INITED;
GET_STACK_TRACE_MALLOC;
size *= nmemb;
@@ -164,9 +164,9 @@ void *operator new[](uptr size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
Deallocate(ptr);
INTERCEPTOR_ATTRIBUTE
-void operator delete(void *ptr) throw() { OPERATOR_DELETE_BODY; }
+void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
INTERCEPTOR_ATTRIBUTE
-void operator delete[](void *ptr) throw() { OPERATOR_DELETE_BODY; }
+void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
INTERCEPTOR_ATTRIBUTE
void operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; }
INTERCEPTOR_ATTRIBUTE
@@ -226,7 +226,7 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr,
ENSURE_LSAN_INITED;
EnsureMainThreadIDIsCorrect();
__sanitizer_pthread_attr_t myattr;
- if (attr == 0) {
+ if (!attr) {
pthread_attr_init(&myattr);
attr = &myattr;
}
@@ -284,4 +284,4 @@ void InitializeInterceptors() {
}
}
-} // namespace __lsan
+} // namespace __lsan
diff --git a/lib/lsan/lsan_thread.cc b/lib/lsan/lsan_thread.cc
index 0f8efc093b56..10ac2c9f499d 100644
--- a/lib/lsan/lsan_thread.cc
+++ b/lib/lsan/lsan_thread.cc
@@ -79,7 +79,7 @@ void ThreadContext::OnFinished() {
u32 ThreadCreate(u32 parent_tid, uptr user_id, bool detached) {
return thread_registry->CreateThread(user_id, detached, parent_tid,
- /* arg */ 0);
+ /* arg */ nullptr);
}
void ThreadStart(u32 tid, uptr os_id) {
@@ -99,9 +99,9 @@ void ThreadFinish() {
}
ThreadContext *CurrentThreadContext() {
- if (!thread_registry) return 0;
+ if (!thread_registry) return nullptr;
if (GetCurrentThread() == kInvalidTid)
- return 0;
+ return nullptr;
// No lock needed when getting current thread.
return (ThreadContext *)thread_registry->GetThreadLocked(GetCurrentThread());
}
@@ -120,7 +120,7 @@ u32 ThreadTid(uptr uid) {
void ThreadJoin(u32 tid) {
CHECK_NE(tid, kInvalidTid);
- thread_registry->JoinThread(tid, /* arg */0);
+ thread_registry->JoinThread(tid, /* arg */nullptr);
}
void EnsureMainThreadIDIsCorrect() {
@@ -157,4 +157,4 @@ void UnlockThreadRegistry() {
thread_registry->Unlock();
}
-} // namespace __lsan
+} // namespace __lsan