ReactOS  0.4.15-dev-3324-gda4e15f
fxtagtracker.hpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxTagTracker.hpp
8 
9 Abstract:
10 
11  This is the C++ header for the FxTagTracker
12 
13 Author:
14 
15 
16 
17 
18 Revision History:
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 --*/
31 
32 #ifndef _FXTAGTRACKER_HPP_
33 #define _FXTAGTRACKER_HPP_
34 
35 extern "C" {
36 
37 #if defined(EVENT_TRACING)
38 #include "FxTagTracker.hpp.tmh"
39 #endif
40 
41 }
42 
46 };
47 
49  TagAddRef = 0,
51 };
52 
53 #define FRAMES_TO_CAPTURE 16
54 #define FRAMES_TO_SKIP 3
55 
59 };
60 
61 //
62 // Tracks outstanding references
63 //
64 
65 struct FxTagTrackingBlock : public FxStump {
66 
68  __in PVOID Tag,
69  __in LONG Line,
71  __in_opt BOOLEAN Initial = FALSE
72  ) :
73  Tag(Tag),
74  Line(Line),
75  File(File),
77  Next(NULL)
78  {
80 
81  if (Initial == FALSE) {
82  //
83  // !wdftagtracker identifies a reference with Line == 0
84  // as the initial reference. However, references taken
85  // in framework code may leave the File/Line empty yet
86  // not be the initial references. They could still
87  // capture stack frames, so they are useful to track.
88  //
89  // Leaving File == NULL but setting Line = 1 unless this
90  // was explicitly labeled an Initial Ref works around this.
91  //
92  if (File == NULL && Line == 0) {
93  this->Line = 1;
94  }
95  }
96  }
97 
99  )
100  {
101  if (StackFrames != NULL) {
102  delete StackFrames;
103  StackFrames = NULL;
104  }
105  }
106 
113 };
114 
115 //
116 // Tracks reference and release history
117 //
118 struct FxTagHistory {
120  //
121  // Note: RefCount may be inaccurate when multiple FxObject::Release
122  // calls execute concurrently. This value should be considered
123  // an approximation and is for wdfkd consumption only.
124  //
131 
133  )
134  {
135  StackFrames = NULL;
136  }
137 
139  )
140  {
141  if (StackFrames != NULL) {
142  delete StackFrames;
143  StackFrames = NULL;
144  }
145  }
146 };
147 
148 
149 #define TAG_HISTORY_DEPTH (25)
150 
151 class FxTagTracker : public FxGlobalsStump {
152 
153 private:
154 
155  //
156  // Making constructor private to enforce usage
157  // of CreateAndInitialize
158  //
159 
161  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
163  __in BOOLEAN CaptureStack,
165  __in_opt PVOID CreateTag = NULL
166  ) :
167  FxGlobalsStump(FxDriverGlobals),
169  m_CaptureStack(CaptureStack),
170  m_Next(NULL),
171  m_FailedCount(0),
172  m_CurRefHistory(0),
174  {
176 
177  //
178  // We keep handle reference trackers in a list,
179  // which wdfkd uses to identify potential handle leaks.
180  //
182  FxDriverGlobalsDebugExtension* pExtension;
183  KIRQL irql;
184 
185  pExtension = GetDriverGlobals()->DebugExtension;
186  ASSERT(pExtension != NULL);
187 
188  //
189  // Insert the tag tracker into the list of allocated trackers
190  //
191  pExtension->AllocatedTagTrackersLock.Acquire(&irql);
193  &m_TrackerEntry);
194  pExtension->AllocatedTagTrackersLock.Release(irql);
195 
196  //
197  // Handle references default to 1 outstanding ref (the object creation ref)
198  //
199  m_Next = new(FxDriverGlobals) FxTagTrackingBlock(CreateTag, 0, NULL, TRUE);
200  if (m_Next == NULL) {
201  m_FailedCount = 1;
202  }
203  }
204  else {
206  }
207  }
208 
209  VOID
211  _Inout_ FxTagTrackingStackFrames** StackFrames,
212  _In_ USHORT NumFrames,
213  _In_reads_(NumFrames) PVOID* Frames
214  );
215 
216 public:
217 
219  static
220  NTSTATUS
221  __inline
223  __out FxTagTracker ** TagTracker,
224  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
226  __in BOOLEAN CaptureStack,
228  __in_opt PVOID CreateTag = NULL
229  )
230  {
232 
233  FxTagTracker * tagTracker = new(FxDriverGlobals)
234  FxTagTracker(FxDriverGlobals, Type, CaptureStack, Owner, CreateTag);
235 
236  if (NULL == tagTracker) {
238 
240  FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
241  "Failed to allocate tag tracker, returning %!STATUS!", status);
242 
243  goto exit;
244  }
245 
246  *TagTracker = tagTracker;
248 
249  exit:
250  return status;
251  }
252 
253  ~FxTagTracker();
254 
255  VOID
257  VOID
258  );
259 
260  VOID
262  __in PVOID Tag,
263  __in LONG Line,
265  __in FxTagRefType RefType,
266  __in ULONG RefCount
267  );
268 
269 protected:
270  //
271  // Whether this tracks handle references or power references.
272  //
274 
275  //
276  // Whether to capture stack frames for each ref/release.
277  //
279 
280  //
281  // Owner object for this FxTagTracker. An FxDevice if this tracks power refs.
282  //
284 
285  //
286  // Link into list of allocated tag trackers kept in the driver's globals
287  //
289 
290  //
291  // Number of times we failed to alloc a tracking block
292  //
294 
295  //
296  // Lock to guard the insertion/removal of tracking blocks
297  //
299 
300  //
301  // List head for tracking blocks
302  //
304 
305  //
306  // Last TAG_HISTORY_DEPTH addrefs and releases on the object
307  //
309 
310  //
311  // Current index into RefHistory
312  //
314 };
315 
316 #endif // _FXTAGTRACKER_HPP_
317 
signed char * PCHAR
Definition: retypes.h:7
FxObject * m_OwningObject
VOID CheckForAbandondedTags(VOID)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define _Inout_
Definition: ms_sal.h:378
LIST_ENTRY m_TrackerEntry
FxTagTrackingStackFrames * StackFrames
FxTagHistory m_TagHistory[TAG_HISTORY_DEPTH]
static __inline VOID MxQueryTickCount(__out PLARGE_INTEGER TickCount)
Definition: mxgeneralkm.h:116
#define __in_opt
Definition: dbghelp.h:38
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
KIRQL irql
Definition: wave.h:1
FxDriverGlobalsDebugExtension * DebugExtension
Definition: fxglobals.h:376
LARGE_INTEGER Time
LIST_ENTRY AllocatedTagTrackersListHead
Definition: fxglobals.h:134
#define InsertTailList(ListHead, Entry)
BOOLEAN m_CaptureStack
UCHAR KIRQL
Definition: env_spec_w32.h:591
static _Must_inspect_result_ NTSTATUS __inline CreateAndInitialize(__out FxTagTracker **TagTracker, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxTagTrackerType Type, __in BOOLEAN CaptureStack, __in FxObject *Owner, __in_opt PVOID CreateTag=NULL)
FxTagRefType
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
FxTagTrackingBlock(__in PVOID Tag, __in LONG Line, __in_opt PSTR File, __in_opt BOOLEAN Initial=FALSE)
#define __out
Definition: dbghelp.h:62
unsigned char BOOLEAN
FxTagRefType RefType
#define _In_
Definition: ms_sal.h:308
FxTagTrackingStackFrames * StackFrames
struct FxTagTrackingBlock * Next
FxTagTracker(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxTagTrackerType Type, __in BOOLEAN CaptureStack, __in FxObject *Owner, __in_opt PVOID CreateTag=NULL)
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define ASSERT(a)
Definition: mode.c:44
FxTagTrackerType
Type
Definition: Type.h:6
LARGE_INTEGER TimeLocked
FxTagTrackerType m_TrackerType
VOID UpdateTagHistory(__in PVOID Tag, __in LONG Line, __in_opt PSTR File, __in FxTagRefType RefType, __in ULONG RefCount)
Definition: ncftp.h:79
unsigned __int64 ULONG64
Definition: imports.h:198
unsigned char UCHAR
Definition: xmlstorage.h:181
#define FRAMES_TO_CAPTURE
VOID CopyStackFrames(_Inout_ FxTagTrackingStackFrames **StackFrames, _In_ USHORT NumFrames, _In_reads_(NumFrames) PVOID *Frames)
FxTagTrackingBlock * m_Next
Definition: typedefs.h:119
#define _Must_inspect_result_
Definition: ms_sal.h:558
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4061
#define _In_reads_(size)
Definition: ms_sal.h:319
ULONG64 Frames[FRAMES_TO_CAPTURE]
Definition: mxlock.h:101
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
unsigned short USHORT
Definition: pedump.c:61
signed char * PSTR
Definition: retypes.h:7
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1556
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
Definition: File.h:15
#define STATUS_SUCCESS
Definition: shellext.h:65
void exit(int exitcode)
Definition: _exit.c:33
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxstump.hpp:98
#define TAG_HISTORY_DEPTH
Definition: ps.c:97