From d18634a5181e03ad1822a16ed0dd12cb4f3f2d59 Mon Sep 17 00:00:00 2001 From: Arkady Shapkin Date: Mon, 7 Apr 2014 00:20:59 +0400 Subject: [PATCH] Internal memory leak fixed --- vld.cpp | 34 ++++++++++------------------------ vld.vcxproj | 4 ++++ vldallocator.h | 13 +++++++++---- vldint.h | 24 +++++++++++++----------- 4 files changed, 36 insertions(+), 39 deletions(-) diff --git a/vld.cpp b/vld.cpp index 1d7b7e12..ed59b9f3 100644 --- a/vld.cpp +++ b/vld.cpp @@ -34,7 +34,6 @@ #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 "vldallocator.h"// Provides internal allocator. #include "vldint.h" // Provides access to the Visual Leak Detector internals. #define BLOCK_MAP_RESERVE 64 // This should strike a balance between memory use and a desire to minimize heap hits. @@ -421,11 +420,6 @@ VisualLeakDetector::~VisualLeakDetector () } delete m_heapMap; - // Free internally allocated resources used by the loaded module set. - for (ModuleSet::Iterator moduleit = m_loadedModules->begin(); moduleit != m_loadedModules->end(); ++moduleit) { - delete [] (*moduleit).name; - delete [] (*moduleit).path; - } delete m_loadedModules; // Free internally allocated resources used for thread local storage. @@ -550,9 +544,9 @@ VOID VisualLeakDetector::attachToLoadedModules (ModuleSet *newmodules) continue; DWORD64 modulebase = (DWORD64) (*newit).addrLow; - LPCWSTR modulename = (*newit).name; - LPCWSTR modulepath = (*newit).path; - DWORD modulesize = (DWORD)((*newit).addrHigh - (*newit).addrLow) + 1; + LPCWSTR modulename = (*newit).name.c_str(); + LPCWSTR modulepath = (*newit).path.c_str(); + DWORD modulesize = (DWORD)((*newit).addrHigh - (*newit).addrLow) + 1; g_symbolLock.Enter(); if ((state == 3) && (moduleFlags & VLD_MODULE_SYMBOLSLOADED)) { @@ -1690,28 +1684,24 @@ blockinfo_t* VisualLeakDetector::findAllocedBlock(LPCVOID mem, __out HANDLE& hea // BOOL VisualLeakDetector::addLoadedModule (PCWSTR modulepath, DWORD64 modulebase, ULONG modulesize, PVOID context) { - size_t length = wcslen(modulepath) + 1; - LPWSTR modulepathw = new WCHAR [length]; - wcsncpy_s(modulepathw, length, modulepath, _TRUNCATE); + vldstring modulepathw(modulepath); // Extract just the filename and extension from the module path. WCHAR filename [_MAX_FNAME]; WCHAR extension [_MAX_EXT]; - _wsplitpath_s(modulepathw, NULL, 0, NULL, 0, filename, _MAX_FNAME, extension, _MAX_EXT); + _wsplitpath_s(modulepathw.c_str(), NULL, 0, NULL, 0, filename, _MAX_FNAME, extension, _MAX_EXT); - length = wcslen(filename) + wcslen(extension) + 1; - LPWSTR modulename = new WCHAR [length]; - wcsncpy_s(modulename, length, filename, _TRUNCATE); - wcsncat_s(modulename, length, extension, _TRUNCATE); - _wcslwr_s(modulename, length); + vldstring modulename(filename); + modulename.append(extension); + _wcslwr_s(&modulename[0], modulename.size() + 1); - if (_wcsicmp(modulename, TEXT(VLDDLL)) == 0) { + if (_wcsicmp(modulename.c_str(), TEXT(VLDDLL)) == 0) { // Record Visual Leak Detector's own base address. g_vld.m_vldBase = (HMODULE)modulebase; } else { LPSTR modulenamea; - ConvertModulePathToAscii(modulename, &modulenamea); + ConvertModulePathToAscii(modulename.c_str(), &modulenamea); // See if this is a module listed in the patch table. If it is, update // the corresponding patch table entries' module base address. @@ -1927,10 +1917,6 @@ VOID VisualLeakDetector::RefreshModules() m_modulesLock.Leave(); // Free resources used by the old module list. - for (ModuleSet::Iterator moduleit = oldmodules->begin(); moduleit != oldmodules->end(); ++moduleit) { - delete [] (*moduleit).name; - delete [] (*moduleit).path; - } delete oldmodules; } diff --git a/vld.vcxproj b/vld.vcxproj index d4c6c891..478ffa83 100644 --- a/vld.vcxproj +++ b/vld.vcxproj @@ -79,6 +79,7 @@ false EditAndContinue true + 4201;4229 psapi.lib;%(AdditionalDependencies) @@ -96,6 +97,7 @@ Level4 false ProgramDatabase + 4201;4229 MachineX64 @@ -120,6 +122,7 @@ Fast OldStyle false + 4201;4229 true @@ -143,6 +146,7 @@ OldStyle false false + 4201;4229 true diff --git a/vldallocator.h b/vldallocator.h index a026d377..50434ae0 100644 --- a/vldallocator.h +++ b/vldallocator.h @@ -25,6 +25,8 @@ #include #include "vldheap.h" // Provides internal new and delete operators. +#pragma push_macro("new") +#undef new template class vldallocator: public std::allocator { @@ -39,17 +41,20 @@ class vldallocator: public std::allocator typedef vldallocator<_Tp1> other; }; - pointer allocate(size_type n, const void *hint=0) + pointer allocate(size_type n, const void * /*hint*/ = 0) { return (pointer)::operator new(sizeof(T)*n, __FILE__, __LINE__); } - void deallocate(pointer p, size_type n) + void deallocate(pointer p, size_type /*n*/) { return ::operator delete(p); } - vldallocator() throw(): std::allocator() { } - vldallocator(const vldallocator &a) throw(): std::allocator(a) { } + vldallocator() throw() : std::allocator() { } + vldallocator(const vldallocator &a) throw() : std::allocator(a) { } + template + vldallocator(const vldallocator &a) throw() : std::allocator(a) { } ~vldallocator() throw() { } }; +#pragma pop_macro("new") diff --git a/vldint.h b/vldint.h index da0f8a64..df41d8af 100644 --- a/vldint.h +++ b/vldint.h @@ -30,19 +30,20 @@ #endif #include -#include -#include "vld_def.h" -#include "version.h" -#include "callstack.h" // Provides a custom class for handling call stacks. -#include "map.h" // Provides a custom STL-like map template. -#include "ntapi.h" // Provides access to NT APIs. -#include "set.h" // Provides a custom STL-like set template. -#include "utility.h" // Provides miscellaneous utility functions. - #pragma push_macro("new") #undef new +#include #include #pragma pop_macro("new") +#include +#include "vld_def.h" +#include "version.h" +#include "callstack.h" // Provides a custom class for handling call stacks. +#include "map.h" // Provides a custom STL-like map template. +#include "ntapi.h" // Provides access to NT APIs. +#include "set.h" // Provides a custom STL-like set template. +#include "utility.h" // Provides miscellaneous utility functions. +#include "vldallocator.h" // Provides internal allocator. #define MAXMODULELISTLENGTH 512 // Maximum module list length, in characters. #define SELFTESTTEXTA "Memory Leak Self-Test" @@ -123,6 +124,7 @@ struct heapinfo_t { // HeapMaps map heaps (via their handles) to BlockMaps. typedef Map HeapMap; +typedef std::basic_string, vldallocator > vldstring; // This structure stores information, primarily the virtual address range, about // a given module and can be used with the Set template because it supports the @@ -143,8 +145,8 @@ struct moduleinfo_t { UINT32 flags; // Module flags: #define VLD_MODULE_EXCLUDED 0x1 // If set, this module is excluded from leak detection. #define VLD_MODULE_SYMBOLSLOADED 0x2 // If set, this module's debug symbols have been loaded. - LPCWSTR name; // The module's name (e.g. "kernel32.dll"). - LPCWSTR path; // The fully qualified path from where the module was loaded. + vldstring name; // The module's name (e.g. "kernel32.dll"). + vldstring path; // The fully qualified path from where the module was loaded. }; // ModuleSets store information about modules loaded in the process.