]> git.lyx.org Git - lyx.git/blob - development/Win32/vld/src/vldint.h
Add support for glue length in parskip (#12867)
[lyx.git] / development / Win32 / vld / src / vldint.h
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 //  Visual Leak Detector - VisualLeakDetector Class Definition
4 //  Copyright (c) 2005-2009 Dan Moulding
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License, or (at your option) any later version.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 //
20 //  See COPYING.txt for the full terms of the GNU Lesser General Public License.
21 //
22 ////////////////////////////////////////////////////////////////////////////////
23
24 #pragma once
25
26 #ifndef VLDBUILD
27 #error \
28 "This header should only be included by Visual Leak Detector when building it from source. \
29 Applications should never include this header."
30 #endif
31
32 #include <cstdio>
33 #include <windows.h>
34 #include "callstack.h" // Provides a custom class for handling call stacks.
35 #include "map.h"       // Provides a custom STL-like map template.
36 #include "ntapi.h"     // Provides access to NT APIs.
37 #include "set.h"       // Provides a custom STL-like set template.
38 #include "utility.h"   // Provides miscellaneous utility functions.
39
40 #define MAXMODULELISTLENGTH 512     // Maximum module list length, in characters.
41 #define SELFTESTTEXTA       "Memory Leak Self-Test"
42 #define SELFTESTTEXTW       L"Memory Leak Self-Test"
43 #define VLDREGKEYPRODUCT    L"Software\\Visual Leak Detector"
44 #define VLDVERSION          L"1.9h"
45
46 // The Visual Leak Detector APIs.
47 extern "C" __declspec(dllexport) void VLDDisable ();
48 extern "C" __declspec(dllexport) void VLDEnable ();
49
50 // Function pointer types for explicit dynamic linking with functions listed in
51 // the import patch table.
52 typedef void* (__cdecl *_calloc_dbg_t) (size_t, size_t, int, const char*, int);
53 typedef void* (__cdecl *_malloc_dbg_t) (size_t, int, const char *, int);
54 typedef void* (__cdecl *_realloc_dbg_t) (void *, size_t, int, const char *, int);
55 typedef void* (__cdecl *calloc_t) (size_t, size_t);
56 typedef HRESULT (__stdcall *CoGetMalloc_t) (DWORD, LPMALLOC *);
57 typedef LPVOID (__stdcall *CoTaskMemAlloc_t) (ULONG);
58 typedef LPVOID (__stdcall *CoTaskMemRealloc_t) (LPVOID, ULONG);
59 typedef void* (__cdecl *malloc_t) (size_t);
60 typedef void* (__cdecl *new_t) (size_t);
61 typedef void* (__cdecl *new_dbg_crt_t) (size_t, int, const char *, int);
62 typedef void* (__cdecl *new_dbg_mfc_t) (size_t, const char *, int);
63 typedef void* (__cdecl *realloc_t) (void *, size_t);
64
65 // Data is collected for every block allocated from any heap in the process.
66 // The data is stored in this structure and these structures are stored in
67 // a BlockMap which maps each of these structures to its corresponding memory
68 // block.
69 typedef struct blockinfo_s {
70     CallStack *callstack;
71     SIZE_T     serialnumber;
72     SIZE_T     size;
73 } blockinfo_t;
74
75 // BlockMaps map memory blocks (via their addresses) to blockinfo_t structures.
76 typedef Map<LPCVOID, blockinfo_t*> BlockMap;
77
78 // Information about each heap in the process is kept in this map. Primarily
79 // this is used for mapping heaps to all of the blocks allocated from those
80 // heaps.
81 typedef struct heapinfo_s {
82     BlockMap blockmap;   // Map of all blocks allocated from this heap.
83     UINT32   flags;      // Heap status flags:
84 #define VLD_HEAP_CRT 0x1 //   If set, this heap is a CRT heap (i.e. the CRT uses it for new/malloc).
85 } heapinfo_t;
86
87 // HeapMaps map heaps (via their handles) to BlockMaps.
88 typedef Map<HANDLE, heapinfo_t*> HeapMap;
89
90 // This structure stores information, primarily the virtual address range, about
91 // a given module and can be used with the Set template because it supports the
92 // '<' operator (sorts by virtual address range).
93 typedef struct moduleinfo_s {
94     BOOL operator < (const struct moduleinfo_s &other) const
95     {
96         if (addrhigh < other.addrlow) {
97             return TRUE;
98         }
99         else {
100             return FALSE;
101         }
102     }
103
104     SIZE_T addrhigh;                 // Highest address within the module's virtual address space (i.e. base + size).
105     SIZE_T addrlow;                  // Lowest address within the module's virtual address space (i.e. base address).
106     UINT32 flags;                    // Module flags:
107 #define VLD_MODULE_EXCLUDED      0x1 //   If set, this module is excluded from leak detection.
108 #define VLD_MODULE_SYMBOLSLOADED 0x2 //   If set, this module's debug symbols have been loaded.
109     LPCSTR name;                     // The module's name (e.g. "kernel32.dll").
110     LPCSTR path;                     // The fully qualified path from where the module was loaded.
111 } moduleinfo_t;
112
113 // ModuleSets store information about modules loaded in the process.
114 typedef Set<moduleinfo_t> ModuleSet;
115
116 // Thread local storage structure. Every thread in the process gets its own copy
117 // of this structure. Thread specific information, such as the current leak
118 // detection status (enabled or disabled) and the address that initiated the
119 // current allocation is stored here.
120 typedef struct tls_s {
121     SIZE_T addrfp;           // Frame pointer at the first call that entered VLD's code for the current allocation.
122     UINT32 flags;            // Thread-local status flags:
123 #define VLD_TLS_CRTALLOC 0x1 //   If set, the current allocation is a CRT allocation.
124 #define VLD_TLS_DISABLED 0x2 //   If set, memory leak detection is disabled for the current thread.
125 #define VLD_TLS_ENABLED  0x4 //   If set, memory leak detection is enabled for the current thread.
126     DWORD  threadid;         // Thread ID of the thread that owns this TLS structure.
127 } tls_t;
128
129 // The TlsSet allows VLD to keep track of all thread local storage structures
130 // allocated in the process.
131 typedef Set<tls_t*> TlsSet;
132
133 ////////////////////////////////////////////////////////////////////////////////
134 //
135 // The VisualLeakDetector Class
136 //
137 //   One global instance of this class is instantiated. Upon construction it
138 //   patches the import address table (IAT) of every other module loaded in the
139 //   process (see the "patchimport" utility function) to allow key Windows heap
140 //   APIs to be patched through to, or redirected to, functions provided by VLD.
141 //   Patching the IATs in this manner allows VLD to be made aware of all
142 //   relevant heap activity, making it possible for VLD to detect and trace
143 //   memory leaks.
144 //
145 //   The one global instance of this class is constructed within the context of
146 //   the process' main thread during process initialization and is destroyed in
147 //   the same context during process termination.
148 //
149 //   When the VisualLeakDetector object is destroyed, it consults its internal
150 //   datastructures, looking for any memory that has not been freed. A memory
151 //   leak report is then generated, indicating any memory leaks that may have
152 //   been identified.
153 //
154 //   This class is derived from IMalloc so that it can provide an implementation
155 //   of the IMalloc COM interface in order to support detection of COM-based
156 //   memory leaks. However, this implementation of IMalloc is actually just a
157 //   thin wrapper around the system's implementation of IMalloc.
158 //
159 class VisualLeakDetector : public IMalloc
160 {
161 public:
162     VisualLeakDetector();
163     ~VisualLeakDetector();
164
165 ////////////////////////////////////////////////////////////////////////////////
166 // Public CRT and MFC Common Handlers
167 //
168 // Many heap functions are indirectly rerouted to these handlers. One common
169 // function exists for each heap function with a given signature. These
170 // handlers are not direct IAT replacements, but are called by the individual
171 // IAT replacement functions.
172 ////////////////////////////////////////////////////////////////////////////////
173     // Standard CRT and MFC common handlers
174     void* _calloc (calloc_t pcalloc, SIZE_T fp, size_t num, size_t size);
175     void* _malloc (malloc_t pmalloc, SIZE_T fp, size_t size);
176     void* _new (new_t pnew, SIZE_T fp, size_t size); 
177     void* _realloc (realloc_t prealloc, SIZE_T fp, void *mem, size_t size);
178
179     // Debug CRT and MFC common handlers
180     void* __calloc_dbg (_calloc_dbg_t p_calloc_dbg, SIZE_T fp, size_t num, size_t size, int type, char const *file, int line);
181     void* __malloc_dbg (_malloc_dbg_t p_malloc_dbg, SIZE_T fp, size_t size, int type, char const *file, int line);
182     void* new_dbg_crt (new_dbg_crt_t pnew_dbg_crt, SIZE_T fp, size_t size, int type, char const *file, int line);
183     void* new_dbg_mfc (new_dbg_crt_t pnew_dbg, SIZE_T fp, size_t size, int type, char const *file, int line);
184     void* new_dbg_mfc (new_dbg_mfc_t pnew_dbg_mfc, SIZE_T fp, size_t size, char const *file, int line);
185     void* __realloc_dbg (_realloc_dbg_t p_realloc_dbg, SIZE_T fp, void *mem, size_t size, int type, char const *file, int line);
186
187 ////////////////////////////////////////////////////////////////////////////////
188 // Public IMalloc methods - for support of COM-based memory leak detection.
189 ////////////////////////////////////////////////////////////////////////////////
190     ULONG   __stdcall AddRef ();
191     LPVOID  __stdcall Alloc (ULONG size);
192     INT     __stdcall DidAlloc (LPVOID mem);
193     VOID    __stdcall Free (LPVOID mem);
194     ULONG   __stdcall GetSize (LPVOID mem);
195     VOID    __stdcall HeapMinimize ();
196     HRESULT __stdcall QueryInterface (REFIID iid, LPVOID *object);
197     LPVOID  __stdcall Realloc (LPVOID mem, ULONG size);
198     ULONG   __stdcall Release ();
199
200 private:
201 ////////////////////////////////////////////////////////////////////////////////
202 // Private leak detection functions - see each function definition for details.
203 ////////////////////////////////////////////////////////////////////////////////
204     VOID   attachtoloadedmodules (ModuleSet *newmodules);
205     LPWSTR buildsymbolsearchpath ();
206     VOID   configure ();
207     BOOL   enabled ();
208     SIZE_T eraseduplicates (const BlockMap::Iterator &element);
209     tls_t* gettls ();
210     VOID   mapblock (HANDLE heap, LPCVOID mem, SIZE_T size, SIZE_T framepointer, BOOL crtalloc);
211     VOID   mapheap (HANDLE heap);
212     VOID   remapblock (HANDLE heap, LPCVOID mem, LPCVOID newmem, SIZE_T size, SIZE_T framepointer, BOOL crtalloc);
213     VOID   reportconfig ();
214     VOID   reportleaks (HANDLE heap);
215     VOID   unmapblock (HANDLE heap, LPCVOID mem);
216     VOID   unmapheap (HANDLE heap);
217
218     // Static functions (callbacks)
219     static BOOL __stdcall addloadedmodule (PCWSTR modulepath, DWORD64 modulebase, ULONG modulesize, PVOID context);
220     static BOOL __stdcall detachfrommodule (PCWSTR modulepath, DWORD64 modulebase, ULONG modulesize, PVOID context);
221
222 ////////////////////////////////////////////////////////////////////////////////
223 // IAT replacement functions - see each function definition for details.
224 //
225 // Because there are so many virtually identical CRT and MFC replacement
226 // functions, they are excluded from the class to reduce the amount of noise
227 // within this class's code. See crtmfcpatch.cpp for those functions.
228 ////////////////////////////////////////////////////////////////////////////////
229     // Win32 IAT replacement functions
230     static FARPROC  __stdcall _GetProcAddress (HMODULE module, LPCSTR procname);
231     static HANDLE   __stdcall _HeapCreate (DWORD options, SIZE_T initsize, SIZE_T maxsize);
232     static BOOL     __stdcall _HeapDestroy (HANDLE heap);
233     static NTSTATUS __stdcall _LdrLoadDll (LPWSTR searchpath, PDWORD flags, unicodestring_t *modulename,
234                                            PHANDLE modulehandle);
235     static LPVOID   __stdcall _RtlAllocateHeap (HANDLE heap, DWORD flags, SIZE_T size);
236     static BOOL     __stdcall _RtlFreeHeap (HANDLE heap, DWORD flags, LPVOID mem);
237     static LPVOID   __stdcall _RtlReAllocateHeap (HANDLE heap, DWORD flags, LPVOID mem, SIZE_T size);
238
239     // COM IAT replacement functions
240     static HRESULT __stdcall _CoGetMalloc (DWORD context, LPMALLOC *imalloc);
241     static LPVOID  __stdcall _CoTaskMemAlloc (ULONG size);
242     static LPVOID  __stdcall _CoTaskMemRealloc (LPVOID mem, ULONG size);
243
244 ////////////////////////////////////////////////////////////////////////////////
245 // Private data
246 ////////////////////////////////////////////////////////////////////////////////
247     WCHAR                m_forcedmodulelist [MAXMODULELISTLENGTH]; // List of modules to be forcefully included in leak detection.
248     HeapMap             *m_heapmap;           // Map of all active heaps in the process.
249     IMalloc             *m_imalloc;           // Pointer to the system implementation of IMalloc.
250     SIZE_T               m_leaksfound;        // Total number of leaks found.
251     ModuleSet           *m_loadedmodules;     // Contains information about all modules loaded in the process.
252     CRITICAL_SECTION     m_loaderlock;        // Serializes the attachment of newly loaded modules.
253     CRITICAL_SECTION     m_maplock;           // Serializes access to the heap and block maps.
254     SIZE_T               m_maxdatadump;       // Maximum number of user-data bytes to dump for each leaked block.
255     UINT32               m_maxtraceframes;    // Maximum number of frames per stack trace for each leaked block.
256     CRITICAL_SECTION     m_moduleslock;       // Protects accesses to the "loaded modules" ModuleSet.
257     UINT32               m_options;           // Configuration options:
258 #define VLD_OPT_AGGREGATE_DUPLICATES    0x1   //   If set, aggregate duplicate leaks in the leak report.
259 #define VLD_OPT_MODULE_LIST_INCLUDE     0x2   //   If set, modules in the module list are included, all others are excluded.
260 #define VLD_OPT_REPORT_TO_DEBUGGER      0x4   //   If set, the memory leak report is sent to the debugger.
261 #define VLD_OPT_REPORT_TO_FILE          0x8   //   If set, the memory leak report is sent to a file.
262 #define VLD_OPT_SAFE_STACK_WALK         0x10  //   If set, the stack is walked using the "safe" method (StackWalk64).
263 #define VLD_OPT_SELF_TEST               0x20  //   If set, peform a self-test to verify memory leak self-checking.
264 #define VLD_OPT_SLOW_DEBUGGER_DUMP      0x40  //   If set, inserts a slight delay between sending output to the debugger.
265 #define VLD_OPT_START_DISABLED          0x80  //   If set, memory leak detection will initially disabled.
266 #define VLD_OPT_TRACE_INTERNAL_FRAMES   0x100 //   If set, include useless frames (e.g. internal to VLD) in call stacks.
267 #define VLD_OPT_UNICODE_REPORT          0x200 //   If set, the leak report will be encoded UTF-16 instead of ASCII.
268 #define VLD_OPT_VLDOFF                  0x400 //   If set, VLD will be completely deactivated. It will not attach to any modules.
269     static patchentry_t  m_patchtable [];     // Table of imports patched for attaching VLD to other modules.
270     FILE                *m_reportfile;        // File where the memory leak report may be sent to.
271     WCHAR                m_reportfilepath [MAX_PATH]; // Full path and name of file to send memory leak report to.
272     const char          *m_selftestfile;      // Filename where the memory leak self-test block is leaked.
273     int                  m_selftestline;      // Line number where the memory leak self-test block is leaked.
274     UINT32               m_status;            // Status flags:
275 #define VLD_STATUS_DBGHELPLINKED        0x1   //   If set, the explicit dynamic link to the Debug Help Library succeeded.
276 #define VLD_STATUS_INSTALLED            0x2   //   If set, VLD was successfully installed.
277 #define VLD_STATUS_NEVER_ENABLED        0x4   //   If set, VLD started disabled, and has not yet been manually enabled.
278 #define VLD_STATUS_FORCE_REPORT_TO_FILE 0x8   //   If set, the leak report is being forced to a file.
279     DWORD                m_tlsindex;          // Thread-local storage index.
280     CRITICAL_SECTION     m_tlslock;           // Protects accesses to the Set of TLS structures.
281     TlsSet              *m_tlsset;            // Set of all all thread-local storage structres for the process.
282     HMODULE              m_vldbase;           // Visual Leak Detector's own module handle (base address).
283
284     // The Visual Leak Detector APIs are our friends.
285     friend __declspec(dllexport) void VLDDisable ();
286     friend __declspec(dllexport) void VLDEnable ();
287 };
288
289 // Configuration option default values
290 #define VLD_DEFAULT_MAX_DATA_DUMP    256
291 #define VLD_DEFAULT_MAX_TRACE_FRAMES 64
292 #define VLD_DEFAULT_REPORT_FILE_NAME L".\\memory_leak_report.txt"