2010-06-13 01:45:57 +08:00
|
|
|
//===---------------------SharingPtr.cpp ------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-06-13 02:29:53 +08:00
|
|
|
#include "lldb/Utility/SharingPtr.h"
|
2010-06-13 01:45:57 +08:00
|
|
|
|
2012-01-19 12:44:00 +08:00
|
|
|
#if defined (ENABLE_SP_LOGGING)
|
|
|
|
|
|
|
|
// If ENABLE_SP_LOGGING is defined, then log all shared pointer assignements
|
|
|
|
// and allow them to be queried using a pointer by a call to:
|
|
|
|
#include <execinfo.h>
|
|
|
|
#include <map>
|
|
|
|
#include <assert.h>
|
|
|
|
#include "lldb/Host/Mutex.h"
|
|
|
|
|
2014-06-27 13:17:41 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
|
2012-01-19 12:44:00 +08:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
class Backtrace
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Backtrace ();
|
|
|
|
|
|
|
|
~Backtrace ();
|
|
|
|
|
|
|
|
void
|
|
|
|
GetFrames ();
|
|
|
|
|
|
|
|
void
|
|
|
|
Dump () const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
void *m_sp_this;
|
|
|
|
std::vector<void *> m_frames;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Backtrace::Backtrace () : m_frames()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Backtrace::~Backtrace ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Backtrace::GetFrames ()
|
|
|
|
{
|
|
|
|
void *frames[1024];
|
2014-06-27 13:17:41 +08:00
|
|
|
const int count = ::backtrace (frames, llvm::array_lengthof(frames));
|
2012-01-19 12:44:00 +08:00
|
|
|
if (count > 2)
|
|
|
|
m_frames.assign (frames + 2, frames + (count - 2));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Backtrace::Dump () const
|
|
|
|
{
|
|
|
|
if (!m_frames.empty())
|
|
|
|
::backtrace_symbols_fd (m_frames.data(), m_frames.size(), STDOUT_FILENO);
|
|
|
|
write (STDOUT_FILENO, "\n\n", 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void track_sp (void *sp_this, void *ptr, long use_count)
|
|
|
|
{
|
|
|
|
typedef std::pair<void *, Backtrace> PtrBacktracePair;
|
|
|
|
typedef std::map<void *, PtrBacktracePair> PtrToBacktraceMap;
|
|
|
|
static lldb_private::Mutex g_mutex(lldb_private::Mutex::eMutexTypeNormal);
|
|
|
|
lldb_private::Mutex::Locker locker (g_mutex);
|
|
|
|
static PtrToBacktraceMap g_map;
|
|
|
|
|
|
|
|
if (sp_this)
|
|
|
|
{
|
|
|
|
printf ("sp(%p) -> %p %lu\n", sp_this, ptr, use_count);
|
|
|
|
|
|
|
|
if (ptr)
|
|
|
|
{
|
|
|
|
Backtrace bt;
|
|
|
|
bt.GetFrames();
|
|
|
|
g_map[sp_this] = std::make_pair(ptr, bt);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_map.erase (sp_this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (ptr)
|
|
|
|
printf ("Searching for shared pointers that are tracking %p: ", ptr);
|
|
|
|
else
|
|
|
|
printf ("Dump all live shared pointres: ");
|
|
|
|
|
|
|
|
uint32_t matches = 0;
|
|
|
|
PtrToBacktraceMap::iterator pos, end = g_map.end();
|
|
|
|
for (pos = g_map.begin(); pos != end; ++pos)
|
|
|
|
{
|
|
|
|
if (ptr == NULL || pos->second.first == ptr)
|
|
|
|
{
|
|
|
|
++matches;
|
|
|
|
printf ("\nsp(%p): %p\n", pos->first, pos->second.first);
|
|
|
|
pos->second.second.Dump();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (matches == 0)
|
|
|
|
{
|
|
|
|
printf ("none.\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-01-28 02:45:39 +08:00
|
|
|
// Put dump_sp_refs in the lldb namespace to it gets through our exports lists filter in the LLDB.framework or lldb.so
|
|
|
|
namespace lldb {
|
|
|
|
|
|
|
|
void dump_sp_refs (void *ptr)
|
|
|
|
{
|
|
|
|
// Use a specially crafted call to "track_sp" which will
|
|
|
|
// dump info on all live shared pointers that reference "ptr"
|
|
|
|
track_sp (NULL, ptr, 0);
|
|
|
|
}
|
|
|
|
|
2012-01-19 12:44:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2010-09-25 07:07:41 +08:00
|
|
|
namespace lldb_private {
|
2010-06-13 01:45:57 +08:00
|
|
|
|
|
|
|
namespace imp
|
|
|
|
{
|
|
|
|
|
|
|
|
|
2011-09-17 14:21:20 +08:00
|
|
|
shared_count::~shared_count()
|
|
|
|
{
|
|
|
|
}
|
2010-06-13 01:45:57 +08:00
|
|
|
|
2011-09-17 14:21:20 +08:00
|
|
|
void
|
|
|
|
shared_count::add_shared()
|
|
|
|
{
|
<rdar://problem/15182550>
Removing Host/Atomic.h
This header file was not being copied as part of our public API headers and this in turn was causing any plugin to link against LLDB.framework, since SharingPtr.h depends on it
Out of several possible options to fix this issue, the cleanest one is to revert LLDB to use std::atomic<>, as we are a C++11 project and should take advantage of it
The original rationale for going from std::atomic to Host/Atomic.h was that MSVC++ fails to link in CLR mode when std::atomic is used
This is a very Visual Studio/.net specific issue, which hopefully will be fixed
Until them, to allow Windows development to proceed, we are going with a targeted solution where we #ifdef include the Windows specific calls, and let everyone else use the
proper atomic support, as should be
If there is an unavoidable need for a LLDB-specific atomic header, the right way to go at it would be to make an API/lldb-atomic.h header and #ifdef the Windows dependency there
The FormatManager should not need to conditionalize use of std::atomic<>, as other parts of the LLDB internals are successfully using atomic (Address and IRExecutionUnit), so this
Win-specific hack is limited to SharingPtr
llvm-svn: 192993
2013-10-19 02:57:49 +08:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
_InterlockedIncrement(&shared_owners_);
|
|
|
|
#else
|
|
|
|
++shared_owners_;
|
|
|
|
#endif
|
2011-09-17 14:21:20 +08:00
|
|
|
}
|
2010-06-13 01:45:57 +08:00
|
|
|
|
2011-09-17 14:21:20 +08:00
|
|
|
void
|
|
|
|
shared_count::release_shared()
|
2010-06-13 01:45:57 +08:00
|
|
|
{
|
<rdar://problem/15182550>
Removing Host/Atomic.h
This header file was not being copied as part of our public API headers and this in turn was causing any plugin to link against LLDB.framework, since SharingPtr.h depends on it
Out of several possible options to fix this issue, the cleanest one is to revert LLDB to use std::atomic<>, as we are a C++11 project and should take advantage of it
The original rationale for going from std::atomic to Host/Atomic.h was that MSVC++ fails to link in CLR mode when std::atomic is used
This is a very Visual Studio/.net specific issue, which hopefully will be fixed
Until them, to allow Windows development to proceed, we are going with a targeted solution where we #ifdef include the Windows specific calls, and let everyone else use the
proper atomic support, as should be
If there is an unavoidable need for a LLDB-specific atomic header, the right way to go at it would be to make an API/lldb-atomic.h header and #ifdef the Windows dependency there
The FormatManager should not need to conditionalize use of std::atomic<>, as other parts of the LLDB internals are successfully using atomic (Address and IRExecutionUnit), so this
Win-specific hack is limited to SharingPtr
llvm-svn: 192993
2013-10-19 02:57:49 +08:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
if (_InterlockedDecrement(&shared_owners_) == -1)
|
|
|
|
#else
|
|
|
|
if (--shared_owners_ == -1)
|
|
|
|
#endif
|
2011-09-17 14:21:20 +08:00
|
|
|
{
|
|
|
|
on_zero_shared();
|
|
|
|
delete this;
|
|
|
|
}
|
2010-06-13 01:45:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
} // imp
|
|
|
|
|
2011-09-17 14:21:20 +08:00
|
|
|
|
2010-06-13 01:45:57 +08:00
|
|
|
} // namespace lldb
|
2011-09-17 14:21:20 +08:00
|
|
|
|