]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Utility/SharingPtr.cpp
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / source / Utility / SharingPtr.cpp
1 //===---------------------SharingPtr.cpp ------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Utility/SharingPtr.h"
11
12 #if defined(ENABLE_SP_LOGGING)
13
14 // If ENABLE_SP_LOGGING is defined, then log all shared pointer assignments
15 // and allow them to be queried using a pointer by a call to:
16 #include <assert.h>
17 #include <execinfo.h>
18
19 #include "llvm/ADT/STLExtras.h"
20
21 #include <map>
22 #include <mutex>
23 #include <vector>
24
25 class Backtrace {
26 public:
27   Backtrace();
28
29   ~Backtrace();
30
31   void GetFrames();
32
33   void Dump() const;
34
35 private:
36   void *m_sp_this;
37   std::vector<void *> m_frames;
38 };
39
40 Backtrace::Backtrace() : m_frames() {}
41
42 Backtrace::~Backtrace() {}
43
44 void Backtrace::GetFrames() {
45   void *frames[1024];
46   const int count = ::backtrace(frames, llvm::array_lengthof(frames));
47   if (count > 2)
48     m_frames.assign(frames + 2, frames + (count - 2));
49 }
50
51 void Backtrace::Dump() const {
52   if (!m_frames.empty())
53     ::backtrace_symbols_fd(m_frames.data(), m_frames.size(), STDOUT_FILENO);
54   write(STDOUT_FILENO, "\n\n", 2);
55 }
56
57 extern "C" void track_sp(void *sp_this, void *ptr, long use_count) {
58   typedef std::pair<void *, Backtrace> PtrBacktracePair;
59   typedef std::map<void *, PtrBacktracePair> PtrToBacktraceMap;
60   static std::mutex g_mutex;
61   std::lock_guard<std::mutex> guard(g_mutex);
62   static PtrToBacktraceMap g_map;
63
64   if (sp_this) {
65     printf("sp(%p) -> %p %lu\n", sp_this, ptr, use_count);
66
67     if (ptr) {
68       Backtrace bt;
69       bt.GetFrames();
70       g_map[sp_this] = std::make_pair(ptr, bt);
71     } else {
72       g_map.erase(sp_this);
73     }
74   } else {
75     if (ptr)
76       printf("Searching for shared pointers that are tracking %p: ", ptr);
77     else
78       printf("Dump all live shared pointres: ");
79
80     uint32_t matches = 0;
81     PtrToBacktraceMap::iterator pos, end = g_map.end();
82     for (pos = g_map.begin(); pos != end; ++pos) {
83       if (ptr == NULL || pos->second.first == ptr) {
84         ++matches;
85         printf("\nsp(%p): %p\n", pos->first, pos->second.first);
86         pos->second.second.Dump();
87       }
88     }
89     if (matches == 0) {
90       printf("none.\n");
91     }
92   }
93 }
94 // Put dump_sp_refs in the lldb namespace to it gets through our exports lists
95 // filter in the LLDB.framework or lldb.so
96 namespace lldb {
97
98 void dump_sp_refs(void *ptr) {
99   // Use a specially crafted call to "track_sp" which will
100   // dump info on all live shared pointers that reference "ptr"
101   track_sp(NULL, ptr, 0);
102 }
103 }
104
105 #endif
106
107 namespace lldb_private {
108
109 namespace imp {
110
111 shared_count::~shared_count() {}
112
113 void shared_count::add_shared() {
114 #ifdef _MSC_VER
115   _InterlockedIncrement(&shared_owners_);
116 #else
117   ++shared_owners_;
118 #endif
119 }
120
121 void shared_count::release_shared() {
122 #ifdef _MSC_VER
123   if (_InterlockedDecrement(&shared_owners_) == -1)
124 #else
125   if (--shared_owners_ == -1)
126 #endif
127   {
128     on_zero_shared();
129     delete this;
130   }
131 }
132
133 } // imp
134
135 } // namespace lldb