Home | History | Annotate | Download | only in Utility
      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 assignements
     15 // and allow them to be queried using a pointer by a call to:
     16 #include <execinfo.h>
     17 #include <map>
     18 #include <assert.h>
     19 #include "lldb/Host/Mutex.h"
     20 
     21 #include <vector>
     22 
     23 class Backtrace
     24 {
     25 public:
     26     Backtrace ();
     27 
     28     ~Backtrace ();
     29 
     30     void
     31     GetFrames ();
     32 
     33     void
     34     Dump () const;
     35 
     36 private:
     37     void *m_sp_this;
     38     std::vector<void *> m_frames;
     39 };
     40 
     41 
     42 Backtrace::Backtrace () : m_frames()
     43 {
     44 }
     45 
     46 Backtrace::~Backtrace ()
     47 {
     48 }
     49 
     50 void
     51 Backtrace::GetFrames ()
     52 {
     53     void *frames[1024];
     54     const int count = ::backtrace (frames, sizeof(frames)/sizeof(void*));
     55     if (count > 2)
     56         m_frames.assign (frames + 2, frames + (count - 2));
     57 }
     58 
     59 void
     60 Backtrace::Dump () const
     61 {
     62     if (!m_frames.empty())
     63         ::backtrace_symbols_fd (m_frames.data(), m_frames.size(), STDOUT_FILENO);
     64     write (STDOUT_FILENO, "\n\n", 2);
     65 }
     66 
     67 extern "C" void track_sp (void *sp_this, void *ptr, long use_count)
     68 {
     69     typedef std::pair<void *, Backtrace> PtrBacktracePair;
     70     typedef std::map<void *, PtrBacktracePair> PtrToBacktraceMap;
     71     static lldb_private::Mutex g_mutex(lldb_private::Mutex::eMutexTypeNormal);
     72     lldb_private::Mutex::Locker locker (g_mutex);
     73     static PtrToBacktraceMap g_map;
     74 
     75     if (sp_this)
     76     {
     77         printf ("sp(%p) -> %p %lu\n", sp_this, ptr, use_count);
     78 
     79         if (ptr)
     80         {
     81             Backtrace bt;
     82             bt.GetFrames();
     83             g_map[sp_this] = std::make_pair(ptr, bt);
     84         }
     85         else
     86         {
     87             g_map.erase (sp_this);
     88         }
     89     }
     90     else
     91     {
     92         if (ptr)
     93             printf ("Searching for shared pointers that are tracking %p: ", ptr);
     94         else
     95             printf ("Dump all live shared pointres: ");
     96 
     97         uint32_t matches = 0;
     98         PtrToBacktraceMap::iterator pos, end = g_map.end();
     99         for (pos = g_map.begin(); pos != end; ++pos)
    100         {
    101             if (ptr == NULL || pos->second.first == ptr)
    102             {
    103                 ++matches;
    104                 printf ("\nsp(%p): %p\n", pos->first, pos->second.first);
    105                 pos->second.second.Dump();
    106             }
    107         }
    108         if (matches == 0)
    109         {
    110             printf ("none.\n");
    111         }
    112     }
    113 }
    114 // Put dump_sp_refs in the lldb namespace to it gets through our exports lists filter in the LLDB.framework or lldb.so
    115 namespace lldb {
    116 
    117     void dump_sp_refs (void *ptr)
    118     {
    119         // Use a specially crafted call to "track_sp" which will
    120         // dump info on all live shared pointers that reference "ptr"
    121         track_sp (NULL, ptr, 0);
    122     }
    123 
    124 }
    125 
    126 #endif
    127 
    128 namespace lldb_private {
    129 
    130 namespace imp
    131 {
    132 
    133 
    134     shared_count::~shared_count()
    135     {
    136     }
    137 
    138     void
    139     shared_count::add_shared()
    140     {
    141         increment(shared_owners_);
    142     }
    143 
    144     void
    145     shared_count::release_shared()
    146     {
    147         if (decrement(shared_owners_) == -1)
    148         {
    149             on_zero_shared();
    150             delete this;
    151         }
    152     }
    153 
    154 } // imp
    155 
    156 
    157 } // namespace lldb
    158 
    159