[Win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / include / gdidebug.h
1 #pragma once
2
3 extern ULONG gulDebugChannels;
4
5 #define GDI_STACK_LEVELS 20
6 extern ULONG_PTR GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
7 extern ULONG_PTR GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
8 extern ULONG_PTR GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
9 extern ULONG_PTR GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
10
11 enum _DEBUGCHANNELS
12 {
13 DbgCustom = 1,
14 DbgObjects = 2,
15 DbgBitBlt = 4,
16 DbgXlate = 8,
17 DbgModeSwitch = 16,
18 };
19
20 void IntDumpHandleTable(PGDI_HANDLE_TABLE HandleTable);
21 ULONG CaptureStackBackTace(PVOID* pFrames, ULONG nFramesToCapture);
22 BOOL GdiDbgHTIntegrityCheck();
23 void GdiDbgDumpLockedHandles();
24
25 #define DBGENABLE(ch) gulDebugChannels |= (ch);
26 #define DBGDISABLE(ch) gulDebugChannels &= ~(ch);
27 #define DPRINTCH(ch) if (gulDebugChannels & (ch)) DbgPrint
28
29 #ifdef GDI_DEBUG
30
31 #define KeRosDumpStackFrames(Frames, Count) KdSystemDebugControl('DsoR', (PVOID)Frames, Count, NULL, 0, NULL, KernelMode)
32 NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags);
33
34 #define IS_HANDLE_VALID(idx) \
35 ((GdiHandleTable->Entries[idx].Type & GDI_ENTRY_BASETYPE_MASK) != 0)
36
37 #define GDIDBG_TRACECALLER() \
38 DPRINT1("-> called from:\n"); \
39 KeRosDumpStackFrames(NULL, 20);
40 #define GDIDBG_TRACEALLOCATOR(handle) \
41 DPRINT1("-> allocated from:\n"); \
42 KeRosDumpStackFrames(GDIHandleAllocator[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
43 #define GDIDBG_TRACELOCKER(handle) \
44 DPRINT1("-> locked from:\n"); \
45 KeRosDumpStackFrames(GDIHandleLocker[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
46 #define GDIDBG_TRACESHARELOCKER(handle) \
47 DPRINT1("-> locked from:\n"); \
48 KeRosDumpStackFrames(GDIHandleShareLocker[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
49 #define GDIDBG_TRACEDELETER(handle) \
50 DPRINT1("-> deleted from:\n"); \
51 KeRosDumpStackFrames(GDIHandleDeleter[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
52 #define GDIDBG_CAPTUREALLOCATOR(handle) \
53 CaptureStackBackTace((PVOID*)GDIHandleAllocator[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
54 #define GDIDBG_CAPTURELOCKER(handle) \
55 CaptureStackBackTace((PVOID*)GDIHandleLocker[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
56 #define GDIDBG_CAPTURESHARELOCKER(handle) \
57 CaptureStackBackTace((PVOID*)GDIHandleShareLocker[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
58 #define GDIDBG_CAPTUREDELETER(handle) \
59 CaptureStackBackTace((PVOID*)GDIHandleDeleter[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
60 #define GDIDBG_DUMPHANDLETABLE() \
61 IntDumpHandleTable(GdiHandleTable)
62 #define GDIDBG_INITLOOPTRACE() \
63 ULONG Attempts = 0;
64 #define GDIDBG_TRACELOOP(Handle, PrevThread, Thread) \
65 if ((++Attempts % 20) == 0) \
66 { \
67 DPRINT1("[%d] Handle 0x%p Locked by 0x%x (we're 0x%x)\n", Attempts, Handle, PrevThread, Thread); \
68 }
69
70 #else
71
72 #define GDIDBG_TRACECALLER()
73 #define GDIDBG_TRACEALLOCATOR(index)
74 #define GDIDBG_TRACELOCKER(index)
75 #define GDIDBG_TRACESHARELOCKER(index)
76 #define GDIDBG_CAPTUREALLOCATOR(index)
77 #define GDIDBG_CAPTURELOCKER(index)
78 #define GDIDBG_CAPTURESHARELOCKER(index)
79 #define GDIDBG_CAPTUREDELETER(handle)
80 #define GDIDBG_DUMPHANDLETABLE()
81 #define GDIDBG_INITLOOPTRACE()
82 #define GDIDBG_TRACELOOP(Handle, PrevThread, Thread)
83 #define GDIDBG_TRACEDELETER(handle)
84
85 #endif /* GDI_DEBUG */
86
87 #if DBG
88 void
89 NTAPI
90 DbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments);
91
92 ULONG_PTR
93 NTAPI
94 DbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult);
95
96 #define ID_Win32PreServiceHook 'WSH0'
97 #define ID_Win32PostServiceHook 'WSH1'
98
99 FORCEINLINE void
100 GdiDbgAssertNoLocks(char * pszFile, ULONG nLine)
101 {
102 PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread();
103 if (pti && pti->cExclusiveLocks != 0)
104 {
105 DbgPrint("(%s:%ld) There are %ld exclusive locks!\n",
106 pszFile, nLine, pti->cExclusiveLocks);
107 GdiDbgDumpLockedHandles();
108 ASSERT(FALSE);
109 }
110 }
111
112 #define ASSERT_NOGDILOCKS() GdiDbgAssertNoLocks(__FILE__,__LINE__)
113 #else
114 #define ASSERT_NOGDILOCKS()
115 #endif
116