blob: bdaedfb9b0495ae9645518a64ba088aa55189a3b [file] [log] [blame]
Greg Claytonef59f822010-06-12 17:45:57 +00001//===---------------------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
Eli Friedman81ad7262010-06-12 18:29:53 +000010#include "lldb/Utility/SharingPtr.h"
Greg Claytonef59f822010-06-12 17:45:57 +000011
Kate Stoneb9c1b512016-09-06 20:57:50 +000012#if defined(ENABLE_SP_LOGGING)
Greg Claytonbdf3a012012-01-19 04:44:00 +000013
Adrian Prantl05097242018-04-30 16:49:04 +000014// If ENABLE_SP_LOGGING is defined, then log all shared pointer assignments and
15// allow them to be queried using a pointer by a call to:
Greg Claytonbdf3a012012-01-19 04:44:00 +000016#include <assert.h>
Kate Stoneb9c1b512016-09-06 20:57:50 +000017#include <execinfo.h>
Greg Claytonbdf3a012012-01-19 04:44:00 +000018
Saleem Abdulrasool28606952014-06-27 05:17:41 +000019#include "llvm/ADT/STLExtras.h"
20
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000021#include <map>
22#include <mutex>
Greg Claytonbdf3a012012-01-19 04:44:00 +000023#include <vector>
24
Kate Stoneb9c1b512016-09-06 20:57:50 +000025class Backtrace {
Greg Claytonbdf3a012012-01-19 04:44:00 +000026public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000027 Backtrace();
28
29 ~Backtrace();
30
31 void GetFrames();
32
33 void Dump() const;
34
Greg Claytonbdf3a012012-01-19 04:44:00 +000035private:
Kate Stoneb9c1b512016-09-06 20:57:50 +000036 void *m_sp_this;
37 std::vector<void *> m_frames;
Greg Claytonbdf3a012012-01-19 04:44:00 +000038};
39
Kate Stoneb9c1b512016-09-06 20:57:50 +000040Backtrace::Backtrace() : m_frames() {}
Greg Claytonbdf3a012012-01-19 04:44:00 +000041
Kate Stoneb9c1b512016-09-06 20:57:50 +000042Backtrace::~Backtrace() {}
43
44void 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));
Greg Claytonbdf3a012012-01-19 04:44:00 +000049}
50
Kate Stoneb9c1b512016-09-06 20:57:50 +000051void 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);
Greg Claytonbdf3a012012-01-19 04:44:00 +000055}
56
Kate Stoneb9c1b512016-09-06 20:57:50 +000057extern "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;
Greg Claytonbdf3a012012-01-19 04:44:00 +000063
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 if (sp_this) {
65 printf("sp(%p) -> %p %lu\n", sp_this, ptr, use_count);
Greg Claytonbdf3a012012-01-19 04:44:00 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 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);
Greg Claytonbdf3a012012-01-19 04:44:00 +000073 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 } else {
75 if (ptr)
76 printf("Searching for shared pointers that are tracking %p: ", ptr);
77 else
78 printf("Dump all live shared pointres: ");
Greg Claytonbdf3a012012-01-19 04:44:00 +000079
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 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 }
Greg Claytonbdf3a012012-01-19 04:44:00 +000088 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 if (matches == 0) {
90 printf("none.\n");
91 }
92 }
Greg Claytonbdf3a012012-01-19 04:44:00 +000093}
Kate Stoneb9c1b512016-09-06 20:57:50 +000094// Put dump_sp_refs in the lldb namespace to it gets through our exports lists
95// filter in the LLDB.framework or lldb.so
Greg Clayton29ad7b92012-01-27 18:45:39 +000096namespace lldb {
Kate Stoneb9c1b512016-09-06 20:57:50 +000097
98void dump_sp_refs(void *ptr) {
Adrian Prantl05097242018-04-30 16:49:04 +000099 // Use a specially crafted call to "track_sp" which will dump info on all
100 // live shared pointers that reference "ptr"
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101 track_sp(NULL, ptr, 0);
102}
Greg Claytonbdf3a012012-01-19 04:44:00 +0000103}
104
105#endif
106
Greg Clayton5573fde2010-09-24 23:07:41 +0000107namespace lldb_private {
Greg Claytonef59f822010-06-12 17:45:57 +0000108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109namespace imp {
Greg Claytonef59f822010-06-12 17:45:57 +0000110
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111shared_count::~shared_count() {}
Greg Clayton747bcb02011-09-17 06:21:20 +0000112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113void shared_count::add_shared() {
Enrico Granatafcb37ae2013-10-18 18:57:49 +0000114#ifdef _MSC_VER
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 _InterlockedIncrement(&shared_owners_);
Enrico Granatafcb37ae2013-10-18 18:57:49 +0000116#else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117 ++shared_owners_;
Enrico Granatafcb37ae2013-10-18 18:57:49 +0000118#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119}
Greg Clayton747bcb02011-09-17 06:21:20 +0000120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121void shared_count::release_shared() {
Enrico Granatafcb37ae2013-10-18 18:57:49 +0000122#ifdef _MSC_VER
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123 if (_InterlockedDecrement(&shared_owners_) == -1)
Enrico Granatafcb37ae2013-10-18 18:57:49 +0000124#else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125 if (--shared_owners_ == -1)
Enrico Granatafcb37ae2013-10-18 18:57:49 +0000126#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 {
128 on_zero_shared();
129 delete this;
130 }
131}
Greg Claytonef59f822010-06-12 17:45:57 +0000132
133} // imp
134
135} // namespace lldb