ReactOS 0.4.15-dev-7907-g95bf896
fxtagtracker.hpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxTagTracker.hpp
8
9Abstract:
10
11 This is the C++ header for the FxTagTracker
12
13Author:
14
15
16
17
18Revision History:
19
20
21
22
23
24
25
26
27
28
29
30--*/
31
32#ifndef _FXTAGTRACKER_HPP_
33#define _FXTAGTRACKER_HPP_
34
35extern "C" {
36
37#if defined(EVENT_TRACING)
38#include "FxTagTracker.hpp.tmh"
39#endif
40
41}
42
46};
47
51};
52
53#define FRAMES_TO_CAPTURE 16
54#define FRAMES_TO_SKIP 3
55
59};
60
61//
62// Tracks outstanding references
63//
64
65struct FxTagTrackingBlock : public FxStump {
66
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;
104 }
105 }
106
113};
114
115//
116// Tracks reference and release history
117//
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 {
136 }
137
139 )
140 {
141 if (StackFrames != NULL) {
142 delete StackFrames;
144 }
145 }
146};
147
148
149#define TAG_HISTORY_DEPTH (25)
150
152
153private:
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),
174 {
176
177 //
178 // We keep handle reference trackers in a list,
179 // which wdfkd uses to identify potential handle leaks.
180 //
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);
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
216public:
217
219 static
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
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
269protected:
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
unsigned char BOOLEAN
Type
Definition: Type.h:7
LONG NTSTATUS
Definition: precomp.h:26
Definition: File.h:16
VOID CheckForAbandondedTags(VOID)
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)
VOID CopyStackFrames(_Inout_ FxTagTrackingStackFrames **StackFrames, _In_ USHORT NumFrames, _In_reads_(NumFrames) PVOID *Frames)
FxTagTrackerType m_TrackerType
FxObject * m_OwningObject
BOOLEAN m_CaptureStack
FxTagHistory m_TagHistory[TAG_HISTORY_DEPTH]
VOID UpdateTagHistory(__in PVOID Tag, __in LONG Line, __in_opt PSTR File, __in FxTagRefType RefType, __in ULONG RefCount)
LIST_ENTRY m_TrackerEntry
FxTagTracker(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxTagTrackerType Type, __in BOOLEAN CaptureStack, __in FxObject *Owner, __in_opt PVOID CreateTag=NULL)
FxTagTrackingBlock * m_Next
Definition: mxlock.h:102
static __inline VOID MxQueryTickCount(__out PLARGE_INTEGER TickCount)
Definition: mxgeneralkm.h:116
#define __in
Definition: dbghelp.h:35
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
KIRQL irql
Definition: wave.h:1
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxTagTrackerType
@ FxTagTrackerTypePower
@ FxTagTrackerTypeHandle
FxTagRefType
@ TagRelease
@ TagAddRef
#define FRAMES_TO_CAPTURE
#define TAG_HISTORY_DEPTH
#define ASSERT(a)
Definition: mode.c:44
unsigned __int64 ULONG64
Definition: imports.h:198
#define _Inout_
Definition: ms_sal.h:378
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define _In_
Definition: ms_sal.h:308
#define _In_reads_(size)
Definition: ms_sal.h:319
_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:1597
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define exit(n)
Definition: config.h:202
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
LIST_ENTRY AllocatedTagTrackersListHead
Definition: fxglobals.h:134
PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxstump.hpp:98
FxTagTrackingStackFrames * StackFrames
LARGE_INTEGER Time
FxTagRefType RefType
LARGE_INTEGER TimeLocked
FxTagTrackingBlock(__in PVOID Tag, __in LONG Line, __in_opt PSTR File, __in_opt BOOLEAN Initial=FALSE)
FxTagTrackingStackFrames * StackFrames
struct FxTagTrackingBlock * Next
ULONG64 Frames[FRAMES_TO_CAPTURE]
Definition: ncftp.h:79
FxDriverGlobalsDebugExtension * DebugExtension
Definition: fxglobals.h:376
Definition: typedefs.h:120
Definition: ps.c:97
char * PSTR
Definition: typedefs.h:51
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
unsigned char UCHAR
Definition: xmlstorage.h:181