Skip to content

Commit

Permalink
Internal memory leak fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
KindDragon committed Apr 6, 2014
1 parent 3a4e7af commit d18634a
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 39 deletions.
34 changes: 10 additions & 24 deletions vld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 4 additions & 0 deletions vld.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
<StringPooling>false</StringPooling>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<EnablePREfast>true</EnablePREfast>
<DisableSpecificWarnings>4201;4229</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
Expand All @@ -96,6 +97,7 @@
<WarningLevel>Level4</WarningLevel>
<StringPooling>false</StringPooling>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4201;4229</DisableSpecificWarnings>
</ClCompile>
<Link>
<TargetMachine>MachineX64</TargetMachine>
Expand All @@ -120,6 +122,7 @@
<FloatingPointModel>Fast</FloatingPointModel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<FunctionLevelLinking>false</FunctionLevelLinking>
<DisableSpecificWarnings>4201;4229</DisableSpecificWarnings>
</ClCompile>
<Link>
<OptimizeReferences>true</OptimizeReferences>
Expand All @@ -143,6 +146,7 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<OmitFramePointers>false</OmitFramePointers>
<FunctionLevelLinking>false</FunctionLevelLinking>
<DisableSpecificWarnings>4201;4229</DisableSpecificWarnings>
</ClCompile>
<Link>
<OptimizeReferences>true</OptimizeReferences>
Expand Down
13 changes: 9 additions & 4 deletions vldallocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <memory>
#include "vldheap.h" // Provides internal new and delete operators.

#pragma push_macro("new")
#undef new
template <typename T>
class vldallocator: public std::allocator<T>
{
Expand All @@ -39,17 +41,20 @@ class vldallocator: public std::allocator<T>
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<T>() { }
vldallocator(const vldallocator &a) throw(): std::allocator<T>(a) { }
vldallocator() throw() : std::allocator<T>() { }
vldallocator(const vldallocator &a) throw() : std::allocator<T>(a) { }
template<class Other>
vldallocator(const vldallocator<Other> &a) throw() : std::allocator<T>(a) { }
~vldallocator() throw() { }
};
#pragma pop_macro("new")
24 changes: 13 additions & 11 deletions vldint.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,20 @@
#endif

#include <cstdio>
#include <windows.h>
#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 <string>
#include <memory>
#pragma pop_macro("new")
#include <windows.h>
#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"
Expand Down Expand Up @@ -123,6 +124,7 @@ struct heapinfo_t {

// HeapMaps map heaps (via their handles) to BlockMaps.
typedef Map<HANDLE, heapinfo_t*> HeapMap;
typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, vldallocator<wchar_t> > 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
Expand All @@ -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.
Expand Down

0 comments on commit d18634a

Please sign in to comment.