This is Unofficial EPICS BASE Doxygen Site
debugPtr.cpp
Go to the documentation of this file.
1 /*
2  * Copyright information and license terms for this software can be
3  * found in the file LICENSE that is included with the distribution
4  */
5 
6 #if __cplusplus>=201103L
7 
8 #include <epicsMutex.h>
9 #include <epicsGuard.h>
10 
11 #define epicsExportSharedSymbols
12 #include <pv/debugPtr.h>
13 
14 namespace {
16 }
17 
18 namespace epics {
19 namespace debug {
20 
21 // joins together a group of ptr_base instances
22 // which all have the same dtor
23 struct tracker {
26 };
27 
29 {
30  if(track) {
31  Guard G(track->mutex);
32  track->refs.insert(this);
33  }
34  snap_stack();
35 }
36 
37 // create new tracker if ptr!=nullptr, otherwise clear
38 void shared_ptr_base::track_new(void* ptr)
39 {
40  track_clear();
41  if(ptr){
42  track.reset(new tracker);
43  Guard G(track->mutex);
44  track->refs.insert(this);
45  }
46  snap_stack();
47 }
48 
49 void shared_ptr_base::track_assign(const shared_ptr_base &o)
50 {
51  if(track!=o.track) {
52  track_clear();
53  track = o.track;
54  if(track) {
55  Guard G(track->mutex);
56  track->refs.insert(this);
57  }
58  snap_stack();
59  }
60 }
61 
63 {
64  if(track) {
65  Guard G(track->mutex);
66  track->refs.erase(this);
67  }
68  track.reset();
69 #ifndef EXCEPT_USE_NONE
70  m_depth = 0;
71 #endif
72 }
73 
74 void shared_ptr_base::swap(shared_ptr_base &o)
75 {
76  // we cheat a bit here to avoid lock order, and to lock only twice
77  if(track) {
78  Guard G(track->mutex);
79  track->refs.insert(&o);
80  track->refs.erase(this);
81  }
82  track.swap(o.track);
83  if(track) {
84  Guard G(track->mutex);
85  track->refs.insert(this);
86  track->refs.erase(&o);
87  }
88  //TODO: keep original somehow???
89  snap_stack();
90  o.snap_stack();
91 }
92 
94 {
95  if(!track) {
96 #ifndef EXCEPT_USE_NONE
97  m_depth = 0;
98 #endif
99  return;
100  }
101 #if defined(EXCEPT_USE_BACKTRACE)
102  {
103  m_depth=backtrace(m_stack,EXCEPT_DEPTH);
104  }
105 #else
106  {}
107 #endif
108 
109 }
110 
111 void shared_ptr_base::show_stack(std::ostream& strm) const
112 {
113  strm<<"ptr "<<this;
114 #ifndef EXCEPT_USE_NONE
115  if(m_depth<=0) return;
116 #endif
117 #if 0 && defined(EXCEPT_USE_BACKTRACE)
118  {
119 
120  char **symbols=backtrace_symbols(m_stack, m_depth);
121 
122  strm<<": ";
123  for(int i=0; i<m_depth; i++) {
124  strm<<symbols[i]<<", ";
125  }
126 
127  std::free(symbols);
128  }
129 #elif !defined(EXCEPT_USE_NONE)
130  {
131  strm<<": ";
132  for(int i=0; i<m_depth; i++) {
133  strm<<std::hex<<m_stack[i]<<" ";
134  }
135  }
136 #endif
137 
138 }
139 
140 void ptr_base::show_refs(std::ostream& strm, bool self, bool weak) const
141 {
142  if(!track) {
143  strm<<"# No refs\n";
144  } else {
145  Guard G(track->mutex);
146  for(auto ref : track->refs) {
147  if(!self && ref==this) continue;
148  strm<<'#';
149  ref->show_stack(strm);
150  strm<<'\n';
151  }
152  }
153 }
154 
155 void ptr_base::spy_refs(ref_set_t &refs) const
156 {
157  if(track) {
158  Guard G(track->mutex);
159  refs.insert(track->refs.begin(), track->refs.end());
160  }
161 }
162 
163 }} // namespace epics::debug
164 
165 #endif // __cplusplus>=201103L
void swap(shared_ptr_base &o)
void track_assign(const shared_ptr_base &o)
int i
Definition: scan.c:967
#define EXCEPT_DEPTH
void show_refs(std::ostream &, bool self=true, bool weak=false) const
epicsGuard< epicsMutex > Guard
Definition: utilities.cpp:15
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
void spy_refs(ref_set_t &) const
std::set< const shared_ptr_base * > ref_set_t
Definition: debugPtr.h:53
epicsMutex mutex
Definition: pvAccess.cpp:71
APIs for the epicsMutex mutual exclusion semaphore.
void show_stack(std::ostream &) const
Definition: tool_lib.h:64