diff --git a/development/Win32/vld/CHANGES.txt b/development/Win32/vld/CHANGES.txt
index 1c6f100d64..c6805efef9 100644
--- a/development/Win32/vld/CHANGES.txt
+++ b/development/Win32/vld/CHANGES.txt
@@ -1,12 +1,36 @@
-Visual Leak Detector (VLD) Version 1.9f (beta)
+Visual Leak Detector (VLD) Version 1.9h (beta)
Change Log / Release Notes
+
+ Enhancements:
+ + Added support to work with Visual Studio 2010.
+1.9h beta (24 February 2009)
+----------------------------
+ Enhancements:
+ + Added support to work with Visual Studio 2008.
+
+ Known Bugs/Restrictions:
+ + Same bugs/restrictions as version 1.9f.
+
+
+1.9g beta (16 April 2008)
+----------------------------
+ Bugs Fixed:
+ + Another deadlock condition may occur when loading DLLs into the process
+ being debugged. Special thanks to Eric Bissonnette and Kristian Paradis for
+ contributing this patch.
+
+ Known Bugs/Restrictions:
+ + Same bugs/restrictions as version 1.9f.
+
+
1.9f beta (18 November 2006)
----------------------------
Bugs Fixed:
+ Deadlocks or access violations may occur when loading DLLs into
multithreaded processes.
+
+ In multithreaded programs, if the main thread terminates before other
threads in the process, then Visual Leak Detector may cause an access
violation while generating the memory leak report.
@@ -14,15 +38,19 @@ Visual Leak Detector (VLD) Version 1.9f (beta)
Known Bugs/Restrictions:
+ Memory allocations made through calls to functions loaded from a DLL using
delayed loading may not be detected.
+
+ Support for programs that use MFC 7.0 or MFC 7.1 is not complete yet. Some
memory leaks from such MFC-based programs may not be detected.
+
+ Visual Leak Detector may report leaks internal to Visual Leak Detector
if the main thread of the process terminates while other threads are still
running.
+
+ If more than one copy of the same C Runtime DLL is loaded in the process at
the same time, then some leaks may go undetected (note that loading more
than one copy of the C Runtime DLL into a process at the same time is
probably a bad idea to begin with).
+
1.9e beta (16 November 2006)
----------------------------
@@ -34,12 +62,15 @@ Visual Leak Detector (VLD) Version 1.9f (beta)
+ Numerous deadlock situations. The multithread synchronization scheme has
been completely re-written which should make deadlocks in VLD much less
likey to happen.
+
+ An access violation will occur in VLD if GetProcAddress is called to obtain
an export's address by ordinal, for certain libraries.
+
+ Problems may potentially occur when the program being debugged exits due to
the Debug Help Library having been detached from the process too early.
Symptoms might include access violation exceptions or other erratic behavior
just as the program exits and while VLD is generating the leak report.
+
+ The copy of vld.ini installed in VLD's installation directory overrides any
other copies of vld.ini that are created, even copies placed in the
working directory of the program being debugged.
@@ -47,35 +78,46 @@ Visual Leak Detector (VLD) Version 1.9f (beta)
Known Bugs/Restrictions:
+ Memory allocations made through calls to functions loaded from a DLL using
delayed loading may not be detected.
+
+ Support for programs that use MFC 7.0 or MFC 7.1 is not complete yet. Some
memory leaks from such MFC-based programs may not be detected.
+
+ If more than one copy of the same C Runtime DLL is loaded in the process at
the same time, then some leaks may go undetected (note that loading more
than one copy of the C Runtime DLL into a process at the same time is
probably a bad idea to begin with).
+
1.9d beta (12 November 2006)
----------------------------
Bugs Fixed:
+ Failed assertion "freed == TRUE" pops up when running a program with VLD
without the debugger attached.
+
+ Some, but not all, multithreaded programs that dynamically load and unload
many DLLs have been known to experience problems, such as deadlocks or
exceptions, when used with VLD.
+
+ Failed assertion "exportmodule != NULL" pops up when running some programs
with VLD.
+
+ VLD fails to show file names or function names in the memory leak report for
some programs that are linked with the dynamic CRT library.
+
+ Access violation exceptions are thrown, but caught by the operating system,
when running some programs with VLD.
+
1.9c beta (6 November 2006)
---------------------------
New Features/Enhancments:
+ New NSIS installer makes setting up and using VLD much easier.
+
+ No need to manually copy dbghelp.dll to the right location, VLD will always
find the right version.
+
+ MFC 8.0 is now fully supported.
+
+ The memory leak report is now written to the output window much faster.
Support has been added, through a new configuration option, to slow down
the report output for older versions of Visual Studio that have trouble
@@ -83,16 +125,22 @@ Visual Leak Detector (VLD) Version 1.9f (beta)
Bugs Fixed:
+ All known compatibilities with Visual Studio 2005 have been eliminated.
+
+ Leaks from calloc may go undetected.
+
+ Leaks from vector new operator may go undetected.
+
+ VLDDisable and VLDEnable do not work as expected; some memory leaks that
should be ignored by VLD due to a previous call to VLDDisable are still
reported.
+
+ Unloading and reloading a previously loaded module may cause leaks that
occur in the module after it was reloaded to go undetected.
+
+ If vld.h is included in a release build, then the compiler will generate
errors if the VLDEnable or VLDDisable APIs have been used.
+
1.9b beta (26 October 2006)
---------------------------
Bugs Fixed:
@@ -114,6 +162,7 @@ Visual Leak Detector (VLD) Version 1.9f (beta)
This restriction does not apply to programs that use MFC 4.2, which is fully
supported.
+
1.9a beta (9 March 2006)
------------------------
New Features/Enhancments:
diff --git a/development/Win32/vld/README.html b/development/Win32/vld/README.html
index e624126f39..87b94694dd 100644
--- a/development/Win32/vld/README.html
+++ b/development/Win32/vld/README.html
@@ -170,6 +170,10 @@
blockquote {
font-style: italic;
}
+
+ form {
+ margin: 20px;
+ }
Visual Leak Detector (Beta)
@@ -183,7 +187,7 @@
@@ -268,7 +276,7 @@
Detector include and library directories to the Visual C++ include and library directory search paths:
- - Visual C++ 8: Go to Tools -> Options -> Projects and Solutions -> VC++ Directories.
+
- Visual C++ 8 and 9: Go to Tools -> Options -> Projects and Solutions -> VC++ Directories.
Select "Include files" from the "Show Directories For" drop-down menu. Add the
include subdirectory from the Visual Leak Detector installation directory. Move it
to the bottom of the list. Then select "Library files" from the drop-down menu and add the
@@ -529,16 +537,25 @@
Building Visual Leak Detector from Source
Because Visual Leak Detector is open source, it can be built from source if you want to tweak it to your
- liking. The most difficult part about building VLD from source is getting your build environment correctly set up.
+ liking. As of Visual Studio 2008, the source can usually be built out-of-the-box without downloading or installing
+ any other tools. If you are using Visual Studio 2008 (or later), you can skip ahead to
+ Executing Your Built vld.dll.
+
+
Users with older versions of Visual Studio should continue reading here and follow the instructions in the next
+ subsection.
+
+For Older Versions of Visual Studio
+
+The most difficult part about building VLD from source is getting your build environment correctly set up.
But if you follow these instructions carefully, the process should be fairly painless.
- VLD depends on the Debug Help Library. This library is part of
Debugging Tools for Windows (DTfW).
Download and install DTfW in order to install the required headers and libraries. I recommend installing version
- 6.5 of DTfW. Newer versions may also work, but older versions will probably not work. Be sure to manually select
- to install the SDK files during the DTfW installation or the headers and libraries will not be installed (they
- are not installed with a default installation).
+ 6.5 of DTfW, or later. Newer versions tend to work fine, but older versions will probably not work. Be sure to
+ manually select to install the SDK files during the DTfW installation or the headers and libraries will not be
+ installed (they are not always installed with a default installation).
- Visual C++ will need to be made aware of where it can find the Debug Help Library header and library files.
Add the sdk\inc and sdk\lib subdirectories from the
@@ -589,6 +606,8 @@
Once you have completed all of the above steps, your build environment should be ready. To build VLD, just open the
vld.sln solution file and do a full build.
+Executing Your Built vld.dll
+
When actually running the built project, vld.dll will expect to find the Debug Help
Library as a private assembly. The private assembly must be located in the same directory as
vld.dll (either the Release or
@@ -607,17 +626,10 @@
Windows x64 Support
-The VLD source code has been modified to add support for x64-based 64-bit Windows. However, the binary contained in
- the distributed version of VLD is 32-bit only. To take advantage of the 64-bit support, you'll need to build a 64-bit
- version of VLD from source. To build the 64-bit version, follow the instructions for building VLD
- from source. So long as it is built using a x64-compatible compiler in 64-bit mode, the resulting DLL will be a
- 64-bit binary.
-
-Note: I have not personally tested the 64-bit extensions so they are not absolutely
- guaranteed to work out-of-the-box. There may be a few lingering 64-bit compiler errors that still need to be worked
- out. If you need 64-bit support and run into problems trying to build the source in 64-bit mode, please
- let me know. I'll be glad to assist in getting the 64-bit code working
- properly.
+Currently VLD will not build on x64 due to limitations of the x64 compiler. Some efforts have been undertaken to
+ get it working in a 64-bit environment, but have not yet been successful. If you need 64-bit support and run into
+ problems trying to build the source in 64-bit mode, please let me know.
+ I'll be glad to assist in getting the 64-bit code working properly, if at all possible.
@@ -659,17 +671,17 @@
DLLs in memory leak detection, by setting the ForceIncludeModules configuration
option to: "mfc70d.dll mfc71d.dll" and explicitly adding vld.lib as an input file
on the linker command line (can be added through project settings by adding it to the list of library modules in
- the linker options). This restriction does not apply to programs that use MFC 4.2 or MFC 8.0 which are both fully
- supported.
+ the linker options). This restriction does not apply to programs that use MFC 4.2, MFC 8.0, or MFC 9.0, which are
+ all fully supported.
- Visual Leak Detector may report leaks internal to Visual Leak Detector if the main thread of the process
terminates while other threads are still running.
- On Windows 2000 and earlier operating systems, you may need to manually add the
- bin\Microsoft.VC80.CRT subdirectory from the Visual Leak Detector installation
- directory to the system PATH environment variable. Also, dbghelp.dll will probably
- need to be manually copied to the directory where the program being debugged resides. Otherwise the system may
- not find the required DLLs when running VLD.
+ bin subdirectory from the Visual Leak Detector installation directory to the system
+ PATH environment variable. Also, dbghelp.dll will probably need to be manually copied
+ to the directory where the program being debugged resides. Otherwise the system may not find the required DLLs when
+ running VLD.
- If more than one copy of the same C Runtime DLL is loaded in the process at the same time, then some leaks may
go undetected (note that loading more than one copy of the C Runtime DLL at the same time is probably a bad idea
@@ -678,6 +690,15 @@
+
Contributing
+
+I encourage developers who've added their own features, or fixed bugs they've found, to contribute to the project.
+ The full version-controlled source tree is available publicly via Git at the URL below. Feel free to clone from this
+ URL and submit patches for consideration for inclusion in future versions. You can also hop onto
+ GitHub (accounts are free) and issue pull requests for changes that you've made and
+ would like to share.
+
+Git Repository URL: git://github.com/dmoulding/vld.git
License
@@ -733,12 +754,24 @@ BWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbG
+
+
+Additional Developers Wanted
+
+This project is looking for additional developers who have the time, knowledge, and talent, to help make VLD continue
+ to be a useful utility for the Windows developer community. If you feel that you or someone you know would be
+ interested in becoming an active member of the Visual Leak Detector development team, please let me know.
+
+
+
-Copyright © 2005-2006 Dan Moulding
+
+
+Copyright © 2005-2009 Dan Moulding
diff --git a/development/Win32/vld/src/callstack.cpp b/development/Win32/vld/src/callstack.cpp
index 70576941b7..7bcbe5829f 100644
--- a/development/Win32/vld/src/callstack.cpp
+++ b/development/Win32/vld/src/callstack.cpp
@@ -1,8 +1,7 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: callstack.cpp,v 1.20 2006/11/18 03:12:34 dmouldin Exp $
//
// Visual Leak Detector - CallStack Class Implementations
-// Copyright (c) 2005-2006 Dan Moulding
+// Copyright (c) 2005-2009 Dan Moulding
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,7 +23,9 @@
#include
#include
+#ifndef __out_xcount
#define __out_xcount(x) // Workaround for the specstrings.h bug in the Platform SDK.
+#endif
#define DBGHELP_TRANSLATE_TCHAR
#include // Provides symbol handling services.
#define VLDBUILD
diff --git a/development/Win32/vld/src/callstack.h b/development/Win32/vld/src/callstack.h
index b4d3d669a1..e17a530a89 100644
--- a/development/Win32/vld/src/callstack.h
+++ b/development/Win32/vld/src/callstack.h
@@ -1,5 +1,4 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: callstack.h,v 1.10 2006/11/18 03:12:34 dmouldin Exp $
//
// Visual Leak Detector - CallStack Class Definitions
// Copyright (c) 2005-2006 Dan Moulding
@@ -114,4 +113,4 @@ class SafeCallStack : public CallStack
{
public:
VOID getstacktrace (UINT32 maxdepth, SIZE_T *framepointer);
-};
\ No newline at end of file
+};
diff --git a/development/Win32/vld/src/crtmfcpatch.h b/development/Win32/vld/src/crtmfcpatch.h
new file mode 100644
index 0000000000..addcacd6b1
--- /dev/null
+++ b/development/Win32/vld/src/crtmfcpatch.h
@@ -0,0 +1,965 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Visual Leak Detector - CRT and MFC IAT Patch Functions Header
+// Copyright (c) 2009 Dan Moulding
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// See COPYING.txt for the full terms of the GNU Lesser General Public License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#ifndef VLDBUILD
+#error \
+"This header should only be included by Visual Leak Detector when building it from source. \
+Applications should never include this header."
+#endif
+
+#include "vldint.h"
+extern __declspec(dllexport) VisualLeakDetector vld;
+
+#define TEMPLATE_HEADER \
+template
+
+#define TEMPLATE_ARGS \
+ crtddll, mfcddll, mfcuddll,\
+ crtd_vector_new_name, crtd_vector_new_dbg_name,\
+ crtd_scalar_new_name, crtd_scalar_new_dbg_name,\
+ mfcd_vector_new_ordinal, mfcd_vector_new_dbg_4p_ordinal, mfcd_vector_new_dbg_3p_ordinal,\
+ mfcd_scalar_new_ordinal, mfcd_scalar_new_dbg_4p_ordinal, mfcd_scalar_new_dbg_3p_ordinal,\
+ mfcud_vector_new_ordinal, mfcud_vector_new_dbg_4p_ordinal, mfcud_vector_new_dbg_3p_ordinal,\
+ mfcud_scalar_new_ordinal, mfcud_scalar_new_dbg_4p_ordinal, mfcud_scalar_new_dbg_3p_ordinal
+
+TEMPLATE_HEADER
+class CrtMfcPatch
+{
+public:
+ static void* __cdecl crtd__calloc_dbg (size_t num, size_t size, int type, char const *file, int line);
+ static void* __cdecl crtd__malloc_dbg (size_t size, int type, const char *file, int line);
+ static void* __cdecl crtd__realloc_dbg (void *mem, size_t size, int type, char const *file, int line);
+ static void* __cdecl crtd__scalar_new_dbg (size_t size, int type, char const *file, int line);
+ static void* __cdecl crtd__vector_new_dbg (size_t size, int type, char const *file, int line);
+ static void* __cdecl crtd_calloc (size_t num, size_t size);
+ static void* __cdecl crtd_malloc (size_t size);
+ static void* __cdecl crtd_realloc (void *mem, size_t size);
+ static void* __cdecl crtd_scalar_new (size_t size);
+ static void* __cdecl crtd_vector_new (size_t size);
+
+ template
+ static void* __cdecl crtd_new_dbg (SIZE_T fp, size_t size, int type, char const *file, int line);
+ template
+ static void* __cdecl crtd_new (SIZE_T fp, size_t size);
+
+ static void* __cdecl mfcd_vector_new (size_t size);
+ static void* __cdecl mfcd__vector_new_dbg_4p (size_t size, int type, char const *file, int line);
+ static void* __cdecl mfcd__vector_new_dbg_3p (size_t size, char const *file, int line);
+ static void* __cdecl mfcd_scalar_new (size_t size);
+ static void* __cdecl mfcd__scalar_new_dbg_4p (size_t size, int type, char const *file, int line);
+ static void* __cdecl mfcd__scalar_new_dbg_3p (size_t size, char const *file, int line);
+ static void* __cdecl mfcud_vector_new (size_t size);
+ static void* __cdecl mfcud__vector_new_dbg_4p (size_t size, int type, char const *file, int line);
+ static void* __cdecl mfcud__vector_new_dbg_3p (size_t size, char const *file, int line);
+ static void* __cdecl mfcud_scalar_new (size_t size);
+ static void* __cdecl mfcud__scalar_new_dbg_4p (size_t size, int type, char const *file, int line);
+ static void* __cdecl mfcud__scalar_new_dbg_3p (size_t size, char const *file, int line);
+
+ template
+ static void* __cdecl mfcd_new_dbg (SIZE_T fp, size_t size, int type, char const *file, int line);
+ template
+ static void* __cdecl mfcd_new_dbg (SIZE_T fp, size_t size, char const *file, int line);
+ template
+ static void* __cdecl mfcd_new (SIZE_T fp, size_t size);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Visual Studio DLLs
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// crtd__calloc_dbg - Calls to _calloc_dbg from msvcrXXd.dll are patched
+// through to this function.
+//
+// - mem (IN): Pointer to the memory block to be reallocated.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The CRT "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by _calloc_dbg.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::crtd__calloc_dbg (size_t num,
+ size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ static _calloc_dbg_t pcrtxxd__calloc_dbg = NULL;
+
+ SIZE_T fp;
+ HMODULE msvcrxxd;
+
+ FRAMEPOINTER(fp);
+
+ if (pcrtxxd__calloc_dbg == NULL) {
+ // This is the first call to this function. Link to the real
+ // _calloc_dbg.
+ msvcrxxd = GetModuleHandle(crtddll);
+ pcrtxxd__calloc_dbg = (_calloc_dbg_t)GetProcAddress(msvcrxxd, "_calloc_dbg");
+ }
+
+ return vld.__calloc_dbg(pcrtxxd__calloc_dbg, fp, num, size, type, file, line);
+}
+
+// crtd__malloc_dbg - Calls to _malloc_dbg from msvcrXXd.dll are patched
+// through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The CRT "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by _malloc_dbg.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::crtd__malloc_dbg (size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ static _malloc_dbg_t pcrtxxd__malloc_dbg = NULL;
+
+ SIZE_T fp;
+ HMODULE msvcrxxd;
+
+ FRAMEPOINTER(fp);
+
+ if (pcrtxxd__malloc_dbg == NULL) {
+ // This is the first call to this function. Link to the real
+ // _malloc_dbg.
+ msvcrxxd = GetModuleHandle(crtddll);
+ pcrtxxd__malloc_dbg = (_malloc_dbg_t)GetProcAddress(msvcrxxd, "_malloc_dbg");
+ }
+
+ return vld.__malloc_dbg(pcrtxxd__malloc_dbg, fp, size, type, file, line);
+}
+
+// crtd__realloc_dbg - Calls to _realloc_dbg from msvcrXXd.dll are patched
+// through to this function.
+//
+// - mem (IN): Pointer to the memory block to be reallocated.
+//
+// - size (IN): The size of the memory block to reallocate.
+//
+// - type (IN): The CRT "use type" of the block to be reallocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by _realloc_dbg.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::crtd__realloc_dbg (void *mem,
+ size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ static _realloc_dbg_t pcrtxxd__realloc_dbg = NULL;
+
+ SIZE_T fp;
+ HMODULE msvcrxxd;
+
+ FRAMEPOINTER(fp);
+
+ if (pcrtxxd__realloc_dbg == NULL) {
+ // This is the first call to this function. Link to the real
+ // _realloc_dbg.
+ msvcrxxd = GetModuleHandle(crtddll);
+ pcrtxxd__realloc_dbg = (_realloc_dbg_t)GetProcAddress(msvcrxxd, "_realloc_dbg");
+ }
+
+ return vld.__realloc_dbg(pcrtxxd__realloc_dbg, fp, mem, size, type, file, line);
+}
+
+// crtd__scalar_new_dbg - Calls to the CRT's debug scalar new operator from
+// msvcrXXd.dll are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The CRT "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the CRT debug scalar new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::crtd__scalar_new_dbg (size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return crtd_new_dbg(fp, size, type, file, line);
+}
+
+// crtd__vector_new_dbg - Calls to the CRT's debug vector new operator from
+// msvcrXXd.dll are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The CRT "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the CRT debug vector new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::crtd__vector_new_dbg (size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return crtd_new_dbg(fp, size, type, file, line);
+}
+
+// crtd_calloc - Calls to calloc from msvcrXXd.dll are patched through to
+// this function.
+//
+// - dll (IN): The name of the dll
+//
+// - num (IN): The number of blocks, of size 'size', to be allocated.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the valued returned from calloc.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::crtd_calloc (size_t num, size_t size)
+{
+ static calloc_t pcrtxxd_calloc = NULL;
+
+ SIZE_T fp;
+ HMODULE msvcrxxd;
+
+ FRAMEPOINTER(fp);
+
+ if (pcrtxxd_calloc == NULL) {
+ // This is the first call to this function. Link to the real malloc.
+ msvcrxxd = GetModuleHandle(crtddll);
+ pcrtxxd_calloc = (calloc_t)GetProcAddress(msvcrxxd, "calloc");
+ }
+
+ return vld._calloc(pcrtxxd_calloc, fp, num, size);
+}
+
+// crtd_malloc - Calls to malloc from msvcrXXd.dll are patched through to
+// this function.
+//
+// - dll (IN): The name of the dll
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the valued returned from malloc.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::crtd_malloc (size_t size)
+{
+ static malloc_t pcrtxxd_malloc = NULL;
+
+ SIZE_T fp;
+ HMODULE msvcrxxd;
+
+ FRAMEPOINTER(fp);
+
+ if (pcrtxxd_malloc == NULL) {
+ // This is the first call to this function. Link to the real malloc.
+ msvcrxxd = GetModuleHandle(crtddll);
+ pcrtxxd_malloc = (malloc_t)GetProcAddress(msvcrxxd, "malloc");
+ }
+
+ return vld._malloc(pcrtxxd_malloc, fp, size);
+}
+
+// crtd_realloc - Calls to realloc from msvcrXXd.dll are patched through to
+// this function.
+//
+// - dll (IN): The name of the dll
+//
+// - mem (IN): Pointer to the memory block to reallocate.
+//
+// - size (IN): Size of the memory block to reallocate.
+//
+// Return Value:
+//
+// Returns the value returned from realloc.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::crtd_realloc (void *mem, size_t size)
+{
+ static realloc_t pcrtxxd_realloc = NULL;
+
+ SIZE_T fp;
+ HMODULE msvcrxxd;
+
+ FRAMEPOINTER(fp);
+
+ if (pcrtxxd_realloc == NULL) {
+ // This is the first call to this function. Link to the real realloc.
+ msvcrxxd = GetModuleHandle(crtddll);
+ pcrtxxd_realloc = (realloc_t)GetProcAddress(msvcrxxd, "realloc");
+ }
+
+ return vld._realloc(pcrtxxd_realloc, fp, mem, size);
+}
+
+// crtd_scalar_new - Calls to the CRT's scalar new operator from msvcrXXd.dll
+// are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the value returned by the CRT scalar new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::crtd_scalar_new (size_t size)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return crtd_new(fp, size);
+}
+
+// crtd_vector_new - Calls to the CRT's vector new operator from msvcrXXd.dll
+// are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the value returned by the CRT vector new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::crtd_vector_new (size_t size)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return crtd_new(fp, size);
+}
+
+// crtd_new_dbg - A template function for implementation of patch functions to
+// the CRT's debug new operator from msvcrXXd.dll
+//
+// - procname (IN): The debug new operator's name
+//
+// - fp (IN): Frame pointer from the call that initiated this allocation.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The CRT "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the CRT debug new operator.
+//
+TEMPLATE_HEADER
+template
+void* CrtMfcPatch::crtd_new_dbg (SIZE_T fp,
+ size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ static new_dbg_crt_t pcrtxxd_new_dbg = NULL;
+
+ HMODULE msvcrxxd;
+
+ if (pcrtxxd_new_dbg == NULL) {
+ // This is the first call to this function. Link to the real CRT debug
+ // new operator.
+ msvcrxxd = GetModuleHandle(crtddll);
+ pcrtxxd_new_dbg = (new_dbg_crt_t)GetProcAddress(msvcrxxd, procname);
+ }
+
+ return vld.new_dbg_crt(pcrtxxd_new_dbg, fp, size, type, file, line);
+}
+
+// crt_new - A template function for implementing patch functions to the
+// CRT's new operator from msvcrXXd.dll
+//
+// - dll (IN): The name of the dll
+//
+// - procname (IN): The debug new operator's name
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the value returned by the CRT new operator.
+//
+TEMPLATE_HEADER
+template
+void* CrtMfcPatch::crtd_new (SIZE_T fp, size_t size)
+{
+ static new_t pcrtxxd_scalar_new = NULL;
+
+ HMODULE msvcrxxd;
+
+ if (pcrtxxd_scalar_new == NULL) {
+ // This is the first call to this function. Link to the real CRT new
+ // operator.
+ msvcrxxd = GetModuleHandle(crtddll);
+ pcrtxxd_scalar_new = (new_t)GetProcAddress(msvcrxxd, procname);
+ }
+
+ return vld._new(pcrtxxd_scalar_new, fp, size);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// MFC DLLs
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// mfcd__scalar_new_dbg_3p - Calls to the MFC debug scalar new operator from
+// mfcXXd.dll are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC debug scalar new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcd__scalar_new_dbg_4p (size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new_dbg
+ (fp, size, type, file, line);
+}
+
+// mfcd__scalar_new_dbg_3p - Calls to the MFC debug scalar new operator from
+// mfcXXd.dll are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC debug scalar new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcd__scalar_new_dbg_3p (size_t size,
+ char const *file,
+ int line)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new_dbg
+ (fp, size, file, line);
+}
+
+// mfcd__vector_new_dbg_4p - Calls to the MFC debug vector new operator from
+// mfcXXd.dll are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC debug vector new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcd__vector_new_dbg_4p (size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new_dbg
+ (fp, size, type, file, line);
+}
+
+// mfcd__vector_new_dbg_3p - Calls to the MFC debug vector new operator from
+// mfcXXd.dll are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC debug vector new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcd__vector_new_dbg_3p (size_t size,
+ char const *file,
+ int line)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new_dbg
+ (fp, size, file, line);
+}
+
+// mfcd_scalar_new - Calls to the MFC scalar new operator from mfcXXd.dll are
+// patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC scalar new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcd_scalar_new (size_t size)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new(fp, size);
+}
+
+// mfcd_vector_new - Calls to the MFC vector new operator from mfcXXd.dll are
+// patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC vector new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcd_vector_new (size_t size)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new(fp, size);
+}
+
+// mfcud__scalar_new_dbg_4p - Calls to the MFC debug scalar new operator from
+// mfcXXud.dll are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC debug scalar new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcud__scalar_new_dbg_4p (size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new_dbg
+ (fp, size, type, file, line);
+}
+
+// mfcud__scalar_new_dbg_3p - Calls to the MFC debug scalar new operator from
+// mfcXXud.dll are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC debug scalar new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcud__scalar_new_dbg_3p (size_t size,
+ char const *file,
+ int line)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new_dbg
+ (fp, size, file, line);
+}
+
+// mfcud__vector_new_dbg_4p - Calls to the MFC debug vector new operator from
+// mfcXXud.dll are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC debug vector new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcud__vector_new_dbg_4p (size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new_dbg
+ (fp, size, type, file, line);
+}
+
+// mfcud__vector_new_dbg_3p - Calls to the MFC debug vector new operator from
+// mfcXXud.dll are patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC debug vector new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcud__vector_new_dbg_3p (size_t size,
+ char const *file,
+ int line)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new_dbg
+ (fp, size, file, line);
+}
+
+// mfcud_scalar_new - Calls to the MFC scalar new operator from mfcXXud.dll are
+// patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC scalar new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcud_scalar_new (size_t size)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new(fp, size);
+}
+
+// mfcud_vector_new - Calls to the MFC vector new operator from mfcXXud.dll are
+// patched through to this function.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC vector new operator.
+//
+TEMPLATE_HEADER
+void* CrtMfcPatch::mfcud_vector_new (size_t size)
+{
+ SIZE_T fp;
+ FRAMEPOINTER(fp);
+
+ return mfcd_new(fp, size);
+}
+
+// mfcd_new_dbg - A generic function for implementing patch functions to the MFC
+// debug new operators:
+// void* __cdecl operator new[](size_t size, int type, char const *file, int line)
+// void* __cdecl operator new(size_t size, int type, char const *file, int line)
+//
+// - mfcdll (IN): The name of the MFC DLL
+//
+// - ordinal (IN): The debug new operator's ordinal value
+//
+// - type (IN): The "use type" of the block to be allocated.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC debug new operator.
+//
+TEMPLATE_HEADER
+template
+void* CrtMfcPatch::mfcd_new_dbg (SIZE_T fp,
+ size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ static new_dbg_crt_t pmfcxxd__new_dbg = NULL;
+
+ HMODULE mfcxxd;
+
+ if (pmfcxxd__new_dbg == NULL) {
+ // This is the first call to this function. Link to the real MFC debug
+ // new operator.
+ mfcxxd = GetModuleHandle(mfcdll);
+ pmfcxxd__new_dbg = (new_dbg_crt_t)GetProcAddress(mfcxxd, (LPCSTR)ordinal);
+ }
+
+ return vld.new_dbg_mfc(pmfcxxd__new_dbg, fp, size, type, file, line);
+}
+
+// mfcd_new_dbg - A generic function for implementing patch functions to the MFC
+// debug new operators:
+// void* __cdecl operator new[](size_t size, char const *file, int line)
+// void* __cdecl operator new(size_t size, char const *file, int line)
+//
+// - mfcdll (IN): The name of the MFC DLL
+//
+// - ordinal (IN): The debug new operator's ordinal value
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC debug new operator.
+//
+TEMPLATE_HEADER
+template
+void* CrtMfcPatch::mfcd_new_dbg (SIZE_T fp,
+ size_t size,
+ char const *file,
+ int line)
+{
+ static new_dbg_mfc_t pmfcxxd__new_dbg = NULL;
+
+ HMODULE mfcxxd;
+
+ if (pmfcxxd__new_dbg == NULL) {
+ // This is the first call to this function. Link to the real MFC debug
+ // new operator.
+ mfcxxd = GetModuleHandle(mfcdll);
+ pmfcxxd__new_dbg = (new_dbg_mfc_t)GetProcAddress(mfcxxd, (LPCSTR)ordinal);
+ }
+
+ return vld.new_dbg_mfc(pmfcxxd__new_dbg, fp, size, file, line);
+}
+
+// mfcd_new - A generic function for implementing patch functions to the MFC new
+// operators.
+//
+// - mfcdll (IN): The name of the MFC DLL
+//
+// - ordinal (IN): The new operator's ordinal value
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the value returned by the MFC new operator.
+//
+TEMPLATE_HEADER
+template
+void* CrtMfcPatch::mfcd_new (SIZE_T fp, size_t size)
+{
+ static new_t pmfcxxd_new = NULL;
+
+ HMODULE mfcxxd;
+
+ if (pmfcxxd_new == NULL) {
+ // This is the first call to this function. Link to the real CRT new
+ // operator.
+ mfcxxd = GetModuleHandle(mfcdll);
+ pmfcxxd_new = (new_t)GetProcAddress(mfcxxd, (LPCSTR)ordinal);
+ }
+
+ return vld._new(pmfcxxd_new, fp, size);
+}
+
+#undef TEMPLATE_HEADER
+#undef TEMPLATE_ARGS
+
+const extern char scalar_new_dbg_name[] = "??2@YAPAXIHPBDH@Z";
+const extern char vector_new_dbg_name[] = "??_U@YAPAXIHPBDH@Z";
+const extern char scalar_new_name[] = "??2@YAPAXI@Z";
+const extern char vector_new_name[] = "??_U@YAPAXI@Z";
+const extern wchar_t msvcrtd_dll[] = L"msvcrtd.dll";
+const extern wchar_t mfc42d_dll[] = L"mfc42d.dll";
+const extern wchar_t mfc42ud_dll[] = L"mfc42ud.dll";
+const extern wchar_t msvcr70d_dll[] = L"msvcr70d.dll";
+const extern wchar_t mfc70d_dll[] = L"mfc70d.dll";
+const extern wchar_t mfc70ud_dll[] = L"mfc70ud.dll";
+const extern wchar_t msvcr71d_dll[] = L"msvcr71d.dll";
+const extern wchar_t mfc71d_dll[] = L"mfc71d.dll";
+const extern wchar_t mfc71ud_dll[] = L"mfc71ud.dll";
+const extern wchar_t msvcr80d_dll[] = L"msvcr80d.dll";
+const extern wchar_t mfc80d_dll[] = L"mfc80d.dll";
+const extern wchar_t mfc80ud_dll[] = L"mfc80ud.dll";
+const extern wchar_t msvcr90d_dll[] = L"msvcr90d.dll";
+const extern wchar_t mfc90d_dll[] = L"mfc90d.dll";
+const extern wchar_t mfc90ud_dll[] = L"mfc90ud.dll";
+const extern wchar_t msvcr100d_dll[] = L"msvcr100d.dll";
+const extern wchar_t mfc100d_dll[] = L"mfc100d.dll";
+const extern wchar_t mfc100ud_dll[] = L"mfc100ud.dll";
+
+// Visual Studio 6.0
+typedef CrtMfcPatch
+ VS60;
+// Visual Studio .NET 2002
+typedef CrtMfcPatch
+ VS70;
+// Visual Studio .NET 2003
+typedef CrtMfcPatch
+ VS71;
+// Visual Studio 2005
+typedef CrtMfcPatch
+ VS80;
+// Visual Studio 2008
+typedef CrtMfcPatch
+ VS90;
+
+// Visual Studio 2010
+typedef CrtMfcPatch
+ VS100;
\ No newline at end of file
diff --git a/development/Win32/vld/src/map.h b/development/Win32/vld/src/map.h
index 8f065494bd..c1c8b137f2 100644
--- a/development/Win32/vld/src/map.h
+++ b/development/Win32/vld/src/map.h
@@ -1,5 +1,4 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: map.h,v 1.10 2006/11/18 03:12:34 dmouldin Exp $
//
// Visual Leak Detector - Lightweight STL-like Map Template
// Copyright (c) 2006 Dan Moulding
diff --git a/development/Win32/vld/src/ntapi.cpp b/development/Win32/vld/src/ntapi.cpp
index 278d722787..e07d1b4942 100644
--- a/development/Win32/vld/src/ntapi.cpp
+++ b/development/Win32/vld/src/ntapi.cpp
@@ -1,5 +1,4 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: ntapi.cpp,v 1.7 2006/11/18 03:12:34 dmouldin Exp $
//
// Visual Leak Detector - Global NT API Function Pointers
// Copyright (c) 2006 Dan Moulding
@@ -30,4 +29,4 @@
LdrLoadDll_t LdrLoadDll;
RtlAllocateHeap_t RtlAllocateHeap;
RtlFreeHeap_t RtlFreeHeap;
-RtlReAllocateHeap_t RtlReAllocateHeap;
\ No newline at end of file
+RtlReAllocateHeap_t RtlReAllocateHeap;
diff --git a/development/Win32/vld/src/ntapi.h b/development/Win32/vld/src/ntapi.h
index 26add1e8da..6d7ad67e63 100644
--- a/development/Win32/vld/src/ntapi.h
+++ b/development/Win32/vld/src/ntapi.h
@@ -1,8 +1,7 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: ntapi.h,v 1.8 2006/11/18 03:12:35 dmouldin Exp $
//
// Visual Leak Detector - NT API Definitions
-// Copyright (c) 2006 Dan Moulding
+// Copyright (c) 2006-2009 Dan Moulding
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -33,7 +32,7 @@ Applications should never include this header."
#include
// Return code type used by LdrLoadDll.
-typedef ULONG NTSTATUS;
+typedef LONG NTSTATUS;
#define STATUS_SUCCESS 0
// Unicode string structure used by NT APIs.
diff --git a/development/Win32/vld/src/resource.h b/development/Win32/vld/src/resource.h
new file mode 100644
index 0000000000..c6b72e6ec8
--- /dev/null
+++ b/development/Win32/vld/src/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by vld.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/development/Win32/vld/src/set.h b/development/Win32/vld/src/set.h
index cfab1b163c..fdeba5c604 100644
--- a/development/Win32/vld/src/set.h
+++ b/development/Win32/vld/src/set.h
@@ -1,5 +1,4 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: set.h,v 1.9 2006/11/18 03:12:35 dmouldin Exp $
//
// Visual Leak Detector - Lightweight STL-like Set Template
// Copyright (c) 2006 Dan Moulding
diff --git a/development/Win32/vld/src/tree.h b/development/Win32/vld/src/tree.h
index 766104ee8e..ca1680f998 100644
--- a/development/Win32/vld/src/tree.h
+++ b/development/Win32/vld/src/tree.h
@@ -1,5 +1,4 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: tree.h,v 1.13 2006/11/18 03:12:35 dmouldin Exp $
//
// Visual Leak Detector - Red-black Tree Template
// Copyright (c) 2005-2006 Dan Moulding
diff --git a/development/Win32/vld/src/utility.cpp b/development/Win32/vld/src/utility.cpp
index e2fbddd6d7..3048ba2932 100644
--- a/development/Win32/vld/src/utility.cpp
+++ b/development/Win32/vld/src/utility.cpp
@@ -1,8 +1,7 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: utility.cpp,v 1.24 2006/11/18 03:12:35 dmouldin Exp $
//
// Visual Leak Detector - Various Utility Functions
-// Copyright (c) 2005-2006 Dan Moulding
+// Copyright (c) 2005-2009 Dan Moulding
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,7 +24,12 @@
#include
#include
#include
+#if _WIN32_WINNT > 0x0600 // Windows XP or earlier, no GetProcessIdOfThread()
+#include
+#endif
+#ifndef __out_xcount
#define __out_xcount(x) // Workaround for the specstrings.h bug in the Platform SDK.
+#endif
#define DBGHELP_TRANSLATE_TCHAR
#include // Provides portable executable (PE) image access functions.
#define VLDBUILD // Declares that we are building Visual Leak Detector.
@@ -779,3 +783,58 @@ BOOL strtobool (LPCWSTR s) {
return FALSE;
}
}
+
+// _GetProcessIdOfThread - Returns the ID of the process owns the thread.
+//
+// - thread (IN): The handle to the thread.
+//
+// Return Value:
+//
+// Returns the ID of the process that owns the thread. Otherwise returns 0.
+//
+DWORD _GetProcessIdOfThread (HANDLE thread)
+{
+ typedef struct _CLIENT_ID {
+ HANDLE UniqueProcess;
+ HANDLE UniqueThread;
+ } CLIENT_ID, *PCLIENT_ID;
+
+ typedef LONG NTSTATUS;
+ typedef LONG KPRIORITY;
+
+ typedef struct _THREAD_BASIC_INFORMATION {
+ NTSTATUS ExitStatus;
+ PVOID TebBaseAddress;
+ CLIENT_ID ClientId;
+ KAFFINITY AffinityMask;
+ KPRIORITY Priority;
+ KPRIORITY BasePriority;
+ } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
+
+ const static THREADINFOCLASS ThreadBasicInformation = (THREADINFOCLASS)0;
+
+ typedef NTSTATUS (WINAPI *PNtQueryInformationThread) (HANDLE thread,
+ THREADINFOCLASS infoclass, PVOID buffer, ULONG buffersize,
+ PULONG used);
+
+ static PNtQueryInformationThread NtQueryInformationThread = NULL;
+
+ THREAD_BASIC_INFORMATION tbi;
+ NTSTATUS status;
+ HMODULE ntdll;
+ if (NtQueryInformationThread == NULL) {
+ ntdll = GetModuleHandle(L"ntdll.dll");
+ NtQueryInformationThread = (PNtQueryInformationThread)GetProcAddress(ntdll, "NtQueryInformationThread");
+ if (NtQueryInformationThread == NULL) {
+ return 0;
+ }
+ }
+
+ status = NtQueryInformationThread(thread, ThreadBasicInformation, &tbi, sizeof(tbi), NULL);
+ if(status < 0) {
+ // Shall we go through all the trouble of setting last error?
+ return 0;
+ }
+
+ return (DWORD)tbi.ClientId.UniqueProcess;
+}
diff --git a/development/Win32/vld/src/utility.h b/development/Win32/vld/src/utility.h
index 2c85b9255d..ac9f348a91 100644
--- a/development/Win32/vld/src/utility.h
+++ b/development/Win32/vld/src/utility.h
@@ -1,5 +1,4 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: utility.h,v 1.19 2006/11/18 03:12:35 dmouldin Exp $
//
// Visual Leak Detector - Various Utility Definitions
// Copyright (c) 2005-2006 Dan Moulding
@@ -59,7 +58,7 @@ Applications should never include this header."
#endif // _M_IX86
#if defined(_M_IX86) || defined (_M_X64)
-#define FRAMEPOINTER(fp) __asm mov fp, BPREG // Copies the current frame pointer to the supplied variable.
+#define FRAMEPOINTER(fp) __asm {mov fp, BPREG} // Copies the current frame pointer to the supplied variable.
#else
// If you want to retarget Visual Leak Detector to another processor
// architecture then you'll need to provide an architecture-specific macro to
@@ -107,3 +106,7 @@ VOID setreportencoding (encoding_e encoding);
VOID setreportfile (FILE *file, BOOL copydebugger);
VOID strapp (LPWSTR *dest, LPCWSTR source);
BOOL strtobool (LPCWSTR s);
+#if _WIN32_WINNT < 0x0600 // Windows XP or earlier, no GetProcessIdOfThread()
+DWORD _GetProcessIdOfThread (HANDLE thread);
+#define GetProcessIdOfThread _GetProcessIdOfThread
+#endif
\ No newline at end of file
diff --git a/development/Win32/vld/src/vld.cpp b/development/Win32/vld/src/vld.cpp
index ffaa43ac71..797a89401f 100644
--- a/development/Win32/vld/src/vld.cpp
+++ b/development/Win32/vld/src/vld.cpp
@@ -1,8 +1,7 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: vld.cpp,v 1.69 2006/11/18 05:07:04 dmouldin Exp $
//
// Visual Leak Detector - VisualLeakDetector Class Implementation
-// Copyright (c) 2005-2006 Dan Moulding
+// Copyright (c) 2005-2009 Dan Moulding
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -29,17 +28,20 @@
#include
#include
#include
+#ifndef __out_xcount
#define __out_xcount(x) // Workaround for the specstrings.h bug in the Platform SDK.
+#endif
#define DBGHELP_TRANSLATE_TCHAR
-#include // Provides symbol handling services.
-#define VLDBUILD // Declares that we are building Visual Leak Detector.
-#include "callstack.h" // Provides a class for handling call stacks.
-#include "map.h" // Provides a lightweight STL-like map template.
-#include "ntapi.h" // Provides access to NT APIs.
-#include "set.h" // Provides a lightweight STL-like set template.
-#include "utility.h" // Provides various utility functions.
-#include "vldheap.h" // Provides internal new and delete operators.
-#include "vldint.h" // Provides access to the Visual Leak Detector internals.
+#include // Provides symbol handling services.
+#define VLDBUILD // Declares that we are building Visual Leak Detector.
+#include "callstack.h" // Provides a class for handling call stacks.
+#include "crtmfcpatch.h" // Provides CRT and MFC patch functions.
+#include "map.h" // Provides a lightweight STL-like map template.
+#include "ntapi.h" // Provides access to NT APIs.
+#include "set.h" // Provides a lightweight STL-like set template.
+#include "utility.h" // Provides various utility functions.
+#include "vldheap.h" // Provides internal new and delete operators.
+#include "vldint.h" // Provides access to the Visual Leak Detector internals.
#define BLOCKMAPRESERVE 64 // This should strike a balance between memory use and a desire to minimize heap hits.
#define HEAPMAPRESERVE 2 // Usually there won't be more than a few heaps in the process, so this should be small.
@@ -57,57 +59,15 @@ HANDLE currentthread; // Pseudo-handle for the current thread.
CRITICAL_SECTION imagelock; // Serializes calls to the Debug Help Library PE image access APIs.
HANDLE processheap; // Handle to the process's heap (COM allocations come from here).
CRITICAL_SECTION stackwalklock; // Serializes calls to StackWalk64 from the Debug Help Library.
-CRITICAL_SECTION symbollock; // Serializes calls to the Debug Help Library symbold handling APIs.
+CRITICAL_SECTION symbollock; // Serializes calls to the Debug Help Library symbols handling APIs.
-// Function pointer types for explicit dynamic linking with functions listed in
-// the import patch table.
-typedef void* (__cdecl *_calloc_dbg_t) (size_t, size_t, int, const char*, int);
-typedef void* (__cdecl *_malloc_dbg_t) (size_t, int, const char *, int);
-typedef void* (__cdecl *_realloc_dbg_t) (void *, size_t, int, const char *, int);
-typedef void* (__cdecl *calloc_t) (size_t, size_t);
-typedef HRESULT (__stdcall *CoGetMalloc_t) (DWORD, LPMALLOC *);
-typedef LPVOID (__stdcall *CoTaskMemAlloc_t) (ULONG);
-typedef LPVOID (__stdcall *CoTaskMemRealloc_t) (LPVOID, ULONG);
-typedef void* (__cdecl *crt_new_dbg_t) (unsigned int, int, const char *, int);
-typedef void* (__cdecl *malloc_t) (size_t);
-typedef void* (__cdecl *mfc_new_dbg_t) (unsigned int, const char *, int);
-typedef void* (__cdecl *new_t) (unsigned int);
-typedef void* (__cdecl *realloc_t) (void *, size_t);
+// The one and only VisualLeakDetector object instance.
+__declspec(dllexport) VisualLeakDetector vld;
// Global function pointers for explicit dynamic linking with functions listed
// in the import patch table. Using explicit dynamic linking minimizes VLD's
// footprint by loading only modules that are actually used. These pointers will
// be linked to the real functions the first time they are used.
-static CoGetMalloc_t pCoGetMalloc = NULL;
-static CoTaskMemAlloc_t pCoTaskMemAlloc = NULL;
-static CoTaskMemRealloc_t pCoTaskMemRealloc = NULL;
-static _calloc_dbg_t pcrt80d__calloc_dbg = NULL;
-static _malloc_dbg_t pcrt80d__malloc_dbg = NULL;
-static _realloc_dbg_t pcrt80d__realloc_dbg = NULL;
-static crt_new_dbg_t pcrt80d__scalar_new_dbg = NULL;
-static crt_new_dbg_t pcrt80d__vector_new_dbg = NULL;
-static calloc_t pcrt80d_calloc = NULL;
-static malloc_t pcrt80d_malloc = NULL;
-static realloc_t pcrt80d_realloc = NULL;
-static new_t pcrt80d_scalar_new = NULL;
-static new_t pcrt80d_vector_new = NULL;
-static _calloc_dbg_t pcrtd__calloc_dbg = NULL;
-static _malloc_dbg_t pcrtd__malloc_dbg = NULL;
-static _realloc_dbg_t pcrtd__realloc_dbg = NULL;
-static crt_new_dbg_t pcrtd__scalar_new_dbg = NULL;
-static calloc_t pcrtd_calloc = NULL;
-static malloc_t pcrtd_malloc = NULL;
-static realloc_t pcrtd_realloc = NULL;
-static new_t pcrtd_scalar_new = NULL;
-static mfc_new_dbg_t pmfc42d__scalar_new_dbg = NULL;
-static new_t pmfc42d_scalar_new = NULL;
-static mfc_new_dbg_t pmfc80d__scalar_new_dbg = NULL;
-static mfc_new_dbg_t pmfc80d__vector_new_dbg = NULL;
-static new_t pmfc80d_scalar_new = NULL;
-static new_t pmfc80d_vector_new = NULL;
-
-// The one and only VisualLeakDetector object instance.
-__declspec(dllexport) VisualLeakDetector vld;
// The import patch table: lists the heap-related API imports that VLD patches
// through to replacement functions provided by VLD. Having this table simply
@@ -122,34 +82,135 @@ patchentry_t VisualLeakDetector::m_patchtable [] = {
"kernel32.dll", "HeapReAlloc", 0x0, _RtlReAllocateHeap,
// MFC new operators (exported by ordinal).
- "mfc42d.dll", (LPCSTR)714, 0x0, _mfc42d__scalar_new_dbg,
- "mfc42d.dll", (LPCSTR)711, 0x0, _mfc42d_scalar_new,
- // XXX MFC 7.x DLL new operators still need to be added to this
- // table, but I don't know their ordinals.
- "mfc80d.dll", (LPCSTR)895, 0x0, _mfc80d__scalar_new_dbg,
- "mfc80d.dll", (LPCSTR)269, 0x0, _mfc80d__vector_new_dbg,
- "mfc80d.dll", (LPCSTR)893, 0x0, _mfc80d_scalar_new,
- "mfc80d.dll", (LPCSTR)267, 0x0, _mfc80d_vector_new,
+ // XXX why are the vector new operators missing for mfc42d.dll?
+ "mfc42d.dll", (LPCSTR)711, 0x0, VS60::mfcd_scalar_new,
+ "mfc42d.dll", (LPCSTR)712, 0x0, VS60::mfcd__scalar_new_dbg_4p,
+ "mfc42d.dll", (LPCSTR)714, 0x0, VS60::mfcd__scalar_new_dbg_3p,
+ "mfc42ud.dll", (LPCSTR)711, 0x0, VS60::mfcud_scalar_new,
+ "mfc42ud.dll", (LPCSTR)712, 0x0, VS60::mfcud__scalar_new_dbg_4p,
+ "mfc42ud.dll", (LPCSTR)714, 0x0, VS60::mfcud__scalar_new_dbg_3p,
+ "mfc70d.dll", (LPCSTR)257, 0x0, VS70::mfcd_vector_new,
+ "mfc70d.dll", (LPCSTR)258, 0x0, VS70::mfcd__vector_new_dbg_4p,
+ "mfc70d.dll", (LPCSTR)259, 0x0, VS70::mfcd__vector_new_dbg_3p,
+ "mfc70d.dll", (LPCSTR)832, 0x0, VS70::mfcd_scalar_new,
+ "mfc70d.dll", (LPCSTR)833, 0x0, VS70::mfcd__scalar_new_dbg_4p,
+ "mfc70d.dll", (LPCSTR)834, 0x0, VS70::mfcd__scalar_new_dbg_3p,
+ "mfc70ud.dll", (LPCSTR)258, 0x0, VS70::mfcud_vector_new,
+ "mfc70ud.dll", (LPCSTR)259, 0x0, VS70::mfcud__vector_new_dbg_4p,
+ "mfc70ud.dll", (LPCSTR)260, 0x0, VS70::mfcud__vector_new_dbg_3p,
+ "mfc70ud.dll", (LPCSTR)833, 0x0, VS70::mfcud_scalar_new,
+ "mfc70ud.dll", (LPCSTR)834, 0x0, VS70::mfcud__scalar_new_dbg_4p,
+ "mfc70ud.dll", (LPCSTR)835, 0x0, VS70::mfcud__scalar_new_dbg_3p,
+ "mfc71d.dll", (LPCSTR)267, 0x0, VS71::mfcd_vector_new,
+ "mfc71d.dll", (LPCSTR)268, 0x0, VS71::mfcd__vector_new_dbg_4p,
+ "mfc71d.dll", (LPCSTR)269, 0x0, VS71::mfcd__vector_new_dbg_3p,
+ "mfc71d.dll", (LPCSTR)893, 0x0, VS71::mfcd_scalar_new,
+ "mfc71d.dll", (LPCSTR)894, 0x0, VS71::mfcd__scalar_new_dbg_4p,
+ "mfc71d.dll", (LPCSTR)895, 0x0, VS71::mfcd__scalar_new_dbg_3p,
+ "mfc71ud.dll", (LPCSTR)267, 0x0, VS71::mfcud_vector_new,
+ "mfc71ud.dll", (LPCSTR)268, 0x0, VS71::mfcud__vector_new_dbg_4p,
+ "mfc71ud.dll", (LPCSTR)269, 0x0, VS71::mfcud__vector_new_dbg_3p,
+ "mfc71ud.dll", (LPCSTR)893, 0x0, VS71::mfcud_scalar_new,
+ "mfc71ud.dll", (LPCSTR)894, 0x0, VS71::mfcud__scalar_new_dbg_4p,
+ "mfc71ud.dll", (LPCSTR)895, 0x0, VS71::mfcud__scalar_new_dbg_3p,
+ "mfc80d.dll", (LPCSTR)267, 0x0, VS80::mfcd_vector_new,
+ "mfc80d.dll", (LPCSTR)268, 0x0, VS80::mfcd__vector_new_dbg_4p,
+ "mfc80d.dll", (LPCSTR)269, 0x0, VS80::mfcd__vector_new_dbg_3p,
+ "mfc80d.dll", (LPCSTR)893, 0x0, VS80::mfcd_scalar_new,
+ "mfc80d.dll", (LPCSTR)894, 0x0, VS80::mfcd__scalar_new_dbg_4p,
+ "mfc80d.dll", (LPCSTR)895, 0x0, VS80::mfcd__scalar_new_dbg_3p,
+ "mfc80ud.dll", (LPCSTR)267, 0x0, VS80::mfcud_vector_new,
+ "mfc80ud.dll", (LPCSTR)268, 0x0, VS80::mfcud__vector_new_dbg_4p,
+ "mfc80ud.dll", (LPCSTR)269, 0x0, VS80::mfcud__vector_new_dbg_3p,
+ "mfc80ud.dll", (LPCSTR)893, 0x0, VS80::mfcud_scalar_new,
+ "mfc80ud.dll", (LPCSTR)894, 0x0, VS80::mfcud__scalar_new_dbg_4p,
+ "mfc80ud.dll", (LPCSTR)895, 0x0, VS80::mfcud__scalar_new_dbg_3p,
+ "mfc90d.dll", (LPCSTR)267, 0x0, VS90::mfcd_vector_new,
+ "mfc90d.dll", (LPCSTR)268, 0x0, VS90::mfcd__vector_new_dbg_4p,
+ "mfc90d.dll", (LPCSTR)269, 0x0, VS90::mfcd__vector_new_dbg_3p,
+ "mfc90d.dll", (LPCSTR)931, 0x0, VS90::mfcd_scalar_new,
+ "mfc90d.dll", (LPCSTR)932, 0x0, VS90::mfcd__scalar_new_dbg_4p,
+ "mfc90d.dll", (LPCSTR)933, 0x0, VS90::mfcd__scalar_new_dbg_3p,
+ "mfc90ud.dll", (LPCSTR)267, 0x0, VS90::mfcud_vector_new,
+ "mfc90ud.dll", (LPCSTR)268, 0x0, VS90::mfcud__vector_new_dbg_4p,
+ "mfc90ud.dll", (LPCSTR)269, 0x0, VS90::mfcud__vector_new_dbg_3p,
+ "mfc90ud.dll", (LPCSTR)935, 0x0, VS90::mfcud_scalar_new,
+ "mfc90ud.dll", (LPCSTR)936, 0x0, VS90::mfcud__scalar_new_dbg_4p,
+ "mfc90ud.dll", (LPCSTR)937, 0x0, VS90::mfcud__scalar_new_dbg_3p,
+ "mfc100d.dll", (LPCSTR)267, 0x0, VS100::mfcd_vector_new,
+ "mfc100d.dll", (LPCSTR)268, 0x0, VS100::mfcd__vector_new_dbg_4p,
+ "mfc100d.dll", (LPCSTR)269, 0x0, VS100::mfcd__vector_new_dbg_3p,
+ "mfc100d.dll", (LPCSTR)1427, 0x0, VS100::mfcd_scalar_new,
+ "mfc100d.dll", (LPCSTR)1428, 0x0, VS100::mfcd__scalar_new_dbg_4p,
+ "mfc100d.dll", (LPCSTR)1429, 0x0, VS100::mfcd__scalar_new_dbg_3p,
+ "mfc100ud.dll", (LPCSTR)267, 0x0, VS100::mfcud_vector_new,
+ "mfc100ud.dll", (LPCSTR)268, 0x0, VS100::mfcud__vector_new_dbg_4p,
+ "mfc100ud.dll", (LPCSTR)269, 0x0, VS100::mfcud__vector_new_dbg_3p,
+ "mfc100ud.dll", (LPCSTR)1434, 0x0, VS100::mfcud_scalar_new,
+ "mfc100ud.dll", (LPCSTR)1435, 0x0, VS100::mfcud__scalar_new_dbg_4p,
+ "mfc100ud.dll", (LPCSTR)1436, 0x0, VS100::mfcud__scalar_new_dbg_3p,
// CRT new operators and heap APIs.
- "msvcr80d.dll", "_calloc_dbg", 0x0, _crt80d__calloc_dbg,
- "msvcr80d.dll", "_malloc_dbg", 0x0, _crt80d__malloc_dbg,
- "msvcr80d.dll", "_realloc_dbg", 0x0, _crt80d__realloc_dbg,
- "msvcr80d.dll", "??2@YAPAXIHPBDH@Z", 0x0, _crt80d__scalar_new_dbg,
- "msvcr80d.dll", "??_U@YAPAXIHPBDH@Z", 0x0, _crt80d__vector_new_dbg,
- "msvcr80d.dll", "calloc", 0x0, _crt80d_calloc,
- "msvcr80d.dll", "malloc", 0x0, _crt80d_malloc,
- "msvcr80d.dll", "realloc", 0x0, _crt80d_realloc,
- "msvcr80d.dll", "??2@YAPAXI@Z", 0x0, _crt80d_scalar_new,
- "msvcr80d.dll", "??_U@YAPAXI@Z", 0x0, _crt80d_vector_new,
- "msvcrtd.dll", "_calloc_dbg", 0x0, _crtd__calloc_dbg,
- "msvcrtd.dll", "_malloc_dbg", 0x0, _crtd__malloc_dbg,
- "msvcrtd.dll", "??2@YAPAXIHPBDH@Z", 0x0, _crtd__scalar_new_dbg,
- "msvcrtd.dll", "_realloc_dbg", 0x0, _crtd__realloc_dbg,
- "msvcrtd.dll", "calloc", 0x0, _crtd_calloc,
- "msvcrtd.dll", "malloc", 0x0, _crtd_malloc,
- "msvcrtd.dll", "realloc", 0x0, _crtd_realloc,
- "msvcrtd.dll", "??2@YAPAXI@Z", 0x0, _crtd_scalar_new,
+ "msvcrtd.dll", "_calloc_dbg", 0x0, VS60::crtd__calloc_dbg,
+ "msvcrtd.dll", "_malloc_dbg", 0x0, VS60::crtd__malloc_dbg,
+ "msvcrtd.dll", "_realloc_dbg", 0x0, VS60::crtd__realloc_dbg,
+ "msvcrtd.dll", "??2@YAPAXIHPBDH@Z", 0x0, VS60::crtd__scalar_new_dbg,
+// "msvcrtd.dll", "??_U@YAPAXIHPBDH@Z", 0x0, VS60::crtd__vector_new_dbg,
+ "msvcrtd.dll", "calloc", 0x0, VS60::crtd_calloc,
+ "msvcrtd.dll", "malloc", 0x0, VS60::crtd_malloc,
+ "msvcrtd.dll", "realloc", 0x0, VS60::crtd_realloc,
+ "msvcrtd.dll", "??2@YAPAXI@Z", 0x0, VS60::crtd_scalar_new,
+// "msvcrtd.dll", "??_U@YAPAXI@Z", 0x0, VS60::crtd_vector_new,
+ "msvcr70d.dll", "_calloc_dbg", 0x0, VS70::crtd__calloc_dbg,
+ "msvcr70d.dll", "_malloc_dbg", 0x0, VS70::crtd__malloc_dbg,
+ "msvcr70d.dll", "_realloc_dbg", 0x0, VS70::crtd__realloc_dbg,
+ "msvcr70d.dll", "??2@YAPAXIHPBDH@Z", 0x0, VS70::crtd__scalar_new_dbg,
+ "msvcr70d.dll", "??_U@YAPAXIHPBDH@Z", 0x0, VS70::crtd__vector_new_dbg,
+ "msvcr70d.dll", "calloc", 0x0, VS70::crtd_calloc,
+ "msvcr70d.dll", "malloc", 0x0, VS70::crtd_malloc,
+ "msvcr70d.dll", "realloc", 0x0, VS70::crtd_realloc,
+ "msvcr70d.dll", "??2@YAPAXI@Z", 0x0, VS70::crtd_scalar_new,
+ "msvcr70d.dll", "??_U@YAPAXI@Z", 0x0, VS70::crtd_vector_new,
+ "msvcr71d.dll", "_calloc_dbg", 0x0, VS71::crtd__calloc_dbg,
+ "msvcr71d.dll", "_malloc_dbg", 0x0, VS71::crtd__malloc_dbg,
+ "msvcr71d.dll", "_realloc_dbg", 0x0, VS71::crtd__realloc_dbg,
+ "msvcr71d.dll", "??2@YAPAXIHPBDH@Z", 0x0, VS71::crtd__scalar_new_dbg,
+ "msvcr71d.dll", "??_U@YAPAXIHPBDH@Z", 0x0, VS71::crtd__vector_new_dbg,
+ "msvcr71d.dll", "calloc", 0x0, VS71::crtd_calloc,
+ "msvcr71d.dll", "malloc", 0x0, VS71::crtd_malloc,
+ "msvcr71d.dll", "realloc", 0x0, VS71::crtd_realloc,
+ "msvcr71d.dll", "??2@YAPAXI@Z", 0x0, VS71::crtd_scalar_new,
+ "msvcr71d.dll", "??_U@YAPAXI@Z", 0x0, VS71::crtd_vector_new,
+ "msvcr80d.dll", "_calloc_dbg", 0x0, VS80::crtd__calloc_dbg,
+ "msvcr80d.dll", "_malloc_dbg", 0x0, VS80::crtd__malloc_dbg,
+ "msvcr80d.dll", "_realloc_dbg", 0x0, VS80::crtd__realloc_dbg,
+ "msvcr80d.dll", "??2@YAPAXIHPBDH@Z", 0x0, VS80::crtd__scalar_new_dbg,
+ "msvcr80d.dll", "??_U@YAPAXIHPBDH@Z", 0x0, VS80::crtd__vector_new_dbg,
+ "msvcr80d.dll", "calloc", 0x0, VS80::crtd_calloc,
+ "msvcr80d.dll", "malloc", 0x0, VS80::crtd_malloc,
+ "msvcr80d.dll", "realloc", 0x0, VS80::crtd_realloc,
+ "msvcr80d.dll", "??2@YAPAXI@Z", 0x0, VS80::crtd_scalar_new,
+ "msvcr80d.dll", "??_U@YAPAXI@Z", 0x0, VS80::crtd_vector_new,
+ "msvcr90d.dll", "_calloc_dbg", 0x0, VS90::crtd__calloc_dbg,
+ "msvcr90d.dll", "_malloc_dbg", 0x0, VS90::crtd__malloc_dbg,
+ "msvcr90d.dll", "_realloc_dbg", 0x0, VS90::crtd__realloc_dbg,
+ "msvcr90d.dll", "??2@YAPAXIHPBDH@Z", 0x0, VS90::crtd__scalar_new_dbg,
+ "msvcr90d.dll", "??_U@YAPAXIHPBDH@Z", 0x0, VS90::crtd__vector_new_dbg,
+ "msvcr90d.dll", "calloc", 0x0, VS90::crtd_calloc,
+ "msvcr90d.dll", "malloc", 0x0, VS90::crtd_malloc,
+ "msvcr90d.dll", "realloc", 0x0, VS90::crtd_realloc,
+ "msvcr90d.dll", "??2@YAPAXI@Z", 0x0, VS90::crtd_scalar_new,
+ "msvcr90d.dll", "??_U@YAPAXI@Z", 0x0, VS90::crtd_vector_new,
+ "msvcr100d.dll", "_calloc_dbg", 0x0, VS100::crtd__calloc_dbg,
+ "msvcr100d.dll", "_malloc_dbg", 0x0, VS100::crtd__malloc_dbg,
+ "msvcr100d.dll", "_realloc_dbg", 0x0, VS100::crtd__realloc_dbg,
+ "msvcr100d.dll", scalar_new_dbg_name, 0x0, VS100::crtd__scalar_new_dbg,
+ "msvcr100d.dll", vector_new_dbg_name, 0x0, VS100::crtd__vector_new_dbg,
+ "msvcr100d.dll", "calloc", 0x0, VS100::crtd_calloc,
+ "msvcr100d.dll", "malloc", 0x0, VS100::crtd_malloc,
+ "msvcr100d.dll", "realloc", 0x0, VS100::crtd_realloc,
+ "msvcr100d.dll", scalar_new_name, 0x0, VS100::crtd_scalar_new,
+ "msvcr100d.dll", vector_new_name, 0x0, VS100::crtd_vector_new,
// NT APIs.
"ntdll.dll", "RtlAllocateHeap", 0x0, _RtlAllocateHeap,
@@ -330,7 +391,6 @@ VisualLeakDetector::~VisualLeakDetector ()
BlockMap::Iterator blockit;
BlockMap *blockmap;
size_t count;
- DWORD exitcode;
vldblockheader_t *header;
HANDLE heap;
HeapMap::Iterator heapit;
@@ -339,10 +399,10 @@ VisualLeakDetector::~VisualLeakDetector ()
WCHAR leakfilew [MAX_PATH];
int leakline = 0;
ModuleSet::Iterator moduleit;
- SIZE_T sleepcount;
HANDLE thread;
BOOL threadsactive= FALSE;
TlsSet::Iterator tlsit;
+ DWORD dwCurProcessID;
if (m_options & VLD_OPT_VLDOFF) {
// VLD has been turned off.
@@ -353,6 +413,8 @@ VisualLeakDetector::~VisualLeakDetector ()
// Detach Visual Leak Detector from all previously attached modules.
EnumerateLoadedModulesW64(currentprocess, detachfrommodule, NULL);
+ dwCurProcessID = GetCurrentProcessId();
+
// See if any threads that have ever entered VLD's code are still active.
EnterCriticalSection(&m_tlslock);
for (tlsit = m_tlsset->begin(); tlsit != m_tlsset->end(); ++tlsit) {
@@ -361,33 +423,29 @@ VisualLeakDetector::~VisualLeakDetector ()
continue;
}
- sleepcount = 0;
- thread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, (*tlsit)->threadid);
+ thread = OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, (*tlsit)->threadid);
if (thread == NULL) {
// Couldn't query this thread. We'll assume that it exited.
continue; // XXX should we check GetLastError()?
}
- while (GetExitCodeThread(thread, &exitcode) == TRUE) {
- if (exitcode != STILL_ACTIVE) {
- // This thread exited.
- break;
- }
- else {
- // There is still at least one other thread running. The CRT
- // will stomp it dead when it cleans up, which is not a
- // graceful way for a thread to go down. Warn about this,
- // and wait until the thread has exited so that we know it
- // can't still be off running somewhere in VLD's code.
- threadsactive = TRUE;
- Sleep(100);
- sleepcount++;
- if ((sleepcount % 100) == 0) {
- // Just in case this takes a long time, let the human
- // know we are still here and alive.
- report(L"Visual Leak Detector: Waiting for threads to terminate...\n");
- }
- }
+ if (GetProcessIdOfThread(thread) != dwCurProcessID) {
+ //The thread ID has been recycled.
+ CloseHandle(thread);
+ continue;
}
+ while (WaitForSingleObject(thread, 10000) == WAIT_TIMEOUT) { // 10 seconds
+ // There is still at least one other thread running. The CRT
+ // will stomp it dead when it cleans up, which is not a
+ // graceful way for a thread to go down. Warn about this,
+ // and wait until the thread has exited so that we know it
+ // can't still be off running somewhere in VLD's code.
+ //
+ // Since we've been waiting a while, let the human know we are
+ // still here and alive.
+ threadsactive = TRUE;
+ report(L"Visual Leak Detector: Waiting for threads to terminate...\n");
+ }
+ CloseHandle(thread);
}
LeaveCriticalSection(&m_tlslock);
@@ -508,1788 +566,12 @@ VisualLeakDetector::~VisualLeakDetector ()
}
}
-// _CoGetMalloc - Calls to CoGetMalloc are patched through to this function.
-// This function returns a pointer to Visual Leak Detector's implementation
-// of the IMalloc interface, instead of returning a pointer to the system
-// implementation. This allows VLD's implementation of the IMalloc interface
-// (which is basically a thin wrapper around the system implementation) to be
-// invoked in place of the system implementation.
-//
-// - context (IN): Reserved; value must be 1.
-//
-// - imalloc (IN): Address of a pointer to receive the address of VLD's
-// implementation of the IMalloc interface.
-//
-// Return Value:
-//
-// Always returns S_OK.
-//
-HRESULT VisualLeakDetector::_CoGetMalloc (DWORD context, LPMALLOC *imalloc)
-{
- HMODULE ole32;
-
- *imalloc = (LPMALLOC)&vld;
-
- if (pCoGetMalloc == NULL) {
- // This is the first call to this function. Link to the real
- // CoGetMalloc and get a pointer to the system implementation of the
- // IMalloc interface.
- ole32 = GetModuleHandle(L"ole32.dll");
- pCoGetMalloc = (CoGetMalloc_t)GetProcAddress(ole32, "CoGetMalloc");
- pCoGetMalloc(context, &vld.m_imalloc);
- }
-
- return S_OK;
-}
-
-// _CoTaskMemAlloc - Calls to CoTaskMemAlloc are patched through to this
-// function. This function is just a wrapper around the real CoTaskMemAlloc
-// that sets appropriate flags to be consulted when the memory is actually
-// allocated by RtlAllocateHeap.
-//
-// - size (IN): Size of the memory block to allocate.
-//
-// Return Value:
-//
-// Returns the value returned from CoTaskMemAlloc.
-//
-LPVOID VisualLeakDetector::_CoTaskMemAlloc (ULONG size)
-{
- LPVOID block;
- SIZE_T fp;
- HMODULE ole32;
- tls_t *tls = vld.gettls();
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pCoTaskMemAlloc == NULL) {
- // This is the first call to this function. Link to the real
- // CoTaskMemAlloc.
- ole32 = GetModuleHandle(L"ole32.dll");
- pCoTaskMemAlloc = (CoTaskMemAlloc_t)GetProcAddress(ole32, "CoTaskMemAlloc");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pCoTaskMemAlloc(size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _CoTaskMemRealloc - Calls to CoTaskMemRealloc are patched through to this
-// function. This function is just a wrapper around the real CoTaskMemRealloc
-// that sets appropriate flags to be consulted when the memory is actually
-// allocated by RtlAllocateHeap.
-//
-// - mem (IN): Pointer to the memory block to reallocate.
-//
-// - size (IN): Size, in bytes, of the block to reallocate.
-//
-// Return Value:
-//
-// Returns the value returned from CoTaskMemRealloc.
-//
-LPVOID VisualLeakDetector::_CoTaskMemRealloc (LPVOID mem, ULONG size)
-{
- LPVOID block;
- SIZE_T fp;
- HMODULE ole32;
- tls_t *tls = vld.gettls();
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pCoTaskMemRealloc == NULL) {
- // This is the first call to this function. Link to the real
- // CoTaskMemRealloc.
- ole32 = GetModuleHandle(L"ole32.dll");
- pCoTaskMemRealloc = (CoTaskMemRealloc_t)GetProcAddress(ole32, "CoTaskMemRealloc");
- }
-
- // Do the allocation. The block will be mapped by _RtlReAllocateHeap.
- block = pCoTaskMemRealloc(mem, size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crt80d__calloc_dbg - Calls to _calloc_dbg from msvcr80d.dll are patched
-// through to this function. This function is just a wrapper around the real
-// _calloc_dbg that sets appropriate flags to be consulted when the memory is
-// actually allocated by RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// - type (IN): The CRT "use type" of the block to be allocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above file, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by _calloc_dbg.
-//
-void* VisualLeakDetector::_crt80d__calloc_dbg (size_t num, size_t size, int type, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcr80d;
- tls_t *tls = vld.gettls();
-
- // _malloc_dbg is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrt80d__calloc_dbg == NULL) {
- // This is the first call to this function. Link to the real
- // _malloc_dbg.
- msvcr80d = GetModuleHandle(L"msvcr80d.dll");
- pcrt80d__calloc_dbg = (_calloc_dbg_t)GetProcAddress(msvcr80d, "_calloc_dbg");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrt80d__calloc_dbg(num, size, type, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crt80d__malloc_dbg - Calls to _malloc_dbg from msvcr80d.dll are patched
-// through to this function. This function is just a wrapper around the real
-// _malloc_dbg that sets appropriate flags to be consulted when the memory is
-// actually allocated by RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// - type (IN): The CRT "use type" of the block to be allocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above file, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by _malloc_dbg.
-//
-void* VisualLeakDetector::_crt80d__malloc_dbg (size_t size, int type, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcr80d;
- tls_t *tls = vld.gettls();
-
- // _malloc_dbg is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrt80d__malloc_dbg == NULL) {
- // This is the first call to this function. Link to the real
- // _malloc_dbg.
- msvcr80d = GetModuleHandle(L"msvcr80d.dll");
- pcrt80d__malloc_dbg = (_malloc_dbg_t)GetProcAddress(msvcr80d, "_malloc_dbg");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrt80d__malloc_dbg(size, type, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crt80d__realloc_dbg - Calls to _realloc_dbg from msvcr80d.dll are patched
-// through to this function. This function is just a wrapper around the real
-// _realloc_dbg that sets appropriate flags to be consulted when the memory is
-// actually allocated by RtlAllocateHeap.
-//
-// - mem (IN): Pointer to the memory block to be reallocated.
-//
-// - size (IN): The size of the memory block to reallocate.
-//
-// - type (IN): The CRT "use type" of the block to be reallocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above filel, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by _realloc_dbg.
-//
-void* VisualLeakDetector::_crt80d__realloc_dbg (void *mem, size_t size, int type, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcr80d;
- tls_t *tls = vld.gettls();
-
- // _realloc_dbg is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrt80d__realloc_dbg == NULL) {
- // This is the first call to this function. Link to the real
- // _realloc_dbg.
- msvcr80d = GetModuleHandle(L"msvcr80d.dll");
- pcrt80d__realloc_dbg = (_realloc_dbg_t)GetProcAddress(msvcr80d, "_realloc_dbg");
- }
-
- // Do the allocation. The block will be mapped by _RtlReAllocateHeap.
- block = pcrt80d__realloc_dbg(mem, size, type, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crt80d__scalar_new_dbg - Calls to the CRT's debug scalar new operator from
-// msvcr80d.dll are patched through to this function. This function is just a
-// wrapper around the real CRT debug scalar new operator that sets appropriate
-// flags to be consulted when the memory is actually allocated by
-// RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// - type (IN): The CRT "use type" of the block to be allocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above file, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by the CRT debug scalar new operator.
-//
-void* VisualLeakDetector::_crt80d__scalar_new_dbg (unsigned int size, int type, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcr80d;
- tls_t *tls = vld.gettls();
-
- // The debug new operator is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrt80d__scalar_new_dbg == NULL) {
- // This is the first call to this function. Link to the real CRT debug
- // new operator.
- msvcr80d = GetModuleHandle(L"msvcr80d.dll");
- pcrt80d__scalar_new_dbg = (crt_new_dbg_t)GetProcAddress(msvcr80d, "??2@YAPAXIHPBDH@Z");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrt80d__scalar_new_dbg(size, type, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crt80d__vector_new_dbg - Calls to the CRT's debug vector new operator from
-// msvcr80d.dll are patched through to this function. This function is just a
-// wrapper around the real CRT debug vector new operator that sets appropriate
-// flags to be consulted when the memory is actually allocated by
-// RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// - type (IN): The CRT "use type" of the block to be allocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above file, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by the CRT debug vector new operator.
-//
-void* VisualLeakDetector::_crt80d__vector_new_dbg (unsigned int size, int type, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcr80d;
- tls_t *tls = vld.gettls();
-
- // The debug new operator is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrt80d__vector_new_dbg == NULL) {
- // This is the first call to this function. Link to the real CRT debug
- // new operator.
- msvcr80d = GetModuleHandle(L"msvcr80d.dll");
- pcrt80d__vector_new_dbg = (crt_new_dbg_t)GetProcAddress(msvcr80d, "??_U@YAPAXIHPBDH@Z");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrt80d__vector_new_dbg(size, type, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crt80d_calloc - Calls to calloc from msvcr80d.dll are patched through to
-// this function. This function is just a wrapper around the real calloc that
-// sets appropriate flags to be consulted when the memory is actually
-// allocated by RtlAllocateHeap.
-//
-// - num (IN): The number of blocks, of size 'size', to be allocated.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// Return Value:
-//
-// Returns the valued returned from calloc.
-//
-void* VisualLeakDetector::_crt80d_calloc (size_t num, size_t size)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcr80d;
- tls_t *tls = vld.gettls();
-
- // malloc is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrt80d_calloc == NULL) {
- // This is the first call to this function. Link to the real malloc.
- msvcr80d = GetModuleHandle(L"msvcr80d.dll");
- pcrt80d_calloc = (calloc_t)GetProcAddress(msvcr80d, "calloc");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrt80d_calloc(num, size);
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crt80d_malloc - Calls to malloc from msvcr80d.dll are patched through to
-// this function. This function is just a wrapper around the real malloc that
-// sets appropriate flags to be consulted when the memory is actually
-// allocated by RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// Return Value:
-//
-// Returns the valued returned from malloc.
-//
-void* VisualLeakDetector::_crt80d_malloc (size_t size)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcr80d;
- tls_t *tls = vld.gettls();
-
- // malloc is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrt80d_malloc == NULL) {
- // This is the first call to this function. Link to the real malloc.
- msvcr80d = GetModuleHandle(L"msvcr80d.dll");
- pcrt80d_malloc = (malloc_t)GetProcAddress(msvcr80d, "malloc");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrt80d_malloc(size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crt80d_realloc - Calls to realloc from msvcr80d.dll are patched through to
-// this function. This function is just a wrapper around the real realloc that
-// sets appropriate flags to be consulted when the memory is actually
-// allocated by RtlAllocateHeap.
-//
-// - mem (IN): Pointer to the memory block to reallocate.
-//
-// - size (IN): Size of the memory block to reallocate.
-//
-// Return Value:
-//
-// Returns the value returned from realloc.
-//
-void* VisualLeakDetector::_crt80d_realloc (void *mem, size_t size)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcr80d;
- tls_t *tls = vld.gettls();
-
- // realloc is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrt80d_realloc == NULL) {
- // This is the first call to this function. Link to the real realloc.
- msvcr80d = GetModuleHandle(L"msvcr80d.dll");
- pcrt80d_realloc = (realloc_t)GetProcAddress(msvcr80d, "realloc");
- }
-
- // Do the allocation. The block will be mapped by _RtlReAllocateHeap.
- block = pcrt80d_realloc(mem, size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crt80d_scalar_new - Calls to the CRT's scalar new operator from msvcr80d.dll
-// are patched through to this function. This function is just a wrapper
-// around the real CRT scalar new operator that sets appropriate flags to be
-// consulted when the memory is actually allocated by RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// Return Value:
-//
-// Returns the value returned by the CRT scalar new operator.
-//
-void* VisualLeakDetector::_crt80d_scalar_new (unsigned int size)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcr80d;
- tls_t *tls = vld.gettls();
-
- // The new operator is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrt80d_scalar_new == NULL) {
- // This is the first call to this function. Link to the real CRT new
- // operator.
- msvcr80d = GetModuleHandle(L"msvcr80d.dll");
- pcrt80d_scalar_new = (new_t)GetProcAddress(msvcr80d, "??2@YAPAXI@Z");
- }
-
- // Do tha allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrt80d_scalar_new(size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crt80d_vector_new - Calls to the CRT's vector new operator from msvcr80d.dll
-// are patched through to this function. This function is just a wrapper
-// around the real CRT vector new operator that sets appropriate flags to be
-// consulted when the memory is actually allocated by RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// Return Value:
-//
-// Returns the value returned by the CRT vector new operator.
-//
-void* VisualLeakDetector::_crt80d_vector_new (unsigned int size)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcr80d;
- tls_t *tls = vld.gettls();
-
- // The new operator is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrt80d_vector_new == NULL) {
- // This is the first call to this function. Link to the real CRT new
- // operator.
- msvcr80d = GetModuleHandle(L"msvcr80d.dll");
- pcrt80d_vector_new = (new_t)GetProcAddress(msvcr80d, "??_U@YAPAXI@Z");
- }
-
- // Do tha allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrt80d_vector_new(size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crtd__calloc_dbg - Calls to _calloc_dbg from msvcrtd.dll are patched through
-// to this function. This function is just a wrapper around the real
-// _calloc_dbg that sets appropriate flags to be consulted when the memory is
-// actually allocated by RtlAllocateHeap.
-//
-// - num (IN): The number of blocks, of size 'size', to be allocated.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// - type (IN): The CRT "use type" of the block to be allocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above file, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by _calloc_dbg.
-//
-void* VisualLeakDetector::_crtd__calloc_dbg (size_t num, size_t size, int type, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcrtd;
- tls_t *tls = vld.gettls();
-
- // _malloc_dbg is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrtd__calloc_dbg == NULL) {
- // This is the first call to this function. Link to the real
- // _malloc_dbg.
- msvcrtd = GetModuleHandle(L"msvcrtd.dll");
- pcrtd__calloc_dbg = (_calloc_dbg_t)GetProcAddress(msvcrtd, "_calloc_dbg");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrtd__calloc_dbg(num, size, type, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crtd__malloc_dbg - Calls to _malloc_dbg from msvcrtd.dll are patched through
-// to this function. This function is just a wrapper around the real
-// _malloc_dbg that sets appropriate flags to be consulted when the memory is
-// actually allocated by RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// - type (IN): The CRT "use type" of the block to be allocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above file, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by _malloc_dbg.
-//
-void* VisualLeakDetector::_crtd__malloc_dbg (size_t size, int type, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcrtd;
- tls_t *tls = vld.gettls();
-
- // _malloc_dbg is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrtd__malloc_dbg == NULL) {
- // This is the first call to this function. Link to the real
- // _malloc_dbg.
- msvcrtd = GetModuleHandle(L"msvcrtd.dll");
- pcrtd__malloc_dbg = (_malloc_dbg_t)GetProcAddress(msvcrtd, "_malloc_dbg");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrtd__malloc_dbg(size, type, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crtd__realloc_dbg - Calls to _realloc_dbg from msvcrtd.dll are patched
-// through to this function. This function is just a wrapper around the real
-// _realloc_dbg that sets appropriate flags to be consulted when the memory is
-// actually allocated by RtlAllocateHeap.
-//
-// - mem (IN): Pointer to the memory block to be reallocated.
-//
-// - size (IN): The size of the memory block to reallocate.
-//
-// - type (IN): The CRT "use type" of the block to be reallocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above filel, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by _realloc_dbg.
-//
-void* VisualLeakDetector::_crtd__realloc_dbg (void *mem, size_t size, int type, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcrtd;
- tls_t *tls = vld.gettls();
-
- // _realloc_dbg is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrtd__realloc_dbg == NULL) {
- // This is the first call to this function. Link to the real
- // _realloc_dbg.
- msvcrtd = GetModuleHandle(L"msvcrtd.dll");
- pcrtd__realloc_dbg = (_realloc_dbg_t)GetProcAddress(msvcrtd, "_realloc_dbg");
- }
-
- // Do the allocation. The block will be mapped by _RtlReAllocateHeap.
- block = pcrtd__realloc_dbg(mem, size, type, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crtd__scalar_new_dbg - Calls to the CRT's debug scalar new operator from
-// msvcrtd.dll are patched through to this function. This function is just a
-// wrapper around the real CRT debug scalar new operator that sets appropriate
-// flags to be consulted when the memory is actually allocated by
-// RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// - type (IN): The CRT "use type" of the block to be allocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above file, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by the CRT debug scalar new operator.
-//
-void* VisualLeakDetector::_crtd__scalar_new_dbg (unsigned int size, int type, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcrtd;
- tls_t *tls = vld.gettls();
-
- // The debug new operator is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrtd__scalar_new_dbg == NULL) {
- // This is the first call to this function. Link to the real CRT debug
- // new operator.
- msvcrtd = GetModuleHandle(L"msvcrtd.dll");
- pcrtd__scalar_new_dbg = (crt_new_dbg_t)GetProcAddress(msvcrtd, "??2@YAPAXIHPBDH@Z");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrtd__scalar_new_dbg(size, type, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crtd_calloc - Calls to calloc from msvcrtd.dll are patched through to this
-// function. This function is just a wrapper around the real calloc that sets
-// appropriate flags to be consulted when the memory is actually allocated by
-// RtlAllocateHeap.
-//
-// - num (IN): The number of blocks, of size 'size', to be allocated.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// Return Value:
+////////////////////////////////////////////////////////////////////////////////
//
-// Returns the valued returned from calloc.
+// Private Leak Detection Functions
//
-void* VisualLeakDetector::_crtd_calloc (size_t num, size_t size)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcrtd;
- tls_t *tls = vld.gettls();
-
- // malloc is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrtd_calloc == NULL) {
- // This is the first call to this function. Link to the real malloc.
- msvcrtd = GetModuleHandle(L"msvcrtd.dll");
- pcrtd_calloc = (calloc_t)GetProcAddress(msvcrtd, "calloc");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrtd_calloc(num, size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crtd_malloc - Calls to malloc from msvcrtd.dll are patched through to this
-// function. This function is just a wrapper around the real malloc that sets
-// appropriate flags to be consulted when the memory is actually allocated by
-// RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// Return Value:
-//
-// Returns the valued returned from malloc.
-//
-void* VisualLeakDetector::_crtd_malloc (size_t size)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcrtd;
- tls_t *tls = vld.gettls();
-
- // malloc is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrtd_malloc == NULL) {
- // This is the first call to this function. Link to the real malloc.
- msvcrtd = GetModuleHandle(L"msvcrtd.dll");
- pcrtd_malloc = (malloc_t)GetProcAddress(msvcrtd, "malloc");
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrtd_malloc(size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crtd_realloc - Calls to realloc from msvcrtd.dll are patched through to this
-// function. This function is just a wrapper around the real realloc that sets
-// appropriate flags to be consulted when the memory is actually allocated by
-// RtlAllocateHeap.
-//
-// - mem (IN): Pointer to the memory block to reallocate.
-//
-// - size (IN): Size of the memory block to reallocate.
-//
-// Return Value:
-//
-// Returns the value returned from realloc.
-//
-void* VisualLeakDetector::_crtd_realloc (void *mem, size_t size)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcrtd;
- tls_t *tls = vld.gettls();
-
- // realloc is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrtd_realloc == NULL) {
- // This is the first call to this function. Link to the real realloc.
- msvcrtd = GetModuleHandle(L"msvcrtd.dll");
- pcrtd_realloc = (realloc_t)GetProcAddress(msvcrtd, "realloc");
- }
-
- // Do the allocation. The block will be mapped by _RtlReAllocateHeap.
- block = pcrtd_realloc(mem, size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _crtd_scalar_new - Calls to the CRT's scalar new operator from msvcrtd.dll
-// are patched through to this function. This function is just a wrapper
-// around the real CRT scalar new operator that sets appropriate flags to be
-// consulted when the memory is actually allocated by RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// Return Value:
-//
-// Returns the value returned by the CRT scalar new operator.
-//
-void* VisualLeakDetector::_crtd_scalar_new (unsigned int size)
-{
- void *block;
- SIZE_T fp;
- HMODULE msvcrtd;
- tls_t *tls = vld.gettls();
-
- // The new operator is a CRT function and allocates from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pcrtd_scalar_new == NULL) {
- // This is the first call to this function. Link to the real CRT new
- // operator.
- msvcrtd = GetModuleHandle(L"msvcrtd.dll");
- pcrtd_scalar_new = (new_t)GetProcAddress(msvcrtd, "??2@YAPAXI@Z");
- }
-
- // Do tha allocation. The block will be mapped by _RtlAllocateHeap.
- block = pcrtd_scalar_new(size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _GetProcAddress - Calls to GetProcAddress are patched through to this
-// function. If the requested function is a function that has been patched
-// through to one of VLD's handlers, then the address of VLD's handler
-// function is returned instead of the real address. Otherwise, this
-// function is just a wrapper around the real GetProcAddress.
-//
-// - module (IN): Handle (base address) of the module from which to retrieve
-// the address of an exported function.
-//
-// - procname (IN): ANSI string containing the name of the exported function
-// whose address is to be retrieved.
-//
-// Return Value:
-//
-// Returns a pointer to the requested function, or VLD's replacement for
-// the function, if there is a replacement function.
-//
-FARPROC VisualLeakDetector::_GetProcAddress (HMODULE module, LPCSTR procname)
-{
- patchentry_t *entry;
- UINT index;
- UINT tablesize = sizeof(vld.m_patchtable) / sizeof(patchentry_t);
-
- // See if there is an entry in the patch table that matches the requested
- // function.
- for (index = 0; index < tablesize; index++) {
- entry = &vld.m_patchtable[index];
- if ((entry->modulebase == 0x0) || ((HMODULE)entry->modulebase != module)) {
- // This patch table entry is for a different module.
- continue;
- }
-
- // This patch table entry is for the specified module. If the requested
- // import's name matches the entry's import name (or ordinal), then
- // return the address of the replacement instead of the address of the
- // actual import.
- if ((SIZE_T)entry->importname < (SIZE_T)vld.m_vldbase) {
- // This entry's import name is not a valid pointer to data in
- // vld.dll. It must be an ordinal value.
- if ((UINT)entry->importname == (UINT)procname) {
- return (FARPROC)entry->replacement;
- }
- }
- else {
- if (strcmp(entry->importname, procname) == 0) {
- return (FARPROC)entry->replacement;
- }
- }
- }
-
- // The requested function is not a patched function. Just return the real
- // address of the requested function.
- return GetProcAddress(module, procname);
-}
-
-// _HeapCreate - Calls to HeapCreate are patched through to this function. This
-// function is just a wrapper around the real HeapCreate that calls VLD's heap
-// creation tracking function after the heap has been created.
-//
-// - options (IN): Heap options.
-//
-// - initsize (IN): Initial size of the heap.
-//
-// - maxsize (IN): Maximum size of the heap.
-//
-// Return Value:
-//
-// Returns the value returned by HeapCreate.
-//
-HANDLE VisualLeakDetector::_HeapCreate (DWORD options, SIZE_T initsize, SIZE_T maxsize)
-{
- DWORD64 displacement;
- SIZE_T fp;
- SYMBOL_INFO *functioninfo;
- HANDLE heap;
- HeapMap::Iterator heapit;
- SIZE_T ra;
- BYTE symbolbuffer [sizeof(SYMBOL_INFO) + (MAXSYMBOLNAMELENGTH * sizeof(WCHAR)) - 1] = { 0 };
- BOOL symfound;
-
- // Get the return address within the calling function.
- FRAMEPOINTER(fp);
- ra = *((SIZE_T*)fp + 1);
-
- // Create the heap.
- heap = HeapCreate(options, initsize, maxsize);
-
- // Map the created heap handle to a new block map.
- vld.mapheap(heap);
-
- // Try to get the name of the function containing the return address.
- functioninfo = (SYMBOL_INFO*)&symbolbuffer;
- functioninfo->SizeOfStruct = sizeof(SYMBOL_INFO);
- functioninfo->MaxNameLen = MAXSYMBOLNAMELENGTH;
- EnterCriticalSection(&symbollock);
- symfound = SymFromAddrW(currentprocess, ra, &displacement, functioninfo);
- LeaveCriticalSection(&symbollock);
- if (symfound == TRUE) {
- if (wcscmp(L"_heap_init", functioninfo->Name) == 0) {
- // HeapCreate was called by _heap_init. This is a static CRT heap.
- EnterCriticalSection(&vld.m_maplock);
- heapit = vld.m_heapmap->find(heap);
- assert(heapit != vld.m_heapmap->end());
- (*heapit).second->flags |= VLD_HEAP_CRT;
- LeaveCriticalSection(&vld.m_maplock);
- }
- }
-
- return heap;
-}
-
-// _HeapDestroy - Calls to HeapDestroy are patched through to this function.
-// This function is just a wrapper around the real HeapDestroy that calls
-// VLD's heap destruction tracking function after the heap has been destroyed.
-//
-// - heap (IN): Handle to the heap to be destroyed.
-//
-// Return Value:
-//
-// Returns the valued returned by HeapDestroy.
-//
-BOOL VisualLeakDetector::_HeapDestroy (HANDLE heap)
-{
- // After this heap is destroyed, the heap's address space will be unmapped
- // from the process's address space. So, we'd better generate a leak report
- // for this heap now, while we can still read from the memory blocks
- // allocated to it.
- vld.reportleaks(heap);
-
- vld.unmapheap(heap);
-
- return HeapDestroy(heap);
-}
-
-// _LdrLoadDll - Calls to LdrLoadDll are patched through to this function. This
-// function invokes the real LdrLoadDll and then re-attaches VLD to all
-// modules loaded in the process after loading of the new DLL is complete.
-// All modules must be re-enumerated because the explicit load of the
-// specified module may result in the implicit load of one or more additional
-// modules which are dependencies of the specified module.
-//
-// - searchpath (IN): The path to use for searching for the specified module to
-// be loaded.
-//
-// - flags (IN): Pointer to action flags.
-//
-// - modulename (IN): Pointer to a unicodestring_t structure specifying the
-// name of the module to be loaded.
-//
-// - modulehandle (OUT): Address of a HANDLE to receive the newly loaded
-// module's handle.
-//
-// Return Value:
-//
-// Returns the value returned by LdrLoadDll.
-//
-NTSTATUS VisualLeakDetector::_LdrLoadDll (LPWSTR searchpath, PDWORD flags, unicodestring_t *modulename,
- PHANDLE modulehandle)
-{
- ModuleSet::Iterator moduleit;
- ModuleSet *newmodules;
- ModuleSet *oldmodules;
- NTSTATUS status;
-
- // Load the DLL.
- status = LdrLoadDll(searchpath, flags, modulename, modulehandle);
-
- if (STATUS_SUCCESS == status) {
- // Create a new set of all loaded modules, including any newly loaded
- // modules.
- newmodules = new ModuleSet;
- newmodules->reserve(MODULESETRESERVE);
- EnterCriticalSection(&vld.m_loaderlock);
- EnumerateLoadedModulesW64(currentprocess, addloadedmodule, newmodules);
- LeaveCriticalSection(&vld.m_loaderlock);
-
- // Attach to all modules included in the set.
- vld.attachtoloadedmodules(newmodules);
-
- // Start using the new set of loaded modules.
- EnterCriticalSection(&vld.m_moduleslock);
- oldmodules = vld.m_loadedmodules;
- vld.m_loadedmodules = newmodules;
- LeaveCriticalSection(&vld.m_moduleslock);
-
- // Free resources used by the old module list.
- for (moduleit = oldmodules->begin(); moduleit != oldmodules->end(); ++moduleit) {
- delete (*moduleit).name;
- delete (*moduleit).path;
- }
- delete oldmodules;
- }
-
- return status;
-}
-
-// _mfc42d__scalar_new_dbg - Calls to the MFC debug scalar new operator from
-// mfc42d.dll are patched through to this function. This function is just a
-// wrapper around the real MFC debug scalar new operator that sets appropriate
-// flags to be consulted when the memory is actually allocated by
-// RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above file, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by the MFC debug scalar new operator.
-//
-void* VisualLeakDetector::_mfc42d__scalar_new_dbg (unsigned int size, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE mfc42d;
- tls_t *tls = vld.gettls();
-
- // The MFC new operators are CRT-based and allocate from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pmfc42d__scalar_new_dbg == NULL) {
- // This is the first call to this function. Link to the real MFC debug
- // new operator.
- mfc42d = GetModuleHandle(L"mfc42d.dll");
- pmfc42d__scalar_new_dbg = (mfc_new_dbg_t)GetProcAddress(mfc42d, (LPCSTR)714);
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pmfc42d__scalar_new_dbg(size, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _mfc42d_scalar_new - Calls to the MFC scalar new operator from mfc42d.dll are
-// patched through to this function. This function is just a wrapper around
-// the real MFC scalar new operator that sets appropriate flags to be
-// consulted when the memory is actually allocated by RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// Return Value:
-//
-// Returns the value returned by the MFC scalar new operator.
-//
-void* VisualLeakDetector::_mfc42d_scalar_new (unsigned int size)
-{
- void *block;
- SIZE_T fp;
- HMODULE mfc42d;
- tls_t *tls = vld.gettls();
-
- // The MFC new operators are CRT-based and allocate from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pmfc42d_scalar_new == NULL) {
- // This is the first call to this function. Link to the real MFC new
- // operator.
- mfc42d = GetModuleHandle(L"mfc42d.dll");
- pmfc42d_scalar_new = (new_t)GetProcAddress(mfc42d, (LPCSTR)711);
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pmfc42d_scalar_new(size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _mfc80d__scalar_new_dbg - Calls to the MFC debug scalar new operator from
-// mfc80d.dll are patched through to this function. This function is just a
-// wrapper around the real MFC debug scalar new operator that sets appropriate
-// flags to be consulted when the memory is actually allocated by
-// RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above file, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by the MFC debug scalar new operator.
-//
-void* VisualLeakDetector::_mfc80d__scalar_new_dbg (unsigned int size, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE mfc80d;
- tls_t *tls = vld.gettls();
-
- // The MFC new operators are CRT-based and allocate from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pmfc80d__scalar_new_dbg == NULL) {
- // This is the first call to this function. Link to the real MFC debug
- // new operator.
- mfc80d = GetModuleHandle(L"mfc80d.dll");
- pmfc80d__scalar_new_dbg = (mfc_new_dbg_t)GetProcAddress(mfc80d, (LPCSTR)895);
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pmfc80d__scalar_new_dbg(size, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _mfc80d__vector_new_dbg - Calls to the MFC debug vector new operator from
-// mfc80d.dll are patched through to this function. This function is just a
-// wrapper around the real MFC debug vector new operator that sets appropriate
-// flags to be consulted when the memory is actually allocated by
-// RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// - file (IN): The name of the file from which this function is being called.
-//
-// - line (IN): The line number, in the above file, at which this function is
-// being called.
-//
-// Return Value:
-//
-// Returns the value returned by the MFC debug vector new operator.
-//
-void* VisualLeakDetector::_mfc80d__vector_new_dbg (unsigned int size, const char *file, int line)
-{
- void *block;
- SIZE_T fp;
- HMODULE mfc80d;
- tls_t *tls = vld.gettls();
-
- // The MFC new operators are CRT-based and allocate from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pmfc80d__vector_new_dbg == NULL) {
- // This is the first call to this function. Link to the real MFC debug
- // new operator.
- mfc80d = GetModuleHandle(L"mfc80d.dll");
- pmfc80d__vector_new_dbg = (mfc_new_dbg_t)GetProcAddress(mfc80d, (LPCSTR)269);
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pmfc80d__vector_new_dbg(size, file, line);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _mfc80d_scalar_new - Calls to the MFC scalar new operator from mfc80d.dll are
-// patched through to this function. This function is just a wrapper around
-// the real MFC scalar new operator that sets appropriate flags to be
-// consulted when the memory is actually allocated by RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// Return Value:
-//
-// Returns the value returned by the MFC scalar new operator.
-//
-void* VisualLeakDetector::_mfc80d_scalar_new (unsigned int size)
-{
- void *block;
- SIZE_T fp;
- HMODULE mfc80d;
- tls_t *tls = vld.gettls();
-
- // The MFC new operators are CRT-based and allocate from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pmfc80d_scalar_new == NULL) {
- // This is the first call to this function. Link to the real MFC 8.0 new
- // operator.
- mfc80d = GetModuleHandle(L"mfc80d.dll");
- pmfc80d_scalar_new = (new_t)GetProcAddress(mfc80d, (LPCSTR)893);
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pmfc80d_scalar_new(size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _mfc80d_vector_new - Calls to the MFC vector new operator from mfc80d.dll are
-// patched through to this function. This function is just a wrapper around
-// the real MFC vector new operator that sets appropriate flags to be
-// consulted when the memory is actually allocated by RtlAllocateHeap.
-//
-// - size (IN): The size, in bytes, of the memory block to be allocated.
-//
-// Return Value:
-//
-// Returns the value returned by the MFC vector new operator.
-//
-void* VisualLeakDetector::_mfc80d_vector_new (unsigned int size)
-{
- void *block;
- SIZE_T fp;
- HMODULE mfc80d;
- tls_t *tls = vld.gettls();
-
- // The MFC new operators are CRT-based and allocate from the CRT heap.
- tls->flags |= VLD_TLS_CRTALLOC;
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- if (pmfc80d_vector_new == NULL) {
- // This is the first call to this function. Link to the real MFC 8.0 new
- // operator.
- mfc80d = GetModuleHandle(L"mfc80d.dll");
- pmfc80d_vector_new = (new_t)GetProcAddress(mfc80d, (LPCSTR)267);
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- block = pmfc80d_vector_new(size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _RtlAllocateHeap - Calls to RtlAllocateHeap are patched through to this
-// function. This function invokes the real RtlAllocateHeap and then calls
-// VLD's allocation tracking function. Pretty much all memory allocations
-// will eventually result in a call to RtlAllocateHeap, so this is where we
-// finally map the allocated block.
-//
-// - heap (IN): Handle to the heap from which to allocate memory.
-//
-// - flags (IN): Heap allocation control flags.
-//
-// - size (IN): Size, in bytes, of the block to allocate.
-//
-// Return Value:
-//
-// Returns the return value from RtlAllocateHeap.
-//
-LPVOID VisualLeakDetector::_RtlAllocateHeap (HANDLE heap, DWORD flags, SIZE_T size)
-{
- BOOL crtalloc;
- BOOL excluded = FALSE;
- SIZE_T fp;
- LPVOID block;
- moduleinfo_t moduleinfo;
- ModuleSet::Iterator moduleit;
- SIZE_T returnaddress;
- tls_t *tls = vld.gettls();
-
- // Allocate the block.
- block = RtlAllocateHeap(heap, flags, size);
- if ((block != NULL) && vld.enabled()) {
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- }
- else {
- fp = tls->addrfp;
- }
- crtalloc = (tls->flags & VLD_TLS_CRTALLOC) ? TRUE : FALSE;
-
- // Reset thread local flags and variables, in case any libraries called
- // into while mapping the block allocate some memory.
- tls->addrfp = 0x0;
- tls->flags &=~VLD_TLS_CRTALLOC;
-
- // Find the information for the module that initiated this allocation.
- returnaddress = *((SIZE_T*)fp + 1);
- moduleinfo.addrhigh = returnaddress;
- moduleinfo.addrlow = returnaddress;
- EnterCriticalSection(&vld.m_moduleslock);
- moduleit = vld.m_loadedmodules->find(moduleinfo);
- if (moduleit != vld.m_loadedmodules->end()) {
- excluded = (*moduleit).flags & VLD_MODULE_EXCLUDED ? TRUE : FALSE;
- }
- LeaveCriticalSection(&vld.m_moduleslock);
- if (!excluded) {
- // The module that initiated this allocation is included in leak
- // detection. Map this block to the specified heap.
- vld.mapblock(heap, block, size, fp, crtalloc);
- }
- }
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// _RtlFreeHeap - Calls to RtlFreeHeap are patched through to this function.
-// This function calls VLD's free tracking function and then invokes the real
-// RtlFreeHeap. Pretty much all memory frees will eventually result in a call
-// to RtlFreeHeap, so this is where we finally unmap the freed block.
-//
-// - heap (IN): Handle to the heap to which the block being freed belongs.
-//
-// - flags (IN): Heap control flags.
-//
-// - mem (IN): Pointer to the memory block being freed.
-//
-// Return Value:
-//
-// Returns the value returned by RtlFreeHeap.
-//
-BOOL VisualLeakDetector::_RtlFreeHeap (HANDLE heap, DWORD flags, LPVOID mem)
-{
- BOOL status;
-
- // Unmap the block from the specified heap.
- vld.unmapblock(heap, mem);
-
- status = RtlFreeHeap(heap, flags, mem);
-
- return status;
-}
-
-// _RtlReAllocateHeap - Calls to RtlReAllocateHeap are patched through to this
-// function. This function invokes the real RtlReAllocateHeap and then calls
-// VLD's reallocation tracking function. All arguments passed to this function
-// are passed on to the real RtlReAllocateHeap without modification. Pretty
-// much all memory re-allocations will eventually result in a call to
-// RtlReAllocateHeap, so this is where we finally remap the reallocated block.
-//
-// - heap (IN): Handle to the heap to reallocate memory from.
-//
-// - flags (IN): Heap control flags.
-//
-// - mem (IN): Pointer to the currently allocated block which is to be
-// reallocated.
-//
-// - size (IN): Size, in bytes, of the block to reallocate.
-//
-// Return Value:
-//
-// Returns the value returned by RtlReAllocateHeap.
-//
-LPVOID VisualLeakDetector::_RtlReAllocateHeap (HANDLE heap, DWORD flags, LPVOID mem, SIZE_T size)
-{
- BOOL crtalloc;
- BOOL excluded = FALSE;
- SIZE_T fp;
- moduleinfo_t moduleinfo;
- ModuleSet::Iterator moduleit;
- LPVOID newmem;
- SIZE_T returnaddress;
- tls_t *tls = vld.gettls();
-
- // Reallocate the block.
- newmem = RtlReAllocateHeap(heap, flags, mem, size);
-
- if (newmem != NULL) {
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- }
- else {
- fp = tls->addrfp;
- }
- crtalloc = (tls->flags & VLD_TLS_CRTALLOC) ? TRUE : FALSE;
-
- // Reset thread local flags and variables, in case any libraries called
- // into while remapping the block allocate some memory.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- // Find the information for the module that initiated this reallocation.
- returnaddress = *((SIZE_T*)fp + 1);
- moduleinfo.addrhigh = returnaddress;
- moduleinfo.addrlow = returnaddress;
- EnterCriticalSection(&vld.m_moduleslock);
- moduleit = vld.m_loadedmodules->find(moduleinfo);
- if (moduleit != vld.m_loadedmodules->end()) {
- excluded = (*moduleit).flags & VLD_MODULE_EXCLUDED ? TRUE : FALSE;
- }
- LeaveCriticalSection(&vld.m_moduleslock);
- if (!excluded) {
- // The module that initiated this allocation is included in leak
- // detection. Remap the block.
- vld.remapblock(heap, mem, newmem, size, fp, crtalloc);
- }
- }
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return newmem;
-}
-
-// AddRef - Calls to IMalloc::AddRef end up here. This function is just a
-// wrapper around the real IMalloc::AddRef implementation.
-//
-// Return Value:
-//
-// Returns the value returned by the system implementation of
-// IMalloc::AddRef.
-//
-ULONG VisualLeakDetector::AddRef ()
-{
- assert(m_imalloc != NULL);
- return m_imalloc->AddRef();
-}
-
-// Alloc - Calls to IMalloc::Alloc end up here. This function is just a wrapper
-// around the real IMalloc::Alloc implementation that sets appropriate flags
-// to be consulted when the memory is actually allocated by RtlAllocateHeap.
-//
-// - size (IN): The size of the memory block to allocate.
-//
-// Return Value:
-//
-// Returns the value returned by the system's IMalloc::Alloc implementation.
-//
-LPVOID VisualLeakDetector::Alloc (ULONG size)
-{
- LPVOID block;
- SIZE_T fp;
- tls_t *tls = vld.gettls();
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- // Do the allocation. The block will be mapped by _RtlAllocateHeap.
- assert(m_imalloc != NULL);
- block = m_imalloc->Alloc(size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// addloadedmodule - Callback function for EnumerateLoadedModules64. This
-// function records information about every module loaded in the process,
-// each time adding the module's information to the provided ModuleSet (the
-// "context" parameter).
-//
-// When EnumerateLoadedModules64 has finished calling this function for each
-// loaded module, then the resulting ModuleSet can be used at any time to get
-// information about any modules loaded into the process.
-//
-// - modulepath (IN): The fully qualified path from where the module was
-// loaded.
-//
-// - modulebase (IN): The base address at which the module has been loaded.
-//
-// - modulesize (IN): The size, in bytes, of the loaded module.
-//
-// - context (IN): Pointer to the ModuleSet to which information about each
-// module is to be added.
-//
-// Return Value:
-//
-// Always returns TRUE, which tells EnumerateLoadedModules64 to continue
-// enumerating.
-//
-BOOL VisualLeakDetector::addloadedmodule (PCWSTR modulepath, DWORD64 modulebase, ULONG modulesize, PVOID context)
-{
- size_t count;
- patchentry_t *entry;
- CHAR extension [_MAX_EXT];
- CHAR filename [_MAX_FNAME];
- UINT index;
- moduleinfo_t moduleinfo;
- LPSTR modulenamea;
- LPSTR modulepatha;
- ModuleSet* newmodules = (ModuleSet*)context;
- SIZE_T size;
- UINT tablesize = sizeof(m_patchtable) / sizeof(patchentry_t);
-
- // Convert the module path to ASCII.
- size = wcslen(modulepath) + 1;
- modulepatha = new CHAR [size];
- wcstombs_s(&count, modulepatha, size, modulepath, _TRUNCATE);
-
- // Extract just the filename and extension from the module path.
- _splitpath_s(modulepatha, NULL, 0, NULL, 0, filename, _MAX_FNAME, extension, _MAX_EXT);
- size = strlen(filename) + strlen(extension) + 1;
- modulenamea = new CHAR [size];
- strncpy_s(modulenamea, size, filename, _TRUNCATE);
- strncat_s(modulenamea, size, extension, _TRUNCATE);
- _strlwr_s(modulenamea, size);
-
- if (_stricmp(modulenamea, "vld.dll") == 0) {
- // Record Visual Leak Detector's own base address.
- vld.m_vldbase = (HMODULE)modulebase;
- }
- else {
- // See if this is a module listed in the patch table. If it is, update
- // the corresponding patch table entries' module base address.
- for (index = 0; index < tablesize; index++) {
- entry = &m_patchtable[index];
- if (_stricmp(entry->exportmodulename, modulenamea) == 0) {
- entry->modulebase = (SIZE_T)modulebase;
- }
- }
- }
-
- // Record the module's information and store it in the set.
- moduleinfo.addrlow = (SIZE_T)modulebase;
- moduleinfo.addrhigh = (SIZE_T)(modulebase + modulesize) - 1;
- moduleinfo.flags = 0x0;
- moduleinfo.name = modulenamea;
- moduleinfo.path = modulepatha;
- newmodules->insert(moduleinfo);
-
- return TRUE;
-}
+////////////////////////////////////////////////////////////////////////////////
// attachtoloadedmodules - Attaches VLD to all modules contained in the provided
// ModuleSet. Not all modules are in the ModuleSet will actually be included
@@ -2631,50 +913,6 @@ VOID VisualLeakDetector::configure ()
}
}
-// detachfrommodule - Callback function for EnumerateLoadedModules64 that
-// detaches Visual Leak Detector from the specified module. If the specified
-// module has not previously been attached to, then calling this function will
-// not actually result in any changes.
-//
-// - modulepath (IN): String containing the name, which may inlcude a path, of
-// the module to detach from (ignored).
-//
-// - modulebase (IN): Base address of the module.
-//
-// - modulesize (IN): Total size of the module (ignored).
-//
-// - context (IN): User-supplied context (ignored).
-//
-// Return Value:
-//
-// Always returns TRUE.
-//
-BOOL VisualLeakDetector::detachfrommodule (PCWSTR /*modulepath*/, DWORD64 modulebase, ULONG /*modulesize*/,
- PVOID /*context*/)
-{
- UINT tablesize = sizeof(m_patchtable) / sizeof(patchentry_t);
-
- restoremodule((HMODULE)modulebase, m_patchtable, tablesize);
-
- return TRUE;
-}
-
-// DidAlloc - Calls to IMalloc::DidAlloc will end up here. This function is just
-// a wrapper around the system implementation of IMalloc::DidAlloc.
-//
-// - mem (IN): Pointer to a memory block to inquire about.
-//
-// Return Value:
-//
-// Returns the value returned by the system implementation of
-// IMalloc::DidAlloc.
-//
-INT VisualLeakDetector::DidAlloc (LPVOID mem)
-{
- assert(m_imalloc != NULL);
- return m_imalloc->DidAlloc(mem);
-}
-
// enabled - Determines if memory leak detection is enabled for the current
// thread.
//
@@ -2755,38 +993,7 @@ SIZE_T VisualLeakDetector::eraseduplicates (const BlockMap::Iterator &element)
return erased;
}
-// Free - Calls to IMalloc::Free will end up here. This function is just a
-// wrapper around the real IMalloc::Free implementation.
-//
-// - mem (IN): Pointer to the memory block to be freed.
-//
-// Return Value:
-//
-// None.
-//
-VOID VisualLeakDetector::Free (LPVOID mem)
-{
- assert(m_imalloc != NULL);
- m_imalloc->Free(mem);
-}
-
-// GetSize - Calls to IMalloc::GetSize will end up here. This function is just a
-// wrapper around the real IMalloc::GetSize implementation.
-//
-// - mem (IN): Pointer to the memory block to inquire about.
-//
-// Return Value:
-//
-// Returns the value returned by the system implementation of
-// IMalloc::GetSize.
-//
-ULONG VisualLeakDetector::GetSize (LPVOID mem)
-{
- assert(m_imalloc != NULL);
- return m_imalloc->GetSize(mem);
-}
-
-// gettls - Obtains the thread local strorage structure for the calling thread.
+// gettls - Obtains the thread local storage structure for the calling thread.
//
// Return Value:
//
@@ -2818,19 +1025,6 @@ tls_t* VisualLeakDetector::gettls ()
return tls;
}
-// HeapMinimize - Calls to IMalloc::HeapMinimize will end up here. This function
-// is just a wrapper around the real IMalloc::HeapMinimize implementation.
-//
-// Return Value:
-//
-// None.
-//
-VOID VisualLeakDetector::HeapMinimize ()
-{
- assert(m_imalloc != NULL);
- m_imalloc->HeapMinimize();
-}
-
// mapblock - Tracks memory allocations. Information about allocated blocks is
// collected and then the block is mapped to this information.
//
@@ -2941,78 +1135,6 @@ VOID VisualLeakDetector::mapheap (HANDLE heap)
LeaveCriticalSection(&m_maplock);
}
-// QueryInterface - Calls to IMalloc::QueryInterface will end up here. This
-// function is just a wrapper around the real IMalloc::QueryInterface
-// implementation.
-//
-// - iid (IN): COM interface ID to query about.
-//
-// - object (IN): Address of a pointer to receive the requested interface
-// pointer.
-//
-// Return Value:
-//
-// Returns the value returned by the system implementation of
-// IMalloc::QueryInterface.
-//
-HRESULT VisualLeakDetector::QueryInterface (REFIID iid, LPVOID *object)
-{
- assert(m_imalloc != NULL);
- return m_imalloc->QueryInterface(iid, object);
-}
-
-// Realloc - Calls to IMalloc::Realloc will end up here. This function is just a
-// wrapper around the real IMalloc::Realloc implementation that sets
-// appropriate flags to be consulted when the memory is actually allocated by
-// RtlAllocateHeap.
-//
-// - mem (IN): Pointer to the memory block to reallocate.
-//
-// - size (IN): Size, in bytes, of the memory block to reallocate.
-//
-// Return Value:
-//
-// Returns the value returned by the system implementation of
-// IMalloc::Realloc.
-//
-LPVOID VisualLeakDetector::Realloc (LPVOID mem, ULONG size)
-{
- LPVOID block;
- SIZE_T fp;
- tls_t *tls = vld.gettls();
-
- if (tls->addrfp == 0x0) {
- // This is the first call to enter VLD for the current allocation.
- // Record the current frame pointer.
- FRAMEPOINTER(fp);
- tls->addrfp = fp;
- }
-
- // Do the allocation. The block will be mapped by _RtlReAllocateHeap.
- assert(m_imalloc != NULL);
- block = m_imalloc->Realloc(mem, size);
-
- // Reset thread local flags and variables for the next allocation.
- tls->addrfp = 0x0;
- tls->flags &= ~VLD_TLS_CRTALLOC;
-
- return block;
-}
-
-// Release - Calls to IMalloc::Release will end up here. This function is just
-// a wrapper around the real IMalloc::Release implementation.
-//
-// Return Value:
-//
-// Returns the value returned by the system implementation of
-// IMalloc::Release.
-//
-ULONG VisualLeakDetector::Release ()
-{
- assert(m_imalloc != NULL);
- return m_imalloc->Release();
-}
-
// remapblock - Tracks reallocations. Unmaps a block from its previously
// collected information and remaps it to updated information.
//
@@ -3336,3 +1458,1291 @@ VOID VisualLeakDetector::unmapheap (HANDLE heap)
m_heapmap->erase(heapit);
LeaveCriticalSection(&m_maplock);
}
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Static Leak Detection Functions (Callbacks)
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// addloadedmodule - Callback function for EnumerateLoadedModules64. This
+// function records information about every module loaded in the process,
+// each time adding the module's information to the provided ModuleSet (the
+// "context" parameter).
+//
+// When EnumerateLoadedModules64 has finished calling this function for each
+// loaded module, then the resulting ModuleSet can be used at any time to get
+// information about any modules loaded into the process.
+//
+// - modulepath (IN): The fully qualified path from where the module was
+// loaded.
+//
+// - modulebase (IN): The base address at which the module has been loaded.
+//
+// - modulesize (IN): The size, in bytes, of the loaded module.
+//
+// - context (IN): Pointer to the ModuleSet to which information about each
+// module is to be added.
+//
+// Return Value:
+//
+// Always returns TRUE, which tells EnumerateLoadedModules64 to continue
+// enumerating.
+//
+BOOL VisualLeakDetector::addloadedmodule (PCWSTR modulepath, DWORD64 modulebase, ULONG modulesize, PVOID context)
+{
+ size_t count;
+ patchentry_t *entry;
+ CHAR extension [_MAX_EXT];
+ CHAR filename [_MAX_FNAME];
+ UINT index;
+ moduleinfo_t moduleinfo;
+ LPSTR modulenamea;
+ LPSTR modulepatha;
+ ModuleSet* newmodules = (ModuleSet*)context;
+ SIZE_T size;
+ UINT tablesize = sizeof(m_patchtable) / sizeof(patchentry_t);
+
+ // Convert the module path to ASCII.
+ size = wcslen(modulepath) + 1;
+ modulepatha = new CHAR [size];
+ wcstombs_s(&count, modulepatha, size, modulepath, _TRUNCATE);
+
+ // Extract just the filename and extension from the module path.
+ _splitpath_s(modulepatha, NULL, 0, NULL, 0, filename, _MAX_FNAME, extension, _MAX_EXT);
+ size = strlen(filename) + strlen(extension) + 1;
+ modulenamea = new CHAR [size];
+ strncpy_s(modulenamea, size, filename, _TRUNCATE);
+ strncat_s(modulenamea, size, extension, _TRUNCATE);
+ _strlwr_s(modulenamea, size);
+
+ if (_stricmp(modulenamea, "vld.dll") == 0) {
+ // Record Visual Leak Detector's own base address.
+ vld.m_vldbase = (HMODULE)modulebase;
+ }
+ else {
+ // See if this is a module listed in the patch table. If it is, update
+ // the corresponding patch table entries' module base address.
+ for (index = 0; index < tablesize; index++) {
+ entry = &m_patchtable[index];
+ if (_stricmp(entry->exportmodulename, modulenamea) == 0) {
+ entry->modulebase = (SIZE_T)modulebase;
+ }
+ }
+ }
+
+ // Record the module's information and store it in the set.
+ moduleinfo.addrlow = (SIZE_T)modulebase;
+ moduleinfo.addrhigh = (SIZE_T)(modulebase + modulesize) - 1;
+ moduleinfo.flags = 0x0;
+ moduleinfo.name = modulenamea;
+ moduleinfo.path = modulepatha;
+ newmodules->insert(moduleinfo);
+
+ return TRUE;
+}
+
+// detachfrommodule - Callback function for EnumerateLoadedModules64 that
+// detaches Visual Leak Detector from the specified module. If the specified
+// module has not previously been attached to, then calling this function will
+// not actually result in any changes.
+//
+// - modulepath (IN): String containing the name, which may include a path, of
+// the module to detach from (ignored).
+//
+// - modulebase (IN): Base address of the module.
+//
+// - modulesize (IN): Total size of the module (ignored).
+//
+// - context (IN): User-supplied context (ignored).
+//
+// Return Value:
+//
+// Always returns TRUE.
+//
+BOOL VisualLeakDetector::detachfrommodule (PCWSTR /*modulepath*/, DWORD64 modulebase, ULONG /*modulesize*/,
+ PVOID /*context*/)
+{
+ UINT tablesize = sizeof(m_patchtable) / sizeof(patchentry_t);
+
+ restoremodule((HMODULE)modulebase, m_patchtable, tablesize);
+
+ return TRUE;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Standard CRT and MFC IAT Replacement Functions
+//
+// The addresses of these functions are not actually directly patched into the
+// import address tables, but these functions do get indirectly called by the
+// patch functions that are placed in the import address tables.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// _calloc - This function is just a wrapper around the real calloc that sets
+// appropriate flags to be consulted when the memory is actually allocated by
+// RtlAllocateHeap.
+//
+// - pcalloc (IN): Pointer to the particular calloc implementation to call.
+//
+// - fp (IN): Frame pointer from the call that initiated this allocation.
+//
+// - num (IN): The number of blocks, of size 'size', to be allocated.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the value returned from the specified calloc.
+//
+void* VisualLeakDetector::_calloc (calloc_t pcalloc,
+ SIZE_T fp,
+ size_t num,
+ size_t size)
+{
+ void *block;
+ tls_t *tls = vld.gettls();
+
+ // malloc is a CRT function and allocates from the CRT heap.
+ tls->flags |= VLD_TLS_CRTALLOC;
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlAllocateHeap.
+ block = pcalloc(num, size);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// _malloc - This function is just a wrapper around the real malloc that sets
+// appropriate flags to be consulted when the memory is actually allocated by
+// RtlAllocateHeap.
+//
+// - pmalloc (IN): Pointer to the particular malloc implementation to call.
+//
+// - fp (IN): Frame pointer from the call that initiated this allocation.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the value returned from the specified malloc.
+//
+void *VisualLeakDetector::_malloc (malloc_t pmalloc, SIZE_T fp, size_t size)
+{
+ void *block;
+ tls_t *tls = vld.gettls();
+
+ // malloc is a CRT function and allocates from the CRT heap.
+ tls->flags |= VLD_TLS_CRTALLOC;
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlAllocateHeap.
+ block = pmalloc(size);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// _new - This function is just a wrapper around the real CRT and MFC new
+// operators that sets appropriate flags to be consulted when the memory is
+// actually allocated by RtlAllocateHeap.
+//
+// - pnew (IN): Pointer to the particular new implementation to call.
+//
+// - fp (IN): Frame pointer from the call that initiated this allocation.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// Return Value:
+//
+// Returns the value returned by the specified CRT new operator.
+//
+void* VisualLeakDetector::_new (new_t pnew, SIZE_T fp, size_t size)
+{
+ void *block;
+ tls_t *tls = vld.gettls();
+
+ // The new operator is a CRT function and allocates from the CRT heap.
+ tls->flags |= VLD_TLS_CRTALLOC;
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlAllocateHeap.
+ block = pnew(size);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// _realloc - This function is just a wrapper around the real realloc that sets
+// appropriate flags to be consulted when the memory is actually allocated by
+// RtlAllocateHeap.
+//
+// - prealloc (IN): Pointer to the particular realloc implementation to call.
+//
+// - fp (IN): Frame pointer from the call that initiated this allocation.
+//
+// - mem (IN): Pointer to the memory block to reallocate.
+//
+// - size (IN): Size of the memory block to reallocate.
+//
+// Return Value:
+//
+// Returns the value returned from the specified realloc.
+//
+void* VisualLeakDetector::_realloc (realloc_t prealloc,
+ SIZE_T fp,
+ void *mem,
+ size_t size)
+{
+ void *block;
+ tls_t *tls = vld.gettls();
+
+ // realloc is a CRT function and allocates from the CRT heap.
+ tls->flags |= VLD_TLS_CRTALLOC;
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlReAllocateHeap.
+ block = prealloc(mem, size);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Debug CRT and MFC IAT Replacement Functions
+//
+// The addresses of these functions are not actually directly patched into the
+// import address tables, but these functions do get indirectly called by the
+// patch functions that are placed in the import address tables.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// __calloc_dbg - This function is just a wrapper around the real _calloc_dbg
+// that sets appropriate flags to be consulted when the memory is actually
+// allocated by RtlAllocateHeap.
+//
+// - p_calloc_dbg: Pointer to the particular _calloc_dbg implementation to
+// call.
+//
+// - fp (IN): Frame pointer from the call that initiated this allocation.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The CRT "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the specified _calloc_dbg.
+//
+void* VisualLeakDetector::__calloc_dbg (_calloc_dbg_t p_calloc_dbg,
+ SIZE_T fp,
+ size_t num,
+ size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ void *block;
+ tls_t *tls = vld.gettls();
+
+ // _malloc_dbg is a CRT function and allocates from the CRT heap.
+ tls->flags |= VLD_TLS_CRTALLOC;
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlAllocateHeap.
+ block = p_calloc_dbg(num, size, type, file, line);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// __malloc_dbg - This function is just a wrapper around the real _malloc_dbg
+// that sets appropriate flags to be consulted when the memory is actually
+// allocated by RtlAllocateHeap.
+//
+// - p_malloc_dbg (IN): Pointer to the particular _malloc_dbg implementation to
+// call.
+//
+// - fp (IN): Frame pointer from the call that initiated this allocation.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The CRT "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the specified _malloc_dbg.
+//
+void* VisualLeakDetector::__malloc_dbg (_malloc_dbg_t p_malloc_dbg,
+ SIZE_T fp,
+ size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ void *block;
+ tls_t *tls = vld.gettls();
+
+ // _malloc_dbg is a CRT function and allocates from the CRT heap.
+ tls->flags |= VLD_TLS_CRTALLOC;
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlAllocateHeap.
+ block = p_malloc_dbg(size, type, file, line);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// new_dbg_crt - This function is just a wrapper around the real CRT debug new
+// operators that sets appropriate flags to be consulted when the memory is
+// actually allocated by RtlAllocateHeap.
+//
+// - pnew_dbg_crt (IN): Pointer to the particular CRT new operator
+// implementation to call.
+//
+// - fp (IN): Frame pointer from the call that initiated this allocation.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The CRT "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the specified CRT debug new operator.
+//
+void* VisualLeakDetector::new_dbg_crt (new_dbg_crt_t pnew_dbg_crt,
+ SIZE_T fp,
+ size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ void *block;
+ tls_t *tls = vld.gettls();
+
+ // The debug new operator is a CRT function and allocates from the CRT heap.
+ tls->flags |= VLD_TLS_CRTALLOC;
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlAllocateHeap.
+ block = pnew_dbg_crt(size, type, file, line);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// new_dbg_mfc - This function is just a wrapper around the real MFC debug new
+// operators that sets appropriate flags to be consulted when the memory is
+// actually allocated by RtlAllocateHeap.
+//
+// - pnew_dbg (IN): Pointer to the particular CRT new operator
+// implementation to call.
+//
+// - fp (IN): Frame pointer from the call that initiated this allocation.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - type (IN): The CRT "use type" of the block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the specified CRT debug new operator.
+//
+void* VisualLeakDetector::new_dbg_mfc (new_dbg_crt_t pnew_dbg,
+ SIZE_T fp,
+ size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ void *block;
+ tls_t *tls = vld.gettls();
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlAllocateHeap.
+ block = pnew_dbg(size, type, file, line);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// new_dbg_mfc - This function is just a wrapper around the real MFC debug new
+// operators that sets appropriate flags to be consulted when the memory is
+// actually allocated by RtlAllocateHeap.
+//
+// - pnew_dbg_mfc (IN): Pointer to the particular MFC new operator
+// implementation to call.
+//
+// - fp (IN): Frame pointer of the call that initiated this allocation.
+//
+// - size (IN): The size, in bytes, of the memory block to be allocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the specified MFC debug new operator.
+//
+void* VisualLeakDetector::new_dbg_mfc (new_dbg_mfc_t pnew_dbg_mfc,
+ SIZE_T fp,
+ size_t size,
+ char const *file,
+ int line)
+{
+ void *block;
+ tls_t *tls = vld.gettls();
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlAllocateHeap.
+ block = pnew_dbg_mfc(size, file, line);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// __realloc_debug - This function is just a wrapper around the real
+// _realloc_dbg that sets appropriate flags to be consulted when the memory is
+// actually allocated by RtlAllocateHeap.
+//
+// - p_realloc_dbg (IN): Pointer to the particular __realloc_dbg implementation
+// to call.
+//
+// - fp (IN): Frame pointer from the call that initiated this allocation.
+//
+// - mem (IN): Pointer to the memory block to be reallocated.
+//
+// - size (IN): The size of the memory block to reallocate.
+//
+// - type (IN): The CRT "use type" of the block to be reallocated.
+//
+// - file (IN): The name of the file from which this function is being called.
+//
+// - line (IN): The line number, in the above file, at which this function is
+// being called.
+//
+// Return Value:
+//
+// Returns the value returned by the specified _realloc_dbg.
+//
+void* VisualLeakDetector::__realloc_dbg (_realloc_dbg_t p_realloc_dbg,
+ SIZE_T fp,
+ void *mem,
+ size_t size,
+ int type,
+ char const *file,
+ int line)
+{
+ void *block;
+ tls_t *tls = vld.gettls();
+
+ // _realloc_dbg is a CRT function and allocates from the CRT heap.
+ tls->flags |= VLD_TLS_CRTALLOC;
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlReAllocateHeap.
+ block = p_realloc_dbg(mem, size, type, file, line);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Win32 IAT Replacement Functions
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// _GetProcAddress - Calls to GetProcAddress are patched through to this
+// function. If the requested function is a function that has been patched
+// through to one of VLD's handlers, then the address of VLD's handler
+// function is returned instead of the real address. Otherwise, this
+// function is just a wrapper around the real GetProcAddress.
+//
+// - module (IN): Handle (base address) of the module from which to retrieve
+// the address of an exported function.
+//
+// - procname (IN): ANSI string containing the name of the exported function
+// whose address is to be retrieved.
+//
+// Return Value:
+//
+// Returns a pointer to the requested function, or VLD's replacement for
+// the function, if there is a replacement function.
+//
+FARPROC VisualLeakDetector::_GetProcAddress (HMODULE module, LPCSTR procname)
+{
+ patchentry_t *entry;
+ UINT index;
+ UINT tablesize = sizeof(vld.m_patchtable) / sizeof(patchentry_t);
+
+ // See if there is an entry in the patch table that matches the requested
+ // function.
+ for (index = 0; index < tablesize; index++) {
+ entry = &vld.m_patchtable[index];
+ if ((entry->modulebase == 0x0) || ((HMODULE)entry->modulebase != module)) {
+ // This patch table entry is for a different module.
+ continue;
+ }
+
+ // This patch table entry is for the specified module. If the requested
+ // import's name matches the entry's import name (or ordinal), then
+ // return the address of the replacement instead of the address of the
+ // actual import.
+ if ((SIZE_T)entry->importname < (SIZE_T)vld.m_vldbase) {
+ // This entry's import name is not a valid pointer to data in
+ // vld.dll. It must be an ordinal value.
+ if ((UINT)entry->importname == (UINT)procname) {
+ return (FARPROC)entry->replacement;
+ }
+ }
+ else {
+ if (strcmp(entry->importname, procname) == 0) {
+ return (FARPROC)entry->replacement;
+ }
+ }
+ }
+
+ // The requested function is not a patched function. Just return the real
+ // address of the requested function.
+ return GetProcAddress(module, procname);
+}
+
+// _HeapCreate - Calls to HeapCreate are patched through to this function. This
+// function is just a wrapper around the real HeapCreate that calls VLD's heap
+// creation tracking function after the heap has been created.
+//
+// - options (IN): Heap options.
+//
+// - initsize (IN): Initial size of the heap.
+//
+// - maxsize (IN): Maximum size of the heap.
+//
+// Return Value:
+//
+// Returns the value returned by HeapCreate.
+//
+HANDLE VisualLeakDetector::_HeapCreate (DWORD options, SIZE_T initsize, SIZE_T maxsize)
+{
+ DWORD64 displacement;
+ SIZE_T fp;
+ SYMBOL_INFO *functioninfo;
+ HANDLE heap;
+ HeapMap::Iterator heapit;
+ SIZE_T ra;
+ BYTE symbolbuffer [sizeof(SYMBOL_INFO) + (MAXSYMBOLNAMELENGTH * sizeof(WCHAR)) - 1] = { 0 };
+ BOOL symfound;
+
+ // Get the return address within the calling function.
+ FRAMEPOINTER(fp);
+ ra = *((SIZE_T*)fp + 1);
+
+ // Create the heap.
+ heap = HeapCreate(options, initsize, maxsize);
+
+ // Map the created heap handle to a new block map.
+ vld.mapheap(heap);
+
+ // Try to get the name of the function containing the return address.
+ functioninfo = (SYMBOL_INFO*)&symbolbuffer;
+ functioninfo->SizeOfStruct = sizeof(SYMBOL_INFO);
+ functioninfo->MaxNameLen = MAXSYMBOLNAMELENGTH;
+ EnterCriticalSection(&symbollock);
+ symfound = SymFromAddrW(currentprocess, ra, &displacement, functioninfo);
+ LeaveCriticalSection(&symbollock);
+ if (symfound == TRUE) {
+ if (wcscmp(L"_heap_init", functioninfo->Name) == 0) {
+ // HeapCreate was called by _heap_init. This is a static CRT heap.
+ EnterCriticalSection(&vld.m_maplock);
+ heapit = vld.m_heapmap->find(heap);
+ assert(heapit != vld.m_heapmap->end());
+ (*heapit).second->flags |= VLD_HEAP_CRT;
+ LeaveCriticalSection(&vld.m_maplock);
+ }
+ }
+
+ return heap;
+}
+
+// _HeapDestroy - Calls to HeapDestroy are patched through to this function.
+// This function is just a wrapper around the real HeapDestroy that calls
+// VLD's heap destruction tracking function after the heap has been destroyed.
+//
+// - heap (IN): Handle to the heap to be destroyed.
+//
+// Return Value:
+//
+// Returns the valued returned by HeapDestroy.
+//
+BOOL VisualLeakDetector::_HeapDestroy (HANDLE heap)
+{
+ // After this heap is destroyed, the heap's address space will be unmapped
+ // from the process's address space. So, we'd better generate a leak report
+ // for this heap now, while we can still read from the memory blocks
+ // allocated to it.
+ vld.reportleaks(heap);
+
+ vld.unmapheap(heap);
+
+ return HeapDestroy(heap);
+}
+
+// _LdrLoadDll - Calls to LdrLoadDll are patched through to this function. This
+// function invokes the real LdrLoadDll and then re-attaches VLD to all
+// modules loaded in the process after loading of the new DLL is complete.
+// All modules must be re-enumerated because the explicit load of the
+// specified module may result in the implicit load of one or more additional
+// modules which are dependencies of the specified module.
+//
+// - searchpath (IN): The path to use for searching for the specified module to
+// be loaded.
+//
+// - flags (IN): Pointer to action flags.
+//
+// - modulename (IN): Pointer to a unicodestring_t structure specifying the
+// name of the module to be loaded.
+//
+// - modulehandle (OUT): Address of a HANDLE to receive the newly loaded
+// module's handle.
+//
+// Return Value:
+//
+// Returns the value returned by LdrLoadDll.
+//
+NTSTATUS VisualLeakDetector::_LdrLoadDll (LPWSTR searchpath, PDWORD flags, unicodestring_t *modulename,
+ PHANDLE modulehandle)
+{
+ ModuleSet::Iterator moduleit;
+ ModuleSet *newmodules;
+ ModuleSet *oldmodules;
+ NTSTATUS status;
+
+ EnterCriticalSection(&vld.m_loaderlock);
+
+ // Load the DLL.
+ status = LdrLoadDll(searchpath, flags, modulename, modulehandle);
+
+ if (STATUS_SUCCESS == status) {
+ // Create a new set of all loaded modules, including any newly loaded
+ // modules.
+ newmodules = new ModuleSet;
+ newmodules->reserve(MODULESETRESERVE);
+ EnumerateLoadedModulesW64(currentprocess, addloadedmodule, newmodules);
+
+ // Attach to all modules included in the set.
+ vld.attachtoloadedmodules(newmodules);
+
+ // Start using the new set of loaded modules.
+ EnterCriticalSection(&vld.m_moduleslock);
+ oldmodules = vld.m_loadedmodules;
+ vld.m_loadedmodules = newmodules;
+ LeaveCriticalSection(&vld.m_moduleslock);
+
+ // Free resources used by the old module list.
+ for (moduleit = oldmodules->begin(); moduleit != oldmodules->end(); ++moduleit) {
+ delete (*moduleit).name;
+ delete (*moduleit).path;
+ }
+ delete oldmodules;
+ }
+
+ LeaveCriticalSection(&vld.m_loaderlock);
+
+ return status;
+}
+
+// _RtlAllocateHeap - Calls to RtlAllocateHeap are patched through to this
+// function. This function invokes the real RtlAllocateHeap and then calls
+// VLD's allocation tracking function. Pretty much all memory allocations
+// will eventually result in a call to RtlAllocateHeap, so this is where we
+// finally map the allocated block.
+//
+// - heap (IN): Handle to the heap from which to allocate memory.
+//
+// - flags (IN): Heap allocation control flags.
+//
+// - size (IN): Size, in bytes, of the block to allocate.
+//
+// Return Value:
+//
+// Returns the return value from RtlAllocateHeap.
+//
+LPVOID VisualLeakDetector::_RtlAllocateHeap (HANDLE heap, DWORD flags, SIZE_T size)
+{
+ BOOL crtalloc;
+ BOOL excluded = FALSE;
+ SIZE_T fp;
+ LPVOID block;
+ moduleinfo_t moduleinfo;
+ ModuleSet::Iterator moduleit;
+ SIZE_T returnaddress;
+ tls_t *tls = vld.gettls();
+
+ // Allocate the block.
+ block = RtlAllocateHeap(heap, flags, size);
+ if ((block != NULL) && vld.enabled()) {
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ FRAMEPOINTER(fp);
+ }
+ else {
+ fp = tls->addrfp;
+ }
+ crtalloc = (tls->flags & VLD_TLS_CRTALLOC) ? TRUE : FALSE;
+
+ // Reset thread local flags and variables, in case any libraries called
+ // into while mapping the block allocate some memory.
+ tls->addrfp = 0x0;
+ tls->flags &=~VLD_TLS_CRTALLOC;
+
+ // Find the information for the module that initiated this allocation.
+ returnaddress = *((SIZE_T*)fp + 1);
+ moduleinfo.addrhigh = returnaddress;
+ moduleinfo.addrlow = returnaddress;
+ EnterCriticalSection(&vld.m_moduleslock);
+ moduleit = vld.m_loadedmodules->find(moduleinfo);
+ if (moduleit != vld.m_loadedmodules->end()) {
+ excluded = (*moduleit).flags & VLD_MODULE_EXCLUDED ? TRUE : FALSE;
+ }
+ LeaveCriticalSection(&vld.m_moduleslock);
+ if (!excluded) {
+ // The module that initiated this allocation is included in leak
+ // detection. Map this block to the specified heap.
+ vld.mapblock(heap, block, size, fp, crtalloc);
+ }
+ }
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// _RtlFreeHeap - Calls to RtlFreeHeap are patched through to this function.
+// This function calls VLD's free tracking function and then invokes the real
+// RtlFreeHeap. Pretty much all memory frees will eventually result in a call
+// to RtlFreeHeap, so this is where we finally unmap the freed block.
+//
+// - heap (IN): Handle to the heap to which the block being freed belongs.
+//
+// - flags (IN): Heap control flags.
+//
+// - mem (IN): Pointer to the memory block being freed.
+//
+// Return Value:
+//
+// Returns the value returned by RtlFreeHeap.
+//
+BOOL VisualLeakDetector::_RtlFreeHeap (HANDLE heap, DWORD flags, LPVOID mem)
+{
+ BOOL status;
+
+ // Unmap the block from the specified heap.
+ vld.unmapblock(heap, mem);
+
+ status = RtlFreeHeap(heap, flags, mem);
+
+ return status;
+}
+
+// _RtlReAllocateHeap - Calls to RtlReAllocateHeap are patched through to this
+// function. This function invokes the real RtlReAllocateHeap and then calls
+// VLD's reallocation tracking function. All arguments passed to this function
+// are passed on to the real RtlReAllocateHeap without modification. Pretty
+// much all memory re-allocations will eventually result in a call to
+// RtlReAllocateHeap, so this is where we finally remap the reallocated block.
+//
+// - heap (IN): Handle to the heap to reallocate memory from.
+//
+// - flags (IN): Heap control flags.
+//
+// - mem (IN): Pointer to the currently allocated block which is to be
+// reallocated.
+//
+// - size (IN): Size, in bytes, of the block to reallocate.
+//
+// Return Value:
+//
+// Returns the value returned by RtlReAllocateHeap.
+//
+LPVOID VisualLeakDetector::_RtlReAllocateHeap (HANDLE heap, DWORD flags, LPVOID mem, SIZE_T size)
+{
+ BOOL crtalloc;
+ BOOL excluded = FALSE;
+ SIZE_T fp;
+ moduleinfo_t moduleinfo;
+ ModuleSet::Iterator moduleit;
+ LPVOID newmem;
+ SIZE_T returnaddress;
+ tls_t *tls = vld.gettls();
+
+ // Reallocate the block.
+ newmem = RtlReAllocateHeap(heap, flags, mem, size);
+
+ if (newmem != NULL) {
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ FRAMEPOINTER(fp);
+ }
+ else {
+ fp = tls->addrfp;
+ }
+ crtalloc = (tls->flags & VLD_TLS_CRTALLOC) ? TRUE : FALSE;
+
+ // Reset thread local flags and variables, in case any libraries called
+ // into while remapping the block allocate some memory.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ // Find the information for the module that initiated this reallocation.
+ returnaddress = *((SIZE_T*)fp + 1);
+ moduleinfo.addrhigh = returnaddress;
+ moduleinfo.addrlow = returnaddress;
+ EnterCriticalSection(&vld.m_moduleslock);
+ moduleit = vld.m_loadedmodules->find(moduleinfo);
+ if (moduleit != vld.m_loadedmodules->end()) {
+ excluded = (*moduleit).flags & VLD_MODULE_EXCLUDED ? TRUE : FALSE;
+ }
+ LeaveCriticalSection(&vld.m_moduleslock);
+ if (!excluded) {
+ // The module that initiated this allocation is included in leak
+ // detection. Remap the block.
+ vld.remapblock(heap, mem, newmem, size, fp, crtalloc);
+ }
+ }
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return newmem;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// COM IAT Replacement Functions
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// _CoGetMalloc - Calls to CoGetMalloc are patched through to this function.
+// This function returns a pointer to Visual Leak Detector's implementation
+// of the IMalloc interface, instead of returning a pointer to the system
+// implementation. This allows VLD's implementation of the IMalloc interface
+// (which is basically a thin wrapper around the system implementation) to be
+// invoked in place of the system implementation.
+//
+// - context (IN): Reserved; value must be 1.
+//
+// - imalloc (IN): Address of a pointer to receive the address of VLD's
+// implementation of the IMalloc interface.
+//
+// Return Value:
+//
+// Always returns S_OK.
+//
+HRESULT VisualLeakDetector::_CoGetMalloc (DWORD context, LPMALLOC *imalloc)
+{
+ static CoGetMalloc_t pCoGetMalloc = NULL;
+
+ HMODULE ole32;
+
+ *imalloc = (LPMALLOC)&vld;
+
+ if (pCoGetMalloc == NULL) {
+ // This is the first call to this function. Link to the real
+ // CoGetMalloc and get a pointer to the system implementation of the
+ // IMalloc interface.
+ ole32 = GetModuleHandle(L"ole32.dll");
+ pCoGetMalloc = (CoGetMalloc_t)GetProcAddress(ole32, "CoGetMalloc");
+ pCoGetMalloc(context, &vld.m_imalloc);
+ }
+
+ return S_OK;
+}
+
+// _CoTaskMemAlloc - Calls to CoTaskMemAlloc are patched through to this
+// function. This function is just a wrapper around the real CoTaskMemAlloc
+// that sets appropriate flags to be consulted when the memory is actually
+// allocated by RtlAllocateHeap.
+//
+// - size (IN): Size of the memory block to allocate.
+//
+// Return Value:
+//
+// Returns the value returned from CoTaskMemAlloc.
+//
+LPVOID VisualLeakDetector::_CoTaskMemAlloc (ULONG size)
+{
+ static CoTaskMemAlloc_t pCoTaskMemAlloc = NULL;
+
+ LPVOID block;
+ SIZE_T fp;
+ HMODULE ole32;
+ tls_t *tls = vld.gettls();
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ FRAMEPOINTER(fp);
+ tls->addrfp = fp;
+ }
+
+ if (pCoTaskMemAlloc == NULL) {
+ // This is the first call to this function. Link to the real
+ // CoTaskMemAlloc.
+ ole32 = GetModuleHandle(L"ole32.dll");
+ pCoTaskMemAlloc = (CoTaskMemAlloc_t)GetProcAddress(ole32, "CoTaskMemAlloc");
+ }
+
+ // Do the allocation. The block will be mapped by _RtlAllocateHeap.
+ block = pCoTaskMemAlloc(size);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// _CoTaskMemRealloc - Calls to CoTaskMemRealloc are patched through to this
+// function. This function is just a wrapper around the real CoTaskMemRealloc
+// that sets appropriate flags to be consulted when the memory is actually
+// allocated by RtlAllocateHeap.
+//
+// - mem (IN): Pointer to the memory block to reallocate.
+//
+// - size (IN): Size, in bytes, of the block to reallocate.
+//
+// Return Value:
+//
+// Returns the value returned from CoTaskMemRealloc.
+//
+LPVOID VisualLeakDetector::_CoTaskMemRealloc (LPVOID mem, ULONG size)
+{
+ static CoTaskMemRealloc_t pCoTaskMemRealloc = NULL;
+
+ LPVOID block;
+ SIZE_T fp;
+ HMODULE ole32;
+ tls_t *tls = vld.gettls();
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ FRAMEPOINTER(fp);
+ tls->addrfp = fp;
+ }
+
+ if (pCoTaskMemRealloc == NULL) {
+ // This is the first call to this function. Link to the real
+ // CoTaskMemRealloc.
+ ole32 = GetModuleHandle(L"ole32.dll");
+ pCoTaskMemRealloc = (CoTaskMemRealloc_t)GetProcAddress(ole32, "CoTaskMemRealloc");
+ }
+
+ // Do the allocation. The block will be mapped by _RtlReAllocateHeap.
+ block = pCoTaskMemRealloc(mem, size);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Public COM IMalloc Implementation Functions
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// AddRef - Calls to IMalloc::AddRef end up here. This function is just a
+// wrapper around the real IMalloc::AddRef implementation.
+//
+// Return Value:
+//
+// Returns the value returned by the system implementation of
+// IMalloc::AddRef.
+//
+ULONG VisualLeakDetector::AddRef ()
+{
+ assert(m_imalloc != NULL);
+ return m_imalloc->AddRef();
+}
+
+// Alloc - Calls to IMalloc::Alloc end up here. This function is just a wrapper
+// around the real IMalloc::Alloc implementation that sets appropriate flags
+// to be consulted when the memory is actually allocated by RtlAllocateHeap.
+//
+// - size (IN): The size of the memory block to allocate.
+//
+// Return Value:
+//
+// Returns the value returned by the system's IMalloc::Alloc implementation.
+//
+LPVOID VisualLeakDetector::Alloc (ULONG size)
+{
+ LPVOID block;
+ SIZE_T fp;
+ tls_t *tls = vld.gettls();
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ FRAMEPOINTER(fp);
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlAllocateHeap.
+ assert(m_imalloc != NULL);
+ block = m_imalloc->Alloc(size);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// DidAlloc - Calls to IMalloc::DidAlloc will end up here. This function is just
+// a wrapper around the system implementation of IMalloc::DidAlloc.
+//
+// - mem (IN): Pointer to a memory block to inquire about.
+//
+// Return Value:
+//
+// Returns the value returned by the system implementation of
+// IMalloc::DidAlloc.
+//
+INT VisualLeakDetector::DidAlloc (LPVOID mem)
+{
+ assert(m_imalloc != NULL);
+ return m_imalloc->DidAlloc(mem);
+}
+
+// Free - Calls to IMalloc::Free will end up here. This function is just a
+// wrapper around the real IMalloc::Free implementation.
+//
+// - mem (IN): Pointer to the memory block to be freed.
+//
+// Return Value:
+//
+// None.
+//
+VOID VisualLeakDetector::Free (LPVOID mem)
+{
+ assert(m_imalloc != NULL);
+ m_imalloc->Free(mem);
+}
+
+// GetSize - Calls to IMalloc::GetSize will end up here. This function is just a
+// wrapper around the real IMalloc::GetSize implementation.
+//
+// - mem (IN): Pointer to the memory block to inquire about.
+//
+// Return Value:
+//
+// Returns the value returned by the system implementation of
+// IMalloc::GetSize.
+//
+ULONG VisualLeakDetector::GetSize (LPVOID mem)
+{
+ assert(m_imalloc != NULL);
+ return m_imalloc->GetSize(mem);
+}
+
+// HeapMinimize - Calls to IMalloc::HeapMinimize will end up here. This function
+// is just a wrapper around the real IMalloc::HeapMinimize implementation.
+//
+// Return Value:
+//
+// None.
+//
+VOID VisualLeakDetector::HeapMinimize ()
+{
+ assert(m_imalloc != NULL);
+ m_imalloc->HeapMinimize();
+}
+
+// QueryInterface - Calls to IMalloc::QueryInterface will end up here. This
+// function is just a wrapper around the real IMalloc::QueryInterface
+// implementation.
+//
+// - iid (IN): COM interface ID to query about.
+//
+// - object (IN): Address of a pointer to receive the requested interface
+// pointer.
+//
+// Return Value:
+//
+// Returns the value returned by the system implementation of
+// IMalloc::QueryInterface.
+//
+HRESULT VisualLeakDetector::QueryInterface (REFIID iid, LPVOID *object)
+{
+ assert(m_imalloc != NULL);
+ return m_imalloc->QueryInterface(iid, object);
+}
+
+// Realloc - Calls to IMalloc::Realloc will end up here. This function is just a
+// wrapper around the real IMalloc::Realloc implementation that sets
+// appropriate flags to be consulted when the memory is actually allocated by
+// RtlAllocateHeap.
+//
+// - mem (IN): Pointer to the memory block to reallocate.
+//
+// - size (IN): Size, in bytes, of the memory block to reallocate.
+//
+// Return Value:
+//
+// Returns the value returned by the system implementation of
+// IMalloc::Realloc.
+//
+LPVOID VisualLeakDetector::Realloc (LPVOID mem, ULONG size)
+{
+ LPVOID block;
+ SIZE_T fp;
+ tls_t *tls = vld.gettls();
+
+ if (tls->addrfp == 0x0) {
+ // This is the first call to enter VLD for the current allocation.
+ // Record the current frame pointer.
+ FRAMEPOINTER(fp);
+ tls->addrfp = fp;
+ }
+
+ // Do the allocation. The block will be mapped by _RtlReAllocateHeap.
+ assert(m_imalloc != NULL);
+ block = m_imalloc->Realloc(mem, size);
+
+ // Reset thread local flags and variables for the next allocation.
+ tls->addrfp = 0x0;
+ tls->flags &= ~VLD_TLS_CRTALLOC;
+
+ return block;
+}
+
+// Release - Calls to IMalloc::Release will end up here. This function is just
+// a wrapper around the real IMalloc::Release implementation.
+//
+// Return Value:
+//
+// Returns the value returned by the system implementation of
+// IMalloc::Release.
+//
+ULONG VisualLeakDetector::Release ()
+{
+ assert(m_imalloc != NULL);
+ return m_imalloc->Release();
+}
diff --git a/development/Win32/vld/include/vld.h b/development/Win32/vld/src/vld.h
similarity index 95%
rename from development/Win32/vld/include/vld.h
rename to development/Win32/vld/src/vld.h
index c6213de000..234c87f3ed 100644
--- a/development/Win32/vld/include/vld.h
+++ b/development/Win32/vld/src/vld.h
@@ -1,106 +1,97 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Visual Leak Detector - Import Library Header
-// Copyright (c) 2006 Dan Moulding
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-// See COPYING.txt for the full terms of the GNU Lesser General Public License.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-#ifdef VLD_BUILD
-#define VLD_EXPORT __declspec(dllexport)
-#else
-
-#define VLD_EXPORT __declspec(dllimport)
-
-#pragma comment(lib, "vld.lib")
-
-// Force a symbolic reference to the global VisualLeakDetector class object from
-// the DLL. This enusres that the DLL is loaded and linked with the program,
-// even if no code otherwise imports any of the DLL's exports.
-#pragma comment(linker, "/include:__imp_?vld@@3VVisualLeakDetector@@A")
-
-#endif
-
-
-#ifdef _DEBUG
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Visual Leak Detector APIs
-//
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-// VLDDisable - Disables Visual Leak Detector's memory leak detection at
-// runtime. If memory leak detection is already disabled, then calling this
-// function has no effect.
-//
-// Note: In multithreaded programs, this function operates on a per-thread
-// basis. In other words, if you call this function from one thread, then
-// memory leak detection is only disabled for that thread. If memory leak
-// detection is enabled for other threads, then it will remain enabled for
-// those other threads. It was designed to work this way to insulate you,
-// the programmer, from having to ensure thread synchronization when calling
-// VLDEnable() and VLDDisable(). Without this, calling these two functions
-// unsychronized could result in unpredictable and unintended behavior.
-// But this also means that if you want to disable memory leak detection
-// process-wide, then you need to call this function from every thread in
-// the process.
-//
-// Return Value:
-//
-// None.
-//
-VLD_EXPORT void VLDDisable ();
-
-// VLDEnable - Enables Visual Leak Detector's memory leak detection at runtime.
-// If memory leak detection is already enabled, which it is by default, then
-// calling this function has no effect.
-//
-// Note: In multithreaded programs, this function operates on a per-thread
-// basis. In other words, if you call this function from one thread, then
-// memory leak detection is only enabled for that thread. If memory leak
-// detection is disabled for other threads, then it will remain disabled for
-// those other threads. It was designed to work this way to insulate you,
-// the programmer, from having to ensure thread synchronization when calling
-// VLDEnable() and VLDDisable(). Without this, calling these two functions
-// unsychronized could result in unpredictable and unintended behavior.
-// But this also means that if you want to enable memory leak detection
-// process-wide, then you need to call this function from every thread in
-// the process.
-//
-// Return Value:
-//
-// None.
-//
-VLD_EXPORT void VLDEnable ();
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#else // !_DEBUG
-
-#define VLDEnable()
-#define VLDDisable()
-
-#endif // _DEBUG
+////////////////////////////////////////////////////////////////////////////////
+//
+// Visual Leak Detector - Import Library Header
+// Copyright (c) 2006 Dan Moulding
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// See COPYING.txt for the full terms of the GNU Lesser General Public License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#ifdef _DEBUG
+
+#pragma comment(lib, "vld.lib")
+
+// Force a symbolic reference to the global VisualLeakDetector class object from
+// the DLL. This enusres that the DLL is loaded and linked with the program,
+// even if no code otherwise imports any of the DLL's exports.
+#pragma comment(linker, "/include:__imp_?vld@@3VVisualLeakDetector@@A")
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Visual Leak Detector APIs
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+// VLDDisable - Disables Visual Leak Detector's memory leak detection at
+// runtime. If memory leak detection is already disabled, then calling this
+// function has no effect.
+//
+// Note: In multithreaded programs, this function operates on a per-thread
+// basis. In other words, if you call this function from one thread, then
+// memory leak detection is only disabled for that thread. If memory leak
+// detection is enabled for other threads, then it will remain enabled for
+// those other threads. It was designed to work this way to insulate you,
+// the programmer, from having to ensure thread synchronization when calling
+// VLDEnable() and VLDDisable(). Without this, calling these two functions
+// unsychronized could result in unpredictable and unintended behavior.
+// But this also means that if you want to disable memory leak detection
+// process-wide, then you need to call this function from every thread in
+// the process.
+//
+// Return Value:
+//
+// None.
+//
+__declspec(dllimport) void VLDDisable ();
+
+// VLDEnable - Enables Visual Leak Detector's memory leak detection at runtime.
+// If memory leak detection is already enabled, which it is by default, then
+// calling this function has no effect.
+//
+// Note: In multithreaded programs, this function operates on a per-thread
+// basis. In other words, if you call this function from one thread, then
+// memory leak detection is only enabled for that thread. If memory leak
+// detection is disabled for other threads, then it will remain disabled for
+// those other threads. It was designed to work this way to insulate you,
+// the programmer, from having to ensure thread synchronization when calling
+// VLDEnable() and VLDDisable(). Without this, calling these two functions
+// unsychronized could result in unpredictable and unintended behavior.
+// But this also means that if you want to enable memory leak detection
+// process-wide, then you need to call this function from every thread in
+// the process.
+//
+// Return Value:
+//
+// None.
+//
+__declspec(dllimport) void VLDEnable ();
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#else // !_DEBUG
+
+#define VLDEnable()
+#define VLDDisable()
+
+#endif // _DEBUG
diff --git a/development/Win32/vld/src/vldapi.cpp b/development/Win32/vld/src/vldapi.cpp
index 9ff15e5e93..eb29ef267b 100644
--- a/development/Win32/vld/src/vldapi.cpp
+++ b/development/Win32/vld/src/vldapi.cpp
@@ -1,5 +1,4 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: vldapi.cpp,v 1.19 2006/11/18 03:12:35 dmouldin Exp $
//
// Visual Leak Detector - Exported APIs
// Copyright (c) 2005-2006 Dan Moulding
diff --git a/development/Win32/vld/src/vldheap.cpp b/development/Win32/vld/src/vldheap.cpp
index cb2d13972c..b6dff2eed3 100644
--- a/development/Win32/vld/src/vldheap.cpp
+++ b/development/Win32/vld/src/vldheap.cpp
@@ -1,5 +1,4 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: vldheap.cpp,v 1.13 2006/11/18 03:12:35 dmouldin Exp $
//
// Visual Leak Detector - Internal C++ Heap Management
// Copyright (c) 2006 Dan Moulding
@@ -35,7 +34,7 @@ CRITICAL_SECTION vldheaplock; // Serializes access to VLD's private hea
// Local helper functions.
static inline void vlddelete (void *block);
-static inline void* vldnew (unsigned int size, const char *file, int line);
+static inline void* vldnew (size_t size, const char *file, int line);
// scalar delete operator - Delete operator used to free internally used memory
// back to VLD's private heap.
@@ -105,7 +104,7 @@ void operator delete [] (void *block, const char *, int)
// If the allocation succeeds, a pointer to the allocated memory block is
// returned. If the allocation fails, NULL is returned.
//
-void* operator new (unsigned int size, const char *file, int line)
+void* operator new (size_t size, const char *file, int line)
{
return vldnew(size, file, line);
}
@@ -126,7 +125,7 @@ void* operator new (unsigned int size, const char *file, int line)
// If the allocation succeeds, a pointer to the allocated memory block is
// returned. If the allocation fails, NULL is returned.
//
-void* operator new [] (unsigned int size, const char *file, int line)
+void* operator new [] (size_t size, const char *file, int line)
{
return vldnew(size, file, line);
}
@@ -182,7 +181,7 @@ void vlddelete (void *block)
// If the memory allocation succeeds, a pointer to the allocated memory
// block is returned. If the allocation fails, NULL is returned.
//
-void* vldnew (unsigned int size, const char *file, int line)
+void* vldnew (size_t size, const char *file, int line)
{
vldblockheader_t *header = (vldblockheader_t*)RtlAllocateHeap(vldheap, 0x0, size + sizeof(vldblockheader_t));
static SIZE_T serialnumber = 0;
@@ -210,4 +209,4 @@ void* vldnew (unsigned int size, const char *file, int line)
// Return a pointer to the beginning of the data section of the block.
return (void*)VLDBLOCKDATA(header);
-}
\ No newline at end of file
+}
diff --git a/development/Win32/vld/src/vldheap.h b/development/Win32/vld/src/vldheap.h
index ccbc07621c..72bd91c091 100644
--- a/development/Win32/vld/src/vldheap.h
+++ b/development/Win32/vld/src/vldheap.h
@@ -1,5 +1,4 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: vldheap.h,v 1.11 2006/11/18 03:12:35 dmouldin Exp $
//
// Visual Leak Detector - Internal C++ Heap Management Definitions
// Copyright (c) 2006 Dan Moulding
@@ -72,7 +71,7 @@ typedef struct vldblockheader_s
struct vldblockheader_s *prev; // Pointer to the preceding block in the list of internally allocated blocks.
const char *file; // Name of the file where this block was allocated.
int line; // Line number within the above file where this block was allocated.
- unsigned int size; // The size of this memory block, not including this header.
+ size_t size; // The size of this memory block, not including this header.
SIZE_T serialnumber; // Each block is assigned a unique serial number, starting from zero.
} vldblockheader_t;
@@ -87,8 +86,8 @@ void operator delete (void *block);
void operator delete [] (void *block);
void operator delete (void *block, const char *file, int line);
void operator delete [] (void *block, const char *file, int line);
-void* operator new (unsigned int size, const char *file, int line);
-void* operator new [] (unsigned int size, const char *file, int line);
+void* operator new (size_t size, const char *file, int line);
+void* operator new [] (size_t size, const char *file, int line);
// All calls to the new operator from within VLD are mapped to the version of
// new that allocates from VLD's private heap.
diff --git a/development/Win32/vld/src/vldint.h b/development/Win32/vld/src/vldint.h
index ed87293baf..2c07607675 100644
--- a/development/Win32/vld/src/vldint.h
+++ b/development/Win32/vld/src/vldint.h
@@ -1,8 +1,7 @@
////////////////////////////////////////////////////////////////////////////////
-// $Id: vldint.h,v 1.45 2006/11/18 05:17:09 dmouldin Exp $
//
// Visual Leak Detector - VisualLeakDetector Class Definition
-// Copyright (c) 2005-2006 Dan Moulding
+// Copyright (c) 2005-2009 Dan Moulding
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -42,12 +41,27 @@ Applications should never include this header."
#define SELFTESTTEXTA "Memory Leak Self-Test"
#define SELFTESTTEXTW L"Memory Leak Self-Test"
#define VLDREGKEYPRODUCT L"Software\\Visual Leak Detector"
-#define VLDVERSION L"1.9f"
+#define VLDVERSION L"1.9h"
// The Visual Leak Detector APIs.
extern "C" __declspec(dllexport) void VLDDisable ();
extern "C" __declspec(dllexport) void VLDEnable ();
+// Function pointer types for explicit dynamic linking with functions listed in
+// the import patch table.
+typedef void* (__cdecl *_calloc_dbg_t) (size_t, size_t, int, const char*, int);
+typedef void* (__cdecl *_malloc_dbg_t) (size_t, int, const char *, int);
+typedef void* (__cdecl *_realloc_dbg_t) (void *, size_t, int, const char *, int);
+typedef void* (__cdecl *calloc_t) (size_t, size_t);
+typedef HRESULT (__stdcall *CoGetMalloc_t) (DWORD, LPMALLOC *);
+typedef LPVOID (__stdcall *CoTaskMemAlloc_t) (ULONG);
+typedef LPVOID (__stdcall *CoTaskMemRealloc_t) (LPVOID, ULONG);
+typedef void* (__cdecl *malloc_t) (size_t);
+typedef void* (__cdecl *new_t) (size_t);
+typedef void* (__cdecl *new_dbg_crt_t) (size_t, int, const char *, int);
+typedef void* (__cdecl *new_dbg_mfc_t) (size_t, const char *, int);
+typedef void* (__cdecl *realloc_t) (void *, size_t);
+
// Data is collected for every block allocated from any heap in the process.
// The data is stored in this structure and these structures are stored in
// a BlockMap which maps each of these structures to its corresponding memory
@@ -100,7 +114,7 @@ typedef struct moduleinfo_s {
typedef Set ModuleSet;
// Thread local storage structure. Every thread in the process gets its own copy
-// of this structure. Thread specific information, such as the currentl leak
+// of this structure. Thread specific information, such as the current leak
// detection status (enabled or disabled) and the address that initiated the
// current allocation is stored here.
typedef struct tls_s {
@@ -148,73 +162,88 @@ public:
VisualLeakDetector();
~VisualLeakDetector();
- // Public IMalloc methods - for support of COM-based memory leak detection.
- ULONG __stdcall AddRef ();
- LPVOID __stdcall Alloc (ULONG size);
- INT __stdcall DidAlloc (LPVOID mem);
- VOID __stdcall Free (LPVOID mem);
- ULONG __stdcall GetSize (LPVOID mem);
- VOID __stdcall HeapMinimize ();
+////////////////////////////////////////////////////////////////////////////////
+// Public CRT and MFC Common Handlers
+//
+// Many heap functions are indirectly rerouted to these handlers. One common
+// function exists for each heap function with a given signature. These
+// handlers are not direct IAT replacements, but are called by the individual
+// IAT replacement functions.
+////////////////////////////////////////////////////////////////////////////////
+ // Standard CRT and MFC common handlers
+ void* _calloc (calloc_t pcalloc, SIZE_T fp, size_t num, size_t size);
+ void* _malloc (malloc_t pmalloc, SIZE_T fp, size_t size);
+ void* _new (new_t pnew, SIZE_T fp, size_t size);
+ void* _realloc (realloc_t prealloc, SIZE_T fp, void *mem, size_t size);
+
+ // Debug CRT and MFC common handlers
+ 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);
+ void* __malloc_dbg (_malloc_dbg_t p_malloc_dbg, SIZE_T fp, size_t size, int type, char const *file, int line);
+ void* new_dbg_crt (new_dbg_crt_t pnew_dbg_crt, SIZE_T fp, size_t size, int type, char const *file, int line);
+ void* new_dbg_mfc (new_dbg_crt_t pnew_dbg, SIZE_T fp, size_t size, int type, char const *file, int line);
+ void* new_dbg_mfc (new_dbg_mfc_t pnew_dbg_mfc, SIZE_T fp, size_t size, char const *file, int line);
+ void* __realloc_dbg (_realloc_dbg_t p_realloc_dbg, SIZE_T fp, void *mem, size_t size, int type, char const *file, int line);
+
+////////////////////////////////////////////////////////////////////////////////
+// Public IMalloc methods - for support of COM-based memory leak detection.
+////////////////////////////////////////////////////////////////////////////////
+ ULONG __stdcall AddRef ();
+ LPVOID __stdcall Alloc (ULONG size);
+ INT __stdcall DidAlloc (LPVOID mem);
+ VOID __stdcall Free (LPVOID mem);
+ ULONG __stdcall GetSize (LPVOID mem);
+ VOID __stdcall HeapMinimize ();
HRESULT __stdcall QueryInterface (REFIID iid, LPVOID *object);
- LPVOID __stdcall Realloc (LPVOID mem, ULONG size);
- ULONG __stdcall Release ();
+ LPVOID __stdcall Realloc (LPVOID mem, ULONG size);
+ ULONG __stdcall Release ();
private:
- // Import patching replacement functions - see each function definition for details.
- static HRESULT __stdcall _CoGetMalloc (DWORD context, LPMALLOC *imalloc);
- static LPVOID __stdcall _CoTaskMemAlloc (ULONG size);
- static LPVOID __stdcall _CoTaskMemRealloc (LPVOID mem, ULONG size);
- static void* __cdecl _crt80d__calloc_dbg (size_t num, size_t size, int type, const char *file, int line);
- static void* __cdecl _crt80d__malloc_dbg (size_t size, int type, const char *file, int line);
- static void* __cdecl _crt80d__realloc_dbg (void *mem, size_t size, int type, const char *file, int line);
- static void* __cdecl _crt80d__scalar_new_dbg (unsigned int size, int type, const char *file, int line);
- static void* __cdecl _crt80d__vector_new_dbg (unsigned int size, int type, const char *file, int line);
- static void* __cdecl _crt80d_calloc (size_t num, size_t size);
- static void* __cdecl _crt80d_malloc (size_t size);
- static void* __cdecl _crt80d_realloc (void *mem, size_t size);
- static void* __cdecl _crt80d_scalar_new (unsigned int size);
- static void* __cdecl _crt80d_vector_new (unsigned int size);
- static void* __cdecl _crtd__calloc_dbg (size_t num, size_t size, int type, const char *file, int line);
- static void* __cdecl _crtd__malloc_dbg (size_t size, int type, const char *file, int line);
- static void* __cdecl _crtd__realloc_dbg (void *mem, size_t size, int type, const char *file, int line);
- static void* __cdecl _crtd__scalar_new_dbg (unsigned int size, int type, const char *file, int line);
- static void* __cdecl _crtd_calloc (size_t num, size_t size);
- static void* __cdecl _crtd_malloc (size_t size);
- static void* __cdecl _crtd_realloc (void *mem, size_t size);
- static void* __cdecl _crtd_scalar_new (unsigned int size);
- static FARPROC __stdcall _GetProcAddress(HMODULE module, LPCSTR procname);
- static HANDLE __stdcall _HeapCreate (DWORD options, SIZE_T initsize, SIZE_T maxsize);
- static BOOL __stdcall _HeapDestroy (HANDLE heap);
- static NTSTATUS __stdcall _LdrLoadDll (LPWSTR searchpath, PDWORD flags, unicodestring_t *modulename,
- PHANDLE modulehandle);
- static void* __cdecl _mfc42d__scalar_new_dbg (unsigned int size, const char *file, int line);
- static void* __cdecl _mfc42d_scalar_new (unsigned int size);
- static void* __cdecl _mfc80d__scalar_new_dbg (unsigned int size, const char *file, int line);
- static void* __cdecl _mfc80d__vector_new_dbg (unsigned int size, const char *file, int line);
- static void* __cdecl _mfc80d_scalar_new (unsigned int size);
- static void* __cdecl _mfc80d_vector_new (unsigned int size);
- static LPVOID __stdcall _RtlAllocateHeap (HANDLE heap, DWORD flags, SIZE_T size);
- static BOOL __stdcall _RtlFreeHeap (HANDLE heap, DWORD flags, LPVOID mem);
- static LPVOID __stdcall _RtlReAllocateHeap (HANDLE heap, DWORD flags, LPVOID mem, SIZE_T size);
-
- // Private functions - see each function definition for details.
- static BOOL __stdcall addloadedmodule (PCWSTR modulepath, DWORD64 modulebase, ULONG modulesize, PVOID context);
- VOID attachtoloadedmodules (ModuleSet *newmodules);
+////////////////////////////////////////////////////////////////////////////////
+// Private leak detection functions - see each function definition for details.
+////////////////////////////////////////////////////////////////////////////////
+ VOID attachtoloadedmodules (ModuleSet *newmodules);
LPWSTR buildsymbolsearchpath ();
- VOID configure ();
- static BOOL __stdcall detachfrommodule (PCWSTR modulepath, DWORD64 modulebase, ULONG modulesize, PVOID context);
- BOOL enabled ();
+ VOID configure ();
+ BOOL enabled ();
SIZE_T eraseduplicates (const BlockMap::Iterator &element);
tls_t* gettls ();
- VOID mapblock (HANDLE heap, LPCVOID mem, SIZE_T size, SIZE_T framepointer, BOOL crtalloc);
- VOID mapheap (HANDLE heap);
- VOID remapblock (HANDLE heap, LPCVOID mem, LPCVOID newmem, SIZE_T size, SIZE_T framepointer, BOOL crtalloc);
- VOID reportconfig ();
- VOID reportleaks (HANDLE heap);
- VOID unmapblock (HANDLE heap, LPCVOID mem);
- VOID unmapheap (HANDLE heap);
+ VOID mapblock (HANDLE heap, LPCVOID mem, SIZE_T size, SIZE_T framepointer, BOOL crtalloc);
+ VOID mapheap (HANDLE heap);
+ VOID remapblock (HANDLE heap, LPCVOID mem, LPCVOID newmem, SIZE_T size, SIZE_T framepointer, BOOL crtalloc);
+ VOID reportconfig ();
+ VOID reportleaks (HANDLE heap);
+ VOID unmapblock (HANDLE heap, LPCVOID mem);
+ VOID unmapheap (HANDLE heap);
- // Private data.
+ // Static functions (callbacks)
+ static BOOL __stdcall addloadedmodule (PCWSTR modulepath, DWORD64 modulebase, ULONG modulesize, PVOID context);
+ static BOOL __stdcall detachfrommodule (PCWSTR modulepath, DWORD64 modulebase, ULONG modulesize, PVOID context);
+
+////////////////////////////////////////////////////////////////////////////////
+// IAT replacement functions - see each function definition for details.
+//
+// Because there are so many virtually identical CRT and MFC replacement
+// functions, they are excluded from the class to reduce the amount of noise
+// within this class's code. See crtmfcpatch.cpp for those functions.
+////////////////////////////////////////////////////////////////////////////////
+ // Win32 IAT replacement functions
+ static FARPROC __stdcall _GetProcAddress (HMODULE module, LPCSTR procname);
+ static HANDLE __stdcall _HeapCreate (DWORD options, SIZE_T initsize, SIZE_T maxsize);
+ static BOOL __stdcall _HeapDestroy (HANDLE heap);
+ static NTSTATUS __stdcall _LdrLoadDll (LPWSTR searchpath, PDWORD flags, unicodestring_t *modulename,
+ PHANDLE modulehandle);
+ static LPVOID __stdcall _RtlAllocateHeap (HANDLE heap, DWORD flags, SIZE_T size);
+ static BOOL __stdcall _RtlFreeHeap (HANDLE heap, DWORD flags, LPVOID mem);
+ static LPVOID __stdcall _RtlReAllocateHeap (HANDLE heap, DWORD flags, LPVOID mem, SIZE_T size);
+
+ // COM IAT replacement functions
+ static HRESULT __stdcall _CoGetMalloc (DWORD context, LPMALLOC *imalloc);
+ static LPVOID __stdcall _CoTaskMemAlloc (ULONG size);
+ static LPVOID __stdcall _CoTaskMemRealloc (LPVOID mem, ULONG size);
+
+////////////////////////////////////////////////////////////////////////////////
+// Private data
+////////////////////////////////////////////////////////////////////////////////
WCHAR m_forcedmodulelist [MAXMODULELISTLENGTH]; // List of modules to be forcefully included in leak detection.
HeapMap *m_heapmap; // Map of all active heaps in the process.
IMalloc *m_imalloc; // Pointer to the system implementation of IMalloc.
@@ -258,6 +287,6 @@ private:
};
// Configuration option default values
-#define VLD_DEFAULT_MAX_DATA_DUMP 0xffffffff
-#define VLD_DEFAULT_MAX_TRACE_FRAMES 0xffffffff
+#define VLD_DEFAULT_MAX_DATA_DUMP 256
+#define VLD_DEFAULT_MAX_TRACE_FRAMES 64
#define VLD_DEFAULT_REPORT_FILE_NAME L".\\memory_leak_report.txt"
diff --git a/development/Win32/vld/tools/cmake/CMakeLists.txt b/development/Win32/vld/tools/cmake/CMakeLists.txt
index 2c95d2de47..0b8b77172a 100644
--- a/development/Win32/vld/tools/cmake/CMakeLists.txt
+++ b/development/Win32/vld/tools/cmake/CMakeLists.txt
@@ -22,6 +22,8 @@
#//
#////////////////////////////////////////////////////////////////////////////////
+cmake_minimum_required(VERSION 2.6.4)
+
project(vld)
include(CheckCXXSourceCompiles)
@@ -44,10 +46,14 @@ if (NOT HAVE_DEBUGGING_TOOLS_FOR_WINDOWS)
message(FATAL_ERROR "")
endif (NOT HAVE_DEBUGGING_TOOLS_FOR_WINDOWS)
+set(vld_path ${CMAKE_CURRENT_SOURCE_DIR}/../..)
+
file(GLOB vld_sources ${vld_path}/src/*.cpp)
file(GLOB vld_headers ${vld_path}/src/*.h)
add_definitions(-DVLD_BUILD -DUNICODE -D_UNICODE)
-add_library(vld SHARED ${vld_sources} ${vld_headers} ${vld_path}/include/vld.h)
+
+add_library(vld SHARED ${vld_sources} ${vld_headers})
+
diff --git a/development/Win32/vld/tools/cmake/vld.cmake b/development/Win32/vld/tools/cmake/vld.cmake
index d1e94bbc8d..bc611bcc4d 100644
--- a/development/Win32/vld/tools/cmake/vld.cmake
+++ b/development/Win32/vld/tools/cmake/vld.cmake
@@ -23,9 +23,5 @@
#////////////////////////////////////////////////////////////////////////////////
# This triggers the useage of vld in all other projects
-include_directories(${vld_path}/include)
-set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /FIvld.h")
-set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /FIvld.h")
-set(vld_dll vld)
-
-add_subdirectory(${vld_path}/tools/cmake ${CMAKE_BINARY_DIR}/vld)
+set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /FI${vld_path}/src/vld.h")
+set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /FI${vld_path}/src/vld.h")
diff --git a/development/Win32/vld/vld.ini b/development/Win32/vld/vld.ini
index bb4c6a9253..701ee09230 100644
--- a/development/Win32/vld/vld.ini
+++ b/development/Win32/vld/vld.ini
@@ -1,5 +1,4 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; $Id: vld.ini,v 1.7 2006/11/18 03:12:35 dmouldin Exp $
;;
;; Visual Leak Detector - Initialization/Configuration File
;; Copyright (c) 2006 Dan Moulding