diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..4a04bf9
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "src/chronos"]
+ path = src/chronos
+ url = https://github.com/datadiode/chronos
diff --git a/README.md b/README.md
index 500abb3..8638d46 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Visual Leak Detector (Support Visual Studio 2019 16.7)
+# Visual Leak Detector (Support Visual Studio 2022 17.12)
## Introduction
@@ -18,6 +18,6 @@ We encourage developers who've added their own features, or fixed bugs they've f
* [Source code](https://github.com/oneiric/vld)
-Copyright © 2005-2021 VLD Team
+Copyright © 2005-2025 VLD Team
[1]: https://github.com/oneiric/vld/blob/master/COPYING.txt
diff --git a/appveyor.yml b/appveyor.yml
index e1621f8..657b8e9 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -11,43 +11,43 @@ environment:
GTEST_REPEAT: 1
matrix:
- - VldStackWalkMethod: safe
- Toolset: v90
- Solution: vld_vs14_wo_mfc.sln
- GTEST_FILTER: -*.Mfc*
- - VldStackWalkMethod: safe
- Toolset: v100
- Solution: vld_vs14_wo_mfc.sln
- GTEST_FILTER: -*.Mfc*
- - VldStackWalkMethod: safe
- Toolset: v110
- Solution: vld_vs14_wo_mfc.sln
- GTEST_FILTER: -*.Mfc*
- - VldStackWalkMethod: safe
- Toolset: v120_xp
- Solution: vld_vs14.sln
+ # - VldStackWalkMethod: safe
+ # Toolset: v90
+ # Solution: vld_vs14_wo_mfc.sln
+ # GTEST_FILTER: -*.Mfc*
+ # - VldStackWalkMethod: safe
+ # Toolset: v100
+ # Solution: vld_vs14_wo_mfc.sln
+ # GTEST_FILTER: -*.Mfc*
+ # - VldStackWalkMethod: safe
+ # Toolset: v110
+ # Solution: vld_vs14_wo_mfc.sln
+ # GTEST_FILTER: -*.Mfc*
+ # - VldStackWalkMethod: safe
+ # Toolset: v120_xp
+ # Solution: vld_vs14.sln
- VldStackWalkMethod: safe
Toolset: v140_xp
- Solution: vld_vs14.sln
-
- - VldStackWalkMethod: fast
- Toolset: v90
- Solution: vld_vs14_wo_mfc.sln
- GTEST_FILTER: -*.Mfc*
- - VldStackWalkMethod: fast
- Toolset: v100
- Solution: vld_vs14_wo_mfc.sln
- GTEST_FILTER: -*.Mfc*
- - VldStackWalkMethod: fast
- Toolset: v110
- Solution: vld_vs14_wo_mfc.sln
- GTEST_FILTER: -*.Mfc*
- - VldStackWalkMethod: fast
- Toolset: v120_xp
- Solution: vld_vs14.sln
+ Solution: vld_vs16.sln
+
+ # - VldStackWalkMethod: fast
+ # Toolset: v90
+ # Solution: vld_vs14_wo_mfc.sln
+ # GTEST_FILTER: -*.Mfc*
+ # - VldStackWalkMethod: fast
+ # Toolset: v100
+ # Solution: vld_vs14_wo_mfc.sln
+ # GTEST_FILTER: -*.Mfc*
+ # - VldStackWalkMethod: fast
+ # Toolset: v110
+ # Solution: vld_vs14_wo_mfc.sln
+ # GTEST_FILTER: -*.Mfc*
+ # - VldStackWalkMethod: fast
+ # Toolset: v120_xp
+ # Solution: vld_vs14.sln
- VldStackWalkMethod: fast
Toolset: v140_xp
- Solution: vld_vs14.sln
+ Solution: vld_vs16.sln
platform:
- Win32
@@ -55,9 +55,9 @@ platform:
configuration:
- Debug_VldRelease
- - Debug_VldRelease_StaticCrt
+ # - Debug_VldRelease_StaticCrt
- Release
- - Release_StaticCrt
+ # - Release_StaticCrt
matrix:
fast_finish: false
@@ -82,7 +82,7 @@ build_script:
return
}
& .\change_toolset.ps1 $env:Toolset
- msbuild /v:m /p:"Configuration=$env:CONFIGURATION" /p:Platform="$env:PLATFORM" "$env:Solution" /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
+ msbuild /v:m /p:"Configuration=$env:CONFIGURATION" /p:Platform="$env:PLATFORM" /p:PlatformToolset=$env:Toolset "$env:Solution" /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
test_script:
- ps: |
diff --git a/lib/cppformat/format.vcxproj b/lib/cppformat/format.vcxproj
index 34873a8..e9bdca0 100644
--- a/lib/cppformat/format.vcxproj
+++ b/lib/cppformat/format.vcxproj
@@ -30,7 +30,7 @@
StaticLibrary
MultiByte
- v142
+ v143
diff --git a/lib/gtest/msvc/gtest.vcxproj b/lib/gtest/msvc/gtest.vcxproj
index afa595a..7a88721 100644
--- a/lib/gtest/msvc/gtest.vcxproj
+++ b/lib/gtest/msvc/gtest.vcxproj
@@ -44,7 +44,7 @@
StaticLibrary
- v142
+ v143
MultiByte
diff --git a/setup/version.h b/setup/version.h
index 7babd1b..0cc3220 100644
--- a/setup/version.h
+++ b/setup/version.h
@@ -1,9 +1,5 @@
-#define VLDVERSION L"2.7.0"
-#define VERSION_NUMBER 2,7,0,0
-#define VERSION_STRING "2.7.0.0"
-#define VERSION_COPYRIGHT "Copyright (C) 2005-2021"
-
-#ifndef __FILE__
-!define VLD_VERSION "2.7.0" // NSIS Script
-#endif
+#define VLDVERSION L"2.8.4"
+#define VERSION_NUMBER 2,8,4,0
+#define VERSION_STRING "2.8.4.0"
+#define VERSION_COPYRIGHT "Copyright (C) 2005-2025"
diff --git a/setup/vld-setup.iss b/setup/vld-setup.iss
index b192276..c481688 100644
--- a/setup/vld-setup.iss
+++ b/setup/vld-setup.iss
@@ -2,9 +2,9 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "Visual Leak Detector"
-#define MyAppVersion "2.7.0"
+#define MyAppVersion "2.8.4"
#define MyAppPublisher "VLD Team"
-#define MyAppURL "http://vld.codeplex.com/"
+#define MyAppURL "https://github.com/oneiric/vld"
#define MyAppRegKey "Software\Visual Leak Detector"
[Setup]
@@ -25,7 +25,7 @@ LicenseFile=license-free.txt
OutputBaseFilename=vld-{#MyAppVersion}-setup
Compression=lzma
SolidCompression=True
-MinVersion=0,6.0
+MinVersion=0,6.1
; Tell Windows Explorer to reload the environment
ChangesEnvironment=yes
AllowNoIcons=yes
@@ -41,16 +41,19 @@ Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "{group}\View Documentation"; Filename: "http://vld.codeplex.com/documentation"
[Files]
+Source: "..\x64\Release\chronos_x64.exe"; DestDir: "{app}\bin\Win64"; Flags: ignoreversion
+Source: "..\Release\chronos_x86.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
+Source: "..\src\chronos\LICENSE"; DestDir: "{app}"; DestName: "LICENSE_chronos.txt"; Flags: ignoreversion
Source: "dbghelp\x64\dbghelp.dll"; DestDir: "{app}\bin\Win64"; Flags: ignoreversion
Source: "dbghelp\x64\Microsoft.DTfW.DHL.manifest"; DestDir: "{app}\bin\Win64"; Flags: ignoreversion
Source: "dbghelp\x86\dbghelp.dll"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "dbghelp\x86\Microsoft.DTfW.DHL.manifest"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
-Source: "..\src\bin\Win32\Release-v142\vld.lib"; DestDir: "{app}\lib\Win32"; Flags: ignoreversion
-Source: "..\src\bin\Win32\Release-v142\vld_x86.dll"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
-Source: "..\src\bin\Win32\Release-v142\vld_x86.pdb"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
-Source: "..\src\bin\x64\Release-v142\vld.lib"; DestDir: "{app}\lib\Win64"; Flags: ignoreversion
-Source: "..\src\bin\x64\Release-v142\vld_x64.dll"; DestDir: "{app}\bin\Win64"; Flags: ignoreversion
-Source: "..\src\bin\x64\Release-v142\vld_x64.pdb"; DestDir: "{app}\bin\Win64"; Flags: ignoreversion
+Source: "..\src\bin\Win32\Release-v143\vld.lib"; DestDir: "{app}\lib\Win32"; Flags: ignoreversion
+Source: "..\src\bin\Win32\Release-v143\vld_x86.dll"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
+Source: "..\src\bin\Win32\Release-v143\vld_x86.pdb"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
+Source: "..\src\bin\x64\Release-v143\vld.lib"; DestDir: "{app}\lib\Win64"; Flags: ignoreversion
+Source: "..\src\bin\x64\Release-v143\vld_x64.dll"; DestDir: "{app}\bin\Win64"; Flags: ignoreversion
+Source: "..\src\bin\x64\Release-v143\vld_x64.pdb"; DestDir: "{app}\bin\Win64"; Flags: ignoreversion
Source: "..\src\vld.h"; DestDir: "{app}\include"; Flags: ignoreversion
Source: "..\src\vld_def.h"; DestDir: "{app}\include"; Flags: ignoreversion
Source: "..\vld.ini"; DestDir: "{app}"; Flags: ignoreversion
@@ -61,7 +64,7 @@ Source: "..\COPYING.txt"; DestDir: "{app}"; Flags: ignoreversion
[Tasks]
Name: "modifypath"; Description: "Add VLD directory to your environmental path"
Name: "modifyVS2008Props"; Description: "Add VLD directory to VS 2008"
-Name: "modifyVS2010Props"; Description: "Add VLD directory to VS 2010 - VS 2019"
+Name: "modifyVS2010Props"; Description: "Add VLD directory to VS 2010 - VS 2022"
[ThirdParty]
UseRelativePaths=True
@@ -318,12 +321,28 @@ var
StaticLibraryDirectoriesNode: Variant;
AdditionalStaticLibraryDirectories: string;
begin
- if not FileExists(filename) then
- Exit;
XMLDocument := CreateOleObject('Msxml2.DOMDocument.3.0');
try
XMLDocument.async := False;
- XMLDocument.load(filename);
+ XMLDocument.preserveWhiteSpace := True;
+ if FileExists(filename) then
+ XMLDocument.load(filename)
+ else
+ XMLDocument.loadXML(
+ ''#13#10
+ ''#13#10
+ ' '#13#10
+ ' '#13#10
+ ' '#13#10
+ ' '#13#10
+ ' '#13#10
+ ' '#13#10
+ ' '#13#10
+ ' '#13#10
+ ' '#13#10
+ ' '#13#10
+ ' '#13#10
+ ''#13#10);
if (XMLDocument.parseError.errorCode = 0) then
begin
XMLDocument.setProperty('SelectionLanguage', 'XPath');
@@ -426,7 +445,7 @@ var
Path: string;
begin
Path := GetEnv('LOCALAPPDATA')+'\Microsoft\MSBuild\v4.0\';
- if DirExists(Path) then
+ if ForceDirectories(Path) then
begin
ModifyProps(Path + 'Microsoft.Cpp.Win32.user.props', 'Win32');
ModifyProps(Path + 'Microsoft.Cpp.x64.user.props', 'Win64');
diff --git a/src/chronos b/src/chronos
new file mode 160000
index 0000000..c22e8ec
--- /dev/null
+++ b/src/chronos
@@ -0,0 +1 @@
+Subproject commit c22e8ec2fc9731ebdf2146511972c9a038c4f53d
diff --git a/src/dllspatches.cpp b/src/dllspatches.cpp
index a997995..d1160ce 100644
--- a/src/dllspatches.cpp
+++ b/src/dllspatches.cpp
@@ -769,6 +769,16 @@ patchentry_t VisualLeakDetector::m_ntdllPatch [] = {
NULL, NULL, NULL
};
+patchentry_t VisualLeakDetector::m_winsockPatch [] = {
+ "socket", NULL, _socket,
+ "accept", NULL, _accept,
+ "connect", NULL, _connect,
+ "closesocket", NULL, _closesocket,
+ "WSACreateEvent", NULL, _WSACreateEvent,
+ "WSACloseEvent", NULL, _WSACloseEvent,
+ NULL, NULL, NULL
+};
+
patchentry_t VisualLeakDetector::m_ole32Patch [] = {
"CoGetMalloc", NULL, _CoGetMalloc,
"CoTaskMemAlloc", NULL, _CoTaskMemAlloc,
@@ -776,6 +786,13 @@ patchentry_t VisualLeakDetector::m_ole32Patch [] = {
NULL, NULL, NULL
};
+SSL_CTX_new_t VisualLeakDetector::m_SSL_CTX_new = NULL;
+
+patchentry_t VisualLeakDetector::m_opensslPatch [] = {
+ "SSL_CTX_new", (LPVOID*)&m_SSL_CTX_new, _SSL_CTX_new,
+ NULL, NULL, NULL
+};
+
moduleentry_t VisualLeakDetector::m_patchTable [] = {
// Win32 heap APIs.
"kernel32.dll", FALSE, 0x0, m_kernelbasePatch, // we patch this record on Win7 and higher
@@ -842,6 +859,12 @@ moduleentry_t VisualLeakDetector::m_patchTable [] = {
// NT APIs.
"ntdll.dll", FALSE, 0x0, m_ntdllPatch,
+ // Winsock APIs.
+ "ws2_32.dll", FALSE, 0x0, m_winsockPatch,
+
+ // OpenSSL APIs.
+ "libssl-3-x64.dll", FALSE, 0x0, m_opensslPatch,
+
// COM heap APIs.
"ole32.dll", FALSE, 0x0, m_ole32Patch
};
diff --git a/src/stdafx.h b/src/stdafx.h
index a968c06..c0055fc 100644
--- a/src/stdafx.h
+++ b/src/stdafx.h
@@ -3,7 +3,8 @@
#include
#include
#include
-#include
+#include
+#include
#if _WIN32_WINNT < 0x0600 // Windows XP or earlier, no GetProcessIdOfThread()
#include
#endif
diff --git a/src/tests/basics/Allocs.cpp b/src/tests/basics/Allocs.cpp
index c5f7f2c..2f81697 100644
--- a/src/tests/basics/Allocs.cpp
+++ b/src/tests/basics/Allocs.cpp
@@ -31,12 +31,8 @@
#define CRTDLLNAME _T("msvcr110d.dll")
#elif _MSC_VER == 1800 // VS 2013
#define CRTDLLNAME _T("msvcr120d.dll")
-#elif _MSC_VER == 1900 // VS 2015
+#elif _MSC_VER >= 1900 // VS 2015+
#define CRTDLLNAME _T("ucrtbased.dll")
-#elif _MSC_VER == 1924 // VS 2019 16.4
-#define CRTDLLNAME _T("ucrtbased.dll")
-#elif _MSC_VER == 1927 // VS 2019 16.7
-#define CRTDLLNAME _T("ucrtbase.dll")
#else
#error Unsupported compiler
#endif
@@ -59,11 +55,7 @@
#define CRTDLLNAME _T("msvcr110.dll")
#elif _MSC_VER == 1800 // VS 2013
#define CRTDLLNAME _T("msvcr120.dll")
-#elif _MSC_VER == 1900 // VS 2015
-#define CRTDLLNAME _T("ucrtbase.dll")
-#elif _MSC_VER == 1924 // VS 2019 16.4
-#define CRTDLLNAME _T("ucrtbase.dll")
-#elif _MSC_VER == 1927 // VS 2019 16.7
+#elif _MSC_VER >= 1900 // VS 2015+
#define CRTDLLNAME _T("ucrtbase.dll")
#else
#error Unsupported compiler
diff --git a/src/tests/basics/basics.vcxproj b/src/tests/basics/basics.vcxproj
index e04dcae..82b6080 100644
--- a/src/tests/basics/basics.vcxproj
+++ b/src/tests/basics/basics.vcxproj
@@ -61,7 +61,7 @@
Application
Unicode
- v142
+ v143
true
diff --git a/src/tests/corruption/corruption.vcxproj b/src/tests/corruption/corruption.vcxproj
index 13289ad..3f4b14d 100644
--- a/src/tests/corruption/corruption.vcxproj
+++ b/src/tests/corruption/corruption.vcxproj
@@ -61,7 +61,7 @@
Application
Unicode
- v142
+ v143
true
diff --git a/src/tests/dynamic_app/dynamic_app.vcxproj b/src/tests/dynamic_app/dynamic_app.vcxproj
index 412621b..e1a0144 100644
--- a/src/tests/dynamic_app/dynamic_app.vcxproj
+++ b/src/tests/dynamic_app/dynamic_app.vcxproj
@@ -61,7 +61,7 @@
Application
Unicode
- v142
+ v143
true
diff --git a/src/tests/dynamic_dll/dynamic.vcxproj b/src/tests/dynamic_dll/dynamic.vcxproj
index 51b1d51..06faf29 100644
--- a/src/tests/dynamic_dll/dynamic.vcxproj
+++ b/src/tests/dynamic_dll/dynamic.vcxproj
@@ -61,7 +61,7 @@
DynamicLibrary
Unicode
- v142
+ v143
true
diff --git a/src/tests/mfc/vldmfc.vcxproj b/src/tests/mfc/vldmfc.vcxproj
index c063cb1..0cf9d96 100644
--- a/src/tests/mfc/vldmfc.vcxproj
+++ b/src/tests/mfc/vldmfc.vcxproj
@@ -45,7 +45,7 @@
Application
Unicode
- v142
+ v143
Dynamic
diff --git a/src/tests/mfc_dll/mfc.vcxproj b/src/tests/mfc_dll/mfc.vcxproj
index bfccd4f..1fbb869 100644
--- a/src/tests/mfc_dll/mfc.vcxproj
+++ b/src/tests/mfc_dll/mfc.vcxproj
@@ -61,7 +61,7 @@
DynamicLibrary
Unicode
- v142
+ v143
true
diff --git a/src/tests/suite/testsuite.cpp b/src/tests/suite/testsuite.cpp
index d87d975..452b56b 100644
--- a/src/tests/suite/testsuite.cpp
+++ b/src/tests/suite/testsuite.cpp
@@ -69,12 +69,8 @@ enum action_e {
#define CRTDLLNAME _T("msvcr110d.dll")
#elif _MSC_VER == 1800 // VS 2013
#define CRTDLLNAME _T("msvcr120d.dll")
-#elif _MSC_VER == 1900 // VS 2015
+#elif _MSC_VER >= 1900 // VS 2015+
#define CRTDLLNAME _T("ucrtbased.dll")
-#elif _MSC_VER == 1924 // VS 2019
-#define CRTDLLNAME _T("ucrtbased.dll")
-#elif _MSC_VER == 1927 // VS 2019 16.7
-#define CRTDLLNAME _T("ucrtbase.dll")
#else
#error Unsupported compiler
#endif
@@ -97,11 +93,7 @@ enum action_e {
#define CRTDLLNAME _T("msvcr110.dll")
#elif _MSC_VER == 1800 // VS 2013
#define CRTDLLNAME _T("msvcr120.dll")
-#elif _MSC_VER == 1900 // VS 2015
-#define CRTDLLNAME _T("ucrtbase.dll")
-#elif _MSC_VER == 1924 // VS 2019 16.4
-#define CRTDLLNAME _T("ucrtbase.dll")
-#elif _MSC_VER == 1927 // VS 2019 16.7
+#elif _MSC_VER >= 1900 // VS 2015+
#define CRTDLLNAME _T("ucrtbase.dll")
#else
#error Unsupported compiler
diff --git a/src/tests/suite/testsuite.vcxproj b/src/tests/suite/testsuite.vcxproj
index 20d1ae6..8e77d65 100644
--- a/src/tests/suite/testsuite.vcxproj
+++ b/src/tests/suite/testsuite.vcxproj
@@ -60,7 +60,7 @@
Application
NotSet
- v142
+ v143
diff --git a/src/tests/vld_ComTest/ComTest_vs14.vcxproj b/src/tests/vld_ComTest/ComTest_vs14.vcxproj
index 318f01a..88bf2a4 100644
--- a/src/tests/vld_ComTest/ComTest_vs14.vcxproj
+++ b/src/tests/vld_ComTest/ComTest_vs14.vcxproj
@@ -61,7 +61,7 @@
DynamicLibrary
Unicode
- v142
+ v143
true
diff --git a/src/tests/vld_dll1/vld_dll1_vs14.vcxproj b/src/tests/vld_dll1/vld_dll1_vs14.vcxproj
index f57ece7..a3af339 100644
--- a/src/tests/vld_dll1/vld_dll1_vs14.vcxproj
+++ b/src/tests/vld_dll1/vld_dll1_vs14.vcxproj
@@ -60,7 +60,7 @@
DynamicLibrary
- v142
+ v143
Unicode
diff --git a/src/tests/vld_dll2/vld_dll2_vs14.vcxproj b/src/tests/vld_dll2/vld_dll2_vs14.vcxproj
index 2110a7a..841df15 100644
--- a/src/tests/vld_dll2/vld_dll2_vs14.vcxproj
+++ b/src/tests/vld_dll2/vld_dll2_vs14.vcxproj
@@ -60,7 +60,7 @@
DynamicLibrary
- v142
+ v143
Unicode
diff --git a/src/tests/vld_main/vld_main_vs14.vcxproj b/src/tests/vld_main/vld_main_vs14.vcxproj
index 3f4b8aa..a1361c3 100644
--- a/src/tests/vld_main/vld_main_vs14.vcxproj
+++ b/src/tests/vld_main/vld_main_vs14.vcxproj
@@ -60,7 +60,7 @@
Application
- v142
+ v143
Unicode
diff --git a/src/tests/vld_main_test/vld_main_test_vs14.vcxproj b/src/tests/vld_main_test/vld_main_test_vs14.vcxproj
index 6bd4efc..f8ab85c 100644
--- a/src/tests/vld_main_test/vld_main_test_vs14.vcxproj
+++ b/src/tests/vld_main_test/vld_main_test_vs14.vcxproj
@@ -60,7 +60,7 @@
Application
- v142
+ v143
Unicode
diff --git a/src/tests/vld_unload/vld_unload_vs14.vcxproj b/src/tests/vld_unload/vld_unload_vs14.vcxproj
index 2078498..a29e886 100644
--- a/src/tests/vld_unload/vld_unload_vs14.vcxproj
+++ b/src/tests/vld_unload/vld_unload_vs14.vcxproj
@@ -60,7 +60,7 @@
Application
- v142
+ v143
Unicode
diff --git a/src/vld.cpp b/src/vld.cpp
index a37d9ce..20733e9 100644
--- a/src/vld.cpp
+++ b/src/vld.cpp
@@ -349,6 +349,7 @@ VisualLeakDetector::VisualLeakDetector ()
m_options = 0x0;
m_reportFile = NULL;
wcsncpy_s(m_reportFilePath, MAX_PATH, VLD_DEFAULT_REPORT_FILE_NAME, _TRUNCATE);
+ wcsncpy_s(m_sslkeyFilePath, MAX_PATH, VLD_DEFAULT_SSLKEY_FILE_NAME, _TRUNCATE);
m_status = 0x0;
HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
@@ -866,19 +867,11 @@ VOID VisualLeakDetector::attachToLoadedModules (ModuleSet *newmodules)
{
// This module does not import VLD. This means that none of the module's
// sources #included vld.h.
- if ((m_options & VLD_OPT_MODULE_LIST_INCLUDE) != 0)
+ const BOOL match = PathMatchSpecW(modulename, m_forcedModuleList);
+ if ((m_options & VLD_OPT_MODULE_LIST_INCLUDE) != (match ? VLD_OPT_MODULE_LIST_INCLUDE : 0))
{
- if (wcsstr(m_forcedModuleList, modulename) == NULL) {
- // Exclude this module from leak detection.
- moduleFlags |= VLD_MODULE_EXCLUDED;
- }
- }
- else
- {
- if (wcsstr(m_forcedModuleList, modulename) != NULL) {
- // Exclude this module from leak detection.
- moduleFlags |= VLD_MODULE_EXCLUDED;
- }
+ // Exclude this module from leak detection.
+ moduleFlags |= VLD_MODULE_EXCLUDED;
}
}
}
@@ -1169,6 +1162,14 @@ VOID VisualLeakDetector::configure ()
WCHAR* path = _wfullpath(m_reportFilePath, filename, MAX_PATH);
assert(path);
+ // Read the SSL key file location.
+ LoadStringOption(L"SSLKeyFile", filename, MAX_PATH, inipath);
+ if (filename[0] == '\0') {
+ wcsncpy_s(filename, MAX_PATH, VLD_DEFAULT_SSLKEY_FILE_NAME, _TRUNCATE);
+ }
+ path = _wfullpath(m_sslkeyFilePath, filename, MAX_PATH);
+ assert(path);
+
LoadStringOption(L"ReportTo", buffer, buffersize, inipath);
if (_wcsicmp(buffer, L"both") == 0) {
m_options |= (VLD_OPT_REPORT_TO_DEBUGGER | VLD_OPT_REPORT_TO_FILE);
@@ -1358,6 +1359,7 @@ VOID VisualLeakDetector::mapBlock (HANDLE heap, LPCVOID mem, SIZE_T size, bool d
blockinfo->reported = false;
blockinfo->debugCrtAlloc = debugcrtalloc;
blockinfo->ucrt = ucrt;
+ blockinfo->resource = IS_INTRESOURCE(heap);
if (SIZE_MAX - m_totalAlloc > size)
m_totalAlloc += size;
@@ -1680,6 +1682,9 @@ VOID VisualLeakDetector::reportConfig ()
bool VisualLeakDetector::isDebugCrtAlloc( LPCVOID block, blockinfo_t* info )
{
+ if (info->resource)
+ return false;
+
// Autodetection allocations from statically linked CRT
if (!info->debugCrtAlloc) {
crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block;
@@ -1916,7 +1921,7 @@ SIZE_T VisualLeakDetector::reportLeaks (heapinfo_t* heapinfo, bool &firstLeak, S
info->callStack->dump(m_options & VLD_OPT_TRACE_INTERNAL_FRAMES);
// Dump the data in the user data section of the memory block.
- if (m_maxDataDump != 0) {
+ if (m_maxDataDump != 0 && size != 0) {
Report(L" Data:\n");
if (m_options & VLD_OPT_UNICODE_REPORT) {
DumpMemoryW(address, (m_maxDataDump < size) ? m_maxDataDump : size);
@@ -2099,6 +2104,14 @@ BOOL VisualLeakDetector::detachFromModule (PCWSTR /*modulepath*/, DWORD64 module
return TRUE;
}
+void VisualLeakDetector::SSL_CTX_keylog_cb_func(const void* ssl_ctx, const char* line)
+{
+ if (FILE *sslkeyFile = _wfsopen(g_vld.m_sslkeyFilePath, L"a", _SH_DENYNO)) {
+ fprintf(sslkeyFile, "%s\n", line);
+ fclose(sslkeyFile);
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
//
// Win32 IAT Replacement Functions
diff --git a/src/vld.vcxproj b/src/vld.vcxproj
index ae0c939..1e375f1 100644
--- a/src/vld.vcxproj
+++ b/src/vld.vcxproj
@@ -32,7 +32,7 @@
- v142
+ v143
@@ -88,7 +88,7 @@
4201;4229;4091;4302;4311;4312;4127
- psapi.lib;%(AdditionalDependencies)
+ shlwapi.lib;ws2_32.lib;%(AdditionalDependencies)
Windows
@@ -107,7 +107,7 @@
false
- psapi.lib;%(AdditionalDependencies)
+ shlwapi.lib;ws2_32.lib;%(AdditionalDependencies)
Windows
@@ -135,6 +135,7 @@
true
true
Windows
+ shlwapi.lib;ws2_32.lib;%(AdditionalDependencies)
vld.dll.dependency.x86.manifest
@@ -160,6 +161,7 @@
true
true
Windows
+ shlwapi.lib;ws2_32.lib;%(AdditionalDependencies)
vld.dll.dependency.x64.manifest
diff --git a/src/vld_hooks.cpp b/src/vld_hooks.cpp
index 314e99c..436f48a 100644
--- a/src/vld_hooks.cpp
+++ b/src/vld_hooks.cpp
@@ -42,6 +42,11 @@ extern HANDLE g_currentProcess;
extern CriticalSection g_heapMapLock;
extern DbgHelp g_DbgHelp;
+// Heap handles are pointers, hence disjunct from numbers below 65536, which
+// hence can serve as pseudo heap handles for tracking non-memory resources.
+#define VLD_SOCKET_RESOURCE MAKEINTRESOURCE(1)
+#define VLD_WSAEVENT_RESOURCE MAKEINTRESOURCE(2)
+
////////////////////////////////////////////////////////////////////////////////
//
// Debug CRT and MFC IAT Replacement Functions
@@ -298,6 +303,198 @@ LPVOID VisualLeakDetector::_HeapReAlloc (HANDLE heap, DWORD flags, LPVOID mem, S
return newmem;
}
+////////////////////////////////////////////////////////////////////////////////
+//
+// Winsock IAT Replacement Functions
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// _socket - Calls to socket are patched through to this function.
+// This function invokes the real socket and then calls VLD's allocation
+// tracking function with a pseudo heap handle of value VLD_SOCKET_RESOURCE.
+//
+// Return Value:
+//
+// Returns the return value from socket.
+//
+SOCKET VisualLeakDetector::_socket (int af, int type, int protocol)
+{
+ PRINT_HOOKED_FUNCTION2();
+ // Allocate the resource.
+ SOCKET s = socket(af, type, protocol);
+
+ if ((s == INVALID_SOCKET) || !g_vld.enabled())
+ return s;
+
+ if (!g_DbgHelp.IsLockedByCurrentThread()) // skip dbghelp.dll calls
+ {
+ CAPTURE_CONTEXT();
+ CaptureContext cc(socket, context_);
+ cc.Set(VLD_SOCKET_RESOURCE, reinterpret_cast(s), NULL, 0);
+ }
+
+ return s;
+}
+
+// _accept - Calls to accept are patched through to this function.
+// This function invokes the real accept and then calls VLD's allocation
+// tracking function with a pseudo heap handle of value VLD_SOCKET_RESOURCE.
+//
+// Return Value:
+//
+// Returns the return value from accept.
+//
+SOCKET VisualLeakDetector::_accept (SOCKET s, struct sockaddr *addr, int *addrlen)
+{
+ PRINT_HOOKED_FUNCTION2();
+ // Allocate the resource.
+ s = accept(s, addr, addrlen);
+
+ if ((s == INVALID_SOCKET) || !g_vld.enabled())
+ return s;
+
+ if (!g_DbgHelp.IsLockedByCurrentThread()) // skip dbghelp.dll calls
+ {
+ CAPTURE_CONTEXT();
+ CaptureContext cc(accept, context_);
+ cc.Set(VLD_SOCKET_RESOURCE, reinterpret_cast(s), NULL, 0);
+ }
+
+ return s;
+}
+
+// _connect - Calls to connect are patched through to this function.
+// This function invokes the real connect and then calls VLD's allocation
+// tracking function with a pseudo heap handle of value VLD_SOCKET_RESOURCE.
+//
+// Return Value:
+//
+// Returns the return value from connect.
+//
+SOCKET VisualLeakDetector::_connect (SOCKET s, const struct sockaddr *name, int namelen)
+{
+ PRINT_HOOKED_FUNCTION2();
+ // Allocate the resource.
+ s = connect(s, name, namelen);
+
+ if ((s == INVALID_SOCKET) || !g_vld.enabled())
+ return s;
+
+ if (!g_DbgHelp.IsLockedByCurrentThread()) // skip dbghelp.dll calls
+ {
+ CAPTURE_CONTEXT();
+ CaptureContext cc(connect, context_);
+ cc.Set(VLD_SOCKET_RESOURCE, reinterpret_cast(s), NULL, 0);
+ }
+
+ return s;
+}
+
+// _closesocket - Calls to closesocket are patched through to this function.
+// This function calls VLD's free tracking function with a pseudo heap handle
+// of value VLD_SOCKET_RESOURCE and then invokes the real closesocket.
+//
+// Return Value:
+//
+// Returns the value returned by closesocket.
+//
+int VisualLeakDetector::_closesocket (SOCKET s)
+{
+ PRINT_HOOKED_FUNCTION2();
+
+ if (!g_DbgHelp.IsLockedByCurrentThread()) // skip dbghelp.dll calls
+ {
+ // Record the current frame pointer.
+ CAPTURE_CONTEXT();
+ context_.func = reinterpret_cast(closesocket);
+
+ // Unmap the resource from the specified pseudo heap.
+ g_vld.unmapBlock(VLD_SOCKET_RESOURCE, reinterpret_cast(s), context_);
+ }
+
+ return closesocket(s);
+}
+
+// _WSACreateEvent - Calls to WSACreateEvent are patched through to this
+// function. This function invokes the real WSACreateEvent and then calls
+// VLD's allocation tracking function with a pseudo heap handle of value
+// VLD_HANDLE_RESOURCE.
+//
+// Return Value:
+//
+// Returns the return value from WSACreateEvent.
+//
+WSAEVENT VisualLeakDetector::_WSACreateEvent ()
+{
+ PRINT_HOOKED_FUNCTION2();
+ // Allocate the resource.
+ WSAEVENT hEvent = WSACreateEvent();
+
+ if ((hEvent == WSA_INVALID_EVENT) || !g_vld.enabled())
+ return hEvent;
+
+ if (!g_DbgHelp.IsLockedByCurrentThread()) // skip dbghelp.dll calls
+ {
+ CAPTURE_CONTEXT();
+ CaptureContext cc(WSACreateEvent, context_);
+ cc.Set(VLD_WSAEVENT_RESOURCE, hEvent, NULL, 0);
+ }
+
+ return hEvent;
+}
+
+// _WSACloseEvent - Calls to WSACloseEvent are patched through to this function.
+// This function calls VLD's free tracking function with a pseudo heap handle
+// of value VLD_HANDLE_RESOURCE and then invokes the real WSACloseEvent.
+//
+// Return Value:
+//
+// Returns the value returned by WSACloseEvent.
+//
+BOOL VisualLeakDetector::_WSACloseEvent (WSAEVENT hEvent)
+{
+ PRINT_HOOKED_FUNCTION2();
+
+ if (!g_DbgHelp.IsLockedByCurrentThread()) // skip dbghelp.dll calls
+ {
+ // Record the current frame pointer.
+ CAPTURE_CONTEXT();
+ context_.func = reinterpret_cast(WSACloseEvent);
+
+ // Unmap the resource from the specified pseudo heap.
+ g_vld.unmapBlock(VLD_WSAEVENT_RESOURCE, hEvent, context_);
+ }
+
+ return WSACloseEvent(hEvent);
+}
+
+// _SSL_CTX_new - Calls to SSL_CTX_new are patched through to this function.
+// This function calls the real SSL_CTX_new and then sets a keylog callback.
+//
+// Return Value:
+//
+// Returns the value returned by SSL_CTX_new.
+//
+void* VisualLeakDetector::_SSL_CTX_new (void* ctx)
+{
+ PRINT_HOOKED_FUNCTION2();
+
+ static SSL_CTX_set_keylog_callback_t pSSL_CTX_set_keylog_callback = NULL;
+
+ if (pSSL_CTX_set_keylog_callback == NULL) {
+ // This is the first call to this function. Link to the real SSL_CTX_set_keylog_callback
+ HMODULE libssl = GetModuleHandleW(L"libssl-3-x64.dll");
+ pSSL_CTX_set_keylog_callback = (SSL_CTX_set_keylog_callback_t)g_vld._RGetProcAddress(libssl, "SSL_CTX_set_keylog_callback");
+ }
+
+ LPVOID ssl_ctx = m_SSL_CTX_new(ctx);
+ if (ssl_ctx)
+ {
+ pSSL_CTX_set_keylog_callback(ssl_ctx, SSL_CTX_keylog_cb_func);
+ }
+ return ssl_ctx;
+}
+
////////////////////////////////////////////////////////////////////////////////
//
// COM IAT Replacement Functions
diff --git a/src/vldint.h b/src/vldint.h
index 05cec20..07e4ef9 100644
--- a/src/vldint.h
+++ b/src/vldint.h
@@ -68,6 +68,10 @@ typedef BOOL(__stdcall *HeapFree_t) (HANDLE, DWORD, LPVOID);
typedef FARPROC(__stdcall *GetProcAddress_t) (HMODULE, LPCSTR);
typedef FARPROC(__stdcall *GetProcAddressForCaller_t) (HMODULE, LPCSTR, LPVOID);
+typedef void (__cdecl *SSL_CTX_keylog_cb_func_t)(const void *, const char *);
+typedef void* (__cdecl *SSL_CTX_new_t) (void*);
+typedef void (__cdecl *SSL_CTX_set_keylog_callback_t) (void*, SSL_CTX_keylog_cb_func_t);
+
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);
@@ -111,6 +115,7 @@ struct blockinfo_t {
bool reported;
bool debugCrtAlloc;
bool ucrt;
+ bool resource;
};
// BlockMaps map memory blocks (via their addresses) to blockinfo_t structures.
@@ -321,6 +326,7 @@ class VisualLeakDetector : public IMalloc
// 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);
+ static void __cdecl SSL_CTX_keylog_cb_func(const void* ssl_ctx, const char* line);
// Utils
static bool isModuleExcluded (UINT_PTR returnaddress);
@@ -353,6 +359,17 @@ class VisualLeakDetector : public IMalloc
static BYTE __stdcall _RtlFreeHeap (HANDLE heap, DWORD flags, LPVOID mem);
static LPVOID __stdcall _RtlReAllocateHeap (HANDLE heap, DWORD flags, LPVOID mem, SIZE_T size);
+ // Winsock IAT replacement functions
+ static SOCKET __stdcall _socket (int af, int type, int protocol);
+ static SOCKET __stdcall _accept (SOCKET s, struct sockaddr *addr, int *addrlen);
+ static SOCKET __stdcall _connect (SOCKET s, const struct sockaddr *name, int namelen);
+ static int __stdcall _closesocket (SOCKET s);
+ static WSAEVENT __stdcall _WSACreateEvent ();
+ static BOOL __stdcall _WSACloseEvent (WSAEVENT hEvent);
+
+ // OpenSSL replacement functions
+ static void* __cdecl _SSL_CTX_new (void*);
+
// COM IAT replacement functions
static HRESULT __stdcall _CoGetMalloc (DWORD context, LPMALLOC *imalloc);
static LPVOID __stdcall _CoTaskMemAlloc (SIZE_T size);
@@ -379,10 +396,13 @@ class VisualLeakDetector : public IMalloc
static patchentry_t m_kernelbasePatch [];
static patchentry_t m_kernel32Patch [];
static patchentry_t m_ntdllPatch [];
+ static patchentry_t m_winsockPatch [];
+ static patchentry_t m_opensslPatch [];
static patchentry_t m_ole32Patch [];
- static moduleentry_t m_patchTable [58]; // Table of imports patched for attaching VLD to other modules.
+ static moduleentry_t m_patchTable [60]; // Table of imports patched for attaching VLD to other modules.
FILE *m_reportFile; // File where the memory leak report may be sent to.
WCHAR m_reportFilePath [MAX_PATH]; // Full path and name of file to send memory leak report to.
+ WCHAR m_sslkeyFilePath [MAX_PATH]; // Full path and name of sslkeylogfile.
const char *m_selfTestFile; // Filename where the memory leak self-test block is leaked.
int m_selfTestLine; // Line number where the memory leak self-test block is leaked.
UINT32 m_status; // Status flags:
@@ -402,6 +422,7 @@ class VisualLeakDetector : public IMalloc
static GetProcessHeap_t m_GetProcessHeap;
static HeapCreate_t m_HeapCreate;
static HeapFree_t m_HeapFree;
+ static SSL_CTX_new_t m_SSL_CTX_new;
};
@@ -409,3 +430,4 @@ class VisualLeakDetector : public IMalloc
#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"
+#define VLD_DEFAULT_SSLKEY_FILE_NAME L".\\sslkeys.log"
diff --git a/vld_vs16.sln b/vld_vs16.sln
index 0caa557..7216850 100644
--- a/vld_vs16.sln
+++ b/vld_vs16.sln
@@ -71,6 +71,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld_main_test", "src\tests\
{8C732490-DC1A-40C0-923F-1555B9141B80} = {8C732490-DC1A-40C0-923F-1555B9141B80}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "chronos", "src\chronos\chronos.vcxproj", "{3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_StaticCrt|Win32 = Debug_StaticCrt|Win32
@@ -472,6 +474,30 @@ Global
{BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release|Win32.Build.0 = Release|Win32
{BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release|x64.ActiveCfg = Release|x64
{BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release|x64.Build.0 = Release|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_StaticCrt|Win32.ActiveCfg = Debug|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_StaticCrt|Win32.Build.0 = Debug|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_StaticCrt|x64.ActiveCfg = Debug|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_StaticCrt|x64.Build.0 = Debug|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Release|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Release|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Release|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_VldRelease_StaticCrt|x64.Build.0 = Release|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_VldRelease|Win32.ActiveCfg = Release|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_VldRelease|Win32.Build.0 = Release|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_VldRelease|x64.ActiveCfg = Release|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug_VldRelease|x64.Build.0 = Release|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug|Win32.Build.0 = Debug|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug|x64.ActiveCfg = Debug|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Debug|x64.Build.0 = Debug|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Release_StaticCrt|Win32.ActiveCfg = Release|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Release_StaticCrt|Win32.Build.0 = Release|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Release_StaticCrt|x64.ActiveCfg = Release|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Release_StaticCrt|x64.Build.0 = Release|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Release|Win32.ActiveCfg = Release|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Release|Win32.Build.0 = Release|Win32
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Release|x64.ActiveCfg = Release|x64
+ {3DB94AD0-4960-4D71-B10A-F3A56AEA4C5D}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE