george.karpenkov created this revision.
george.karpenkov added reviewers: NoQ, bogner, chandlerc, zturner, aprantl.
Herald added a subscriber: mgrang.

There are many "dumping" actions available from the compiler: Clang dumps AST, 
Clang static analyzer dumps generated nodes in the "exploded graph" it 
generates.

However, in many of those dumps raw pointer values are printed for the objects 
of interest, which can considerably complicate debugging due to those values 
being non-reproducible.
This patch adds a method for converting a pointer generated through an 
allocator to a deterministic (up to an architecture) pair of integers, which 
can make the debugging experience much more pleasant. 
(E.g. compare hunting for a value "0xa9273f732" which changes every run to 
hunting for "(1, 23)").

Discussion started at 
http://lists.llvm.org/pipermail/cfe-dev/2018-August/059178.html

Code in collaboration with @NoQ


https://reviews.llvm.org/D51393

Files:
  llvm/include/llvm/Support/Allocator.h


Index: llvm/include/llvm/Support/Allocator.h
===================================================================
--- llvm/include/llvm/Support/Allocator.h
+++ llvm/include/llvm/Support/Allocator.h
@@ -21,6 +21,7 @@
 #ifndef LLVM_SUPPORT_ALLOCATOR_H
 #define LLVM_SUPPORT_ALLOCATOR_H
 
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -283,6 +284,28 @@
 
   size_t GetNumSlabs() const { return Slabs.size() + CustomSizedSlabs.size(); }
 
+  /// \return A reproducible pair of objects, uniquely identifying
+  /// an input pointer \p Ptr in the given allocator.
+  /// Returns an empty optional if the pointer is not found in the allocator.
+  llvm::Optional<std::pair<size_t, long>> identifyObject(const void *Ptr) {
+    const char *P = reinterpret_cast<const char *>(Ptr);
+    for (size_t Idx=0; Idx < Slabs.size(); Idx++) {
+      const char *S = reinterpret_cast<const char *>(Slabs[Idx]);
+      if (P >= S && P < S + computeSlabSize(Idx))
+        return std::make_pair(Idx, P - S);
+    }
+    for (size_t Idx=0; Idx < CustomSizedSlabs.size(); Idx++) {
+      const char *S =
+          reinterpret_cast<const char *>(CustomSizedSlabs[Idx].first);
+      size_t Size = CustomSizedSlabs[Idx].second;
+
+      // Use negative index to denote custom sized slabs.
+      if (P >= S && P < S + Size)
+        return std::make_pair(-Idx - 1, P - S);
+    }
+    return None;
+  }
+
   size_t getTotalMemory() const {
     size_t TotalMemory = 0;
     for (auto I = Slabs.begin(), E = Slabs.end(); I != E; ++I)


Index: llvm/include/llvm/Support/Allocator.h
===================================================================
--- llvm/include/llvm/Support/Allocator.h
+++ llvm/include/llvm/Support/Allocator.h
@@ -21,6 +21,7 @@
 #ifndef LLVM_SUPPORT_ALLOCATOR_H
 #define LLVM_SUPPORT_ALLOCATOR_H
 
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -283,6 +284,28 @@
 
   size_t GetNumSlabs() const { return Slabs.size() + CustomSizedSlabs.size(); }
 
+  /// \return A reproducible pair of objects, uniquely identifying
+  /// an input pointer \p Ptr in the given allocator.
+  /// Returns an empty optional if the pointer is not found in the allocator.
+  llvm::Optional<std::pair<size_t, long>> identifyObject(const void *Ptr) {
+    const char *P = reinterpret_cast<const char *>(Ptr);
+    for (size_t Idx=0; Idx < Slabs.size(); Idx++) {
+      const char *S = reinterpret_cast<const char *>(Slabs[Idx]);
+      if (P >= S && P < S + computeSlabSize(Idx))
+        return std::make_pair(Idx, P - S);
+    }
+    for (size_t Idx=0; Idx < CustomSizedSlabs.size(); Idx++) {
+      const char *S =
+          reinterpret_cast<const char *>(CustomSizedSlabs[Idx].first);
+      size_t Size = CustomSizedSlabs[Idx].second;
+
+      // Use negative index to denote custom sized slabs.
+      if (P >= S && P < S + Size)
+        return std::make_pair(-Idx - 1, P - S);
+    }
+    return None;
+  }
+
   size_t getTotalMemory() const {
     size_t TotalMemory = 0;
     for (auto I = Slabs.begin(), E = Slabs.end(); I != E; ++I)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to