[PATCH] [asan] LSan hooks in asan_allocator2.cc

Sergey Matveev earthdok at google.com
Mon May 20 06:54:13 PDT 2013


Hi kcc, glider, samsonov,

http://llvm-reviews.chandlerc.com/D827

Files:
  lib/asan/asan_allocator2.cc

Index: lib/asan/asan_allocator2.cc
===================================================================
--- lib/asan/asan_allocator2.cc
+++ lib/asan/asan_allocator2.cc
@@ -28,6 +28,10 @@
 #include "sanitizer_common/sanitizer_stackdepot.h"
 #include "sanitizer_common/sanitizer_quarantine.h"
 
+#if SANITIZE_LEAKS
+#include "lsan/lsan_common.h"
+#endif
+
 namespace __asan {
 
 struct AsanMapUnmapCallback {
@@ -164,6 +168,9 @@
   u32 from_memalign     : 1;
   u32 alloc_type        : 2;
   u32 rz_log            : 3;
+#if SANITIZE_LEAKS
+  u32 lsan_tag          : 2;
+#endif
   // 2-nd 8 bytes
   // This field is used for small sizes. For large sizes it is equal to
   // SizeClassMap::kMaxSize and the actual size is stored in the
@@ -700,6 +707,84 @@
 
 }  // namespace __asan
 
+// --- Implementation of LSan-specific functions --- {{{1
+#if SANITIZE_LEAKS
+namespace __lsan {
+void LockAllocator() {
+  __asan::allocator.ForceLock();
+}
+
+void UnlockAllocator() {
+  __asan::allocator.ForceUnlock();
+}
+
+void GetAllocatorGlobalRange(uptr *begin, uptr *end) {
+  *begin = (uptr)&__asan::allocator;
+  *end = *begin + sizeof(__asan::allocator);
+}
+
+void *PointsIntoChunk(void* p) {
+  uptr addr = reinterpret_cast<uptr>(p);
+  __asan::AsanChunk *m = __asan::GetAsanChunkByAddr(addr);
+  if (!m) return 0;
+  uptr chunk = m->Beg();
+  if ((m->chunk_state == __asan::CHUNK_ALLOCATED) && (addr >= chunk) &&
+      addr < chunk + m->UsedSize())
+    return reinterpret_cast<void *>(chunk);
+  return 0;
+}
+
+void *GetUserBegin(void *p) {
+  __asan::AsanChunk *m = __asan::GetAsanChunkByAddr(reinterpret_cast<uptr>(p));
+  CHECK(m);
+  return reinterpret_cast<void *>(m->Beg());
+}
+
+LsanMetadata::LsanMetadata(void *chunk) {
+  uptr addr = reinterpret_cast<uptr>(chunk);
+  metadata_ = reinterpret_cast<void *>(addr - __asan::kChunkHeaderSize);
+}
+
+bool LsanMetadata::allocated() const {
+  __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
+  return m->chunk_state == __asan::CHUNK_ALLOCATED;
+}
+
+ChunkTag LsanMetadata::tag() const {
+  __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
+  return static_cast<ChunkTag>(m->lsan_tag);
+}
+
+void LsanMetadata::set_tag(ChunkTag value) {
+  __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
+  m->lsan_tag = value;
+}
+
+uptr LsanMetadata::requested_size() const {
+  __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
+  return m->user_requested_size;
+}
+
+u32 LsanMetadata::stack_trace_id() const {
+  __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
+  return m->alloc_context_id;
+}
+
+template <typename Callable> void ForEachChunk(Callable const &callback) {
+  __asan::allocator.ForEachChunk(callback);
+}
+
+template void ForEachChunk<ProcessPlatformSpecificAllocationsCb>(
+    ProcessPlatformSpecificAllocationsCb const &callback);
+template void ForEachChunk<PrintLeakedCb>(PrintLeakedCb const &callback);
+template void ForEachChunk<CollectLeaksCb>(CollectLeaksCb const &callback);
+template void ForEachChunk<MarkIndirectlyLeakedCb>(
+    MarkIndirectlyLeakedCb const &callback);
+template void ForEachChunk<ReportLeakedCb>(ReportLeakedCb const &callback);
+template void ForEachChunk<ClearTagCb>(ClearTagCb const &callback);
+}  // namespace __lsan
+#endif  // SANITIZE_LEAKS
+
 // ---------------------- Interface ---------------- {{{1
 using namespace __asan;  // NOLINT
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D827.1.patch
Type: text/x-patch
Size: 3461 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130520/7b377272/attachment.bin>


More information about the llvm-commits mailing list