From 7a916694acff2c4822bb3f17afd49699f8a150a9 Mon Sep 17 00:00:00 2001 From: Matt Durak Date: Thu, 31 Jan 2019 13:14:20 -0800 Subject: [PATCH 1/2] Fix false positive for string initialization in header with initterm in callstack --- src/callstack.cpp | 1580 +++++++++-------- src/tests/static_string_test/static_string.h | 8 + .../static_string_test/static_string_test.cpp | 32 + .../static_string_test.vcxproj | 343 ++++ .../static_string_test.vcxproj.filters | 36 + src/tests/static_string_test/stdafx.cpp | 8 + src/tests/static_string_test/stdafx.h | 15 + src/tests/static_string_test/targetver.h | 8 + vld_vs14.sln | 1023 +++++------ 9 files changed, 1766 insertions(+), 1287 deletions(-) create mode 100644 src/tests/static_string_test/static_string.h create mode 100644 src/tests/static_string_test/static_string_test.cpp create mode 100644 src/tests/static_string_test/static_string_test.vcxproj create mode 100644 src/tests/static_string_test/static_string_test.vcxproj.filters create mode 100644 src/tests/static_string_test/stdafx.cpp create mode 100644 src/tests/static_string_test/stdafx.h create mode 100644 src/tests/static_string_test/targetver.h diff --git a/src/callstack.cpp b/src/callstack.cpp index a5404c31..b8971f3f 100644 --- a/src/callstack.cpp +++ b/src/callstack.cpp @@ -1,789 +1,791 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Visual Leak Detector - CallStack Class Implementations -// Copyright (c) 2005-2014 VLD Team -// -// 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. -// -//////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#define VLDBUILD -#include "callstack.h" // This class' header. -#include "utility.h" // Provides various utility functions. -#include "vldheap.h" // Provides internal new and delete operators. -#include "vldint.h" // Provides access to VLD internals. -#include "cppformat\format.h" - -// Imported global variables. -extern HANDLE g_currentProcess; -extern HANDLE g_currentThread; -extern CriticalSection g_heapMapLock; -extern VisualLeakDetector g_vld; -extern DbgHelp g_DbgHelp; - -// Helper function to compare the begin of a string with a substring -// -template -bool beginWith(const LPCWSTR filename, size_t len, wchar_t const (&substr)[N]) -{ - size_t count = N - 1; - return ((len >= count) && wcsncmp(filename, substr, count) == 0); -} - -// Helper function to compare the end of a string with a substring -// -template -bool endWith(const LPCWSTR filename, size_t len, wchar_t const (&substr)[N]) -{ - size_t count = N - 1; - return ((len >= count) && wcsncmp(filename + len - count, substr, count) == 0); -} - -// Constructor - Initializes the CallStack with an initial size of zero and one -// Chunk of capacity. -// -CallStack::CallStack () -{ - m_capacity = CALLSTACK_CHUNK_SIZE; - m_size = 0; - m_status = 0x0; - m_store.next = NULL; - m_topChunk = &m_store; - m_topIndex = 0; - m_resolved = NULL; - m_resolvedCapacity = 0; - m_resolvedLength = 0; -} - -// Destructor - Frees all memory allocated to the CallStack. -// -CallStack::~CallStack () -{ - CallStack::chunk_t *chunk = m_store.next; - CallStack::chunk_t *temp; - - while (chunk) { - temp = chunk; - chunk = temp->next; - delete temp; - } - - delete [] m_resolved; - - m_resolved = NULL; - m_resolvedCapacity = 0; - m_resolvedLength = 0; -} - -CallStack* CallStack::Create() -{ - CallStack* result = NULL; - if (g_vld.GetOptions() & VLD_OPT_SAFE_STACK_WALK) { - result = new SafeCallStack(); - } - else { - result = new FastCallStack(); - } - return result; -} - -// operator == - Equality operator. Compares the CallStack to another CallStack -// for equality. Two CallStacks are equal if they are the same size and if -// every frame in each is identical to the corresponding frame in the other. -// -// other (IN) - Reference to the CallStack to compare the current CallStack -// against for equality. -// -// Return Value: -// -// Returns true if the two CallStacks are equal. Otherwise returns false. -// -BOOL CallStack::operator == (const CallStack &other) const -{ - if (m_size != other.m_size) { - // They can't be equal if the sizes are different. - return FALSE; - } - - // Walk the chunk list and within each chunk walk the frames array until we - // either find a mismatch, or until we reach the end of the call stacks. - const CallStack::chunk_t *prevChunk = NULL; - const CallStack::chunk_t *chunk = &m_store; - const CallStack::chunk_t *otherChunk = &other.m_store; - while (prevChunk != m_topChunk) { - UINT32 size = (chunk == m_topChunk) ? m_topIndex : CALLSTACK_CHUNK_SIZE; - for (UINT32 index = 0; index < size; index++) { - if (chunk->frames[index] != otherChunk->frames[index]) { - // Found a mismatch. They are not equal. - return FALSE; - } - } - prevChunk = chunk; - chunk = chunk->next; - otherChunk = otherChunk->next; - } - - // Reached the end of the call stacks. They are equal. - return TRUE; -} - -// operator [] - Random access operator. Retrieves the frame at the specified -// index. -// -// Note: We give up a bit of efficiency here, in favor of efficiency of push -// operations. This is because walking of a CallStack is done infrequently -// (only if a leak is found), whereas pushing is done very frequently (for -// each frame in the program's call stack when the program allocates some -// memory). -// -// - index (IN): Specifies the index of the frame to retrieve. -// -// Return Value: -// -// Returns the program counter for the frame at the specified index. If the -// specified index is out of range for the CallStack, the return value is -// undefined. -// -UINT_PTR CallStack::operator [] (UINT32 index) const -{ - UINT32 chunknumber = index / CALLSTACK_CHUNK_SIZE; - const CallStack::chunk_t *chunk = &m_store; - - for (UINT32 count = 0; count < chunknumber; count++) { - chunk = chunk->next; - } - - return chunk->frames[index % CALLSTACK_CHUNK_SIZE]; -} - -// clear - Resets the CallStack, returning it to a state where no frames have -// been pushed onto it, readying it for reuse. -// -// Note: Calling this function does not release any memory allocated to the -// CallStack. We give up a bit of memory-usage efficiency here in favor of -// performance of push operations. -// -// Return Value: -// -// None. -// -VOID CallStack::clear () -{ - m_size = 0; - m_topChunk = &m_store; - m_topIndex = 0; - if (m_resolved) - { - delete [] m_resolved; - m_resolved = NULL; - } - m_resolvedCapacity = 0; - m_resolvedLength = 0; -} - -LPCWSTR CallStack::getFunctionName(SIZE_T programCounter, DWORD64& displacement64, - SYMBOL_INFO* functionInfo, CriticalSectionLocker& locker) const -{ - // Initialize structures passed to the symbol handler. - functionInfo->SizeOfStruct = sizeof(SYMBOL_INFO); - functionInfo->MaxNameLen = MAX_SYMBOL_NAME_LENGTH; - - // Try to get the name of the function containing this program - // counter address. - displacement64 = 0; - LPCWSTR functionName; - DbgTrace(L"dbghelp32.dll %i: SymFromAddrW\n", GetCurrentThreadId()); - if (g_DbgHelp.SymFromAddrW(g_currentProcess, programCounter, &displacement64, functionInfo, locker)) { - functionName = functionInfo->Name; - } - else { - // GetFormattedMessage( GetLastError() ); - fmt::WArrayWriter wf(functionInfo->Name, MAX_SYMBOL_NAME_LENGTH); - wf.write(L"" ADDRESSCPPFORMAT, programCounter); - functionName = wf.c_str(); - displacement64 = 0; - } - return functionName; -} - -DWORD CallStack::resolveFunction(SIZE_T programCounter, IMAGEHLP_LINEW64* sourceInfo, DWORD displacement, - LPCWSTR functionName, LPWSTR stack_line, DWORD stackLineSize) const -{ - WCHAR callingModuleName[260]; - HMODULE hCallingModule = GetCallingModule(programCounter); - LPWSTR moduleName = L"(Module name unavailable)"; - if (hCallingModule && - GetModuleFileName(hCallingModule, callingModuleName, _countof(callingModuleName)) > 0) - { - moduleName = wcsrchr(callingModuleName, L'\\'); - if (moduleName == NULL) - moduleName = wcsrchr(callingModuleName, L'/'); - if (moduleName != NULL) - moduleName++; - else - moduleName = callingModuleName; - } - - fmt::WArrayWriter w(stack_line, stackLineSize); - // Display the current stack frame's information. - if (sourceInfo) - { - if (displacement == 0) - { - w.write(L" {} ({}): {}!{}()\n", - sourceInfo->FileName, sourceInfo->LineNumber, moduleName, - functionName); - } - else - { - w.write(L" {} ({}): {}!{}() + 0x{:X} bytes\n", - sourceInfo->FileName, sourceInfo->LineNumber, moduleName, - functionName, displacement); - } - } - else - { - if (displacement == 0) - { - w.write(L" {}!{}()\n", - moduleName, functionName); - } - else - { - w.write(L" {}!{}() + 0x{:X} bytes\n", - moduleName, functionName, displacement); - } - } - DWORD NumChars = (DWORD)w.size(); - stack_line[NumChars] = '\0'; - return NumChars; -} - - -// isCrtStartupAlloc - Determines whether the memory leak was generated from crt startup code. -// This is not an actual memory leaks as it is freed by crt after the VLD object has been destroyed. -// -// Return Value: -// -// true if isCrtStartupModule for any callstack frame returns true. -// -bool CallStack::isCrtStartupAlloc() -{ - if (m_status & CALLSTACK_STATUS_STARTUPCRT) { - return true; - } else if (m_status & CALLSTACK_STATUS_NOTSTARTUPCRT) { - return false; - } - - IMAGEHLP_LINE64 sourceInfo = { 0 }; - sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - - BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE] = { 0 }; - CriticalSectionLocker locker(g_DbgHelp); - - // Iterate through each frame in the call stack. - for (UINT32 frame = 0; frame < m_size; frame++) { - // Try to get the source file and line number associated with - // this program counter address. - SIZE_T programCounter = (*this)[frame]; - DWORD64 displacement64; - LPCWSTR functionName = getFunctionName(programCounter, displacement64, (SYMBOL_INFO*)&symbolBuffer, locker); - - m_status |= isCrtStartupFunction(functionName); - if (m_status & CALLSTACK_STATUS_STARTUPCRT) { - return true; - } else if (m_status & CALLSTACK_STATUS_NOTSTARTUPCRT) { - return false; - } - } - - m_status |= CALLSTACK_STATUS_NOTSTARTUPCRT; - return false; -} - - -// dump - Dumps a nicely formatted rendition of the CallStack, including -// symbolic information (function names and line numbers) if available. -// -// Note: The symbol handler must be initialized prior to calling this -// function. -// -// - showinternalframes (IN): If true, then all frames in the CallStack will be -// dumped. Otherwise, frames internal to the heap will not be dumped. -// -// Return Value: -// -// None. -// -void CallStack::dump(BOOL showInternalFrames) -{ - if (!m_resolved) { - resolve(showInternalFrames); - } - - // The stack was reoslved already - if (m_resolved) { - return Print(m_resolved); - } -} - -// Resolve - Creates a nicely formatted rendition of the CallStack, including -// symbolic information (function names and line numbers) if available. and -// saves it for later retrieval. -// -// Note: The symbol handler must be initialized prior to calling this -// function. -// -// - showInternalFrames (IN): If true, then all frames in the CallStack will be -// dumped. Otherwise, frames internal to the heap will not be dumped. -// -// Return Value: -// -// None. -// -int CallStack::resolve(BOOL showInternalFrames) -{ - if (m_resolved) - { - // already resolved, no need to do it again - // resolving twice may report an incorrect module for the stack frames - // if the memory was leaked in a dynamic library that was already unloaded. - return 0; - } - - if (m_status & CALLSTACK_STATUS_STARTUPCRT) { - // there is no need to resolve a leak that will not be reported - return 0; - } - - if (m_status & CALLSTACK_STATUS_INCOMPLETE) { - // This call stack appears to be incomplete. Using StackWalk64 may be - // more reliable. - Report(L" HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n" - L" in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n" - L" complete stack trace.\n"); - } - - int unresolvedFunctionsCount = 0; - IMAGEHLP_LINE64 sourceInfo = { 0 }; - sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - - bool skipStartupLeaks = !!(g_vld.GetOptions() & VLD_OPT_SKIP_CRTSTARTUP_LEAKS); - - // Use static here to increase performance, and avoid heap allocs. - // It's thread safe because of g_heapMapLock lock. - static WCHAR stack_line[MAXREPORTLENGTH + 1] = L""; - bool isPrevFrameInternal = false; - DWORD NumChars = 0; - CriticalSectionLocker locker(g_DbgHelp); - - const size_t max_line_length = MAXREPORTLENGTH + 1; - m_resolvedCapacity = m_size * max_line_length; - const size_t allocedBytes = m_resolvedCapacity * sizeof(WCHAR); - m_resolved = new WCHAR[m_resolvedCapacity]; - if (m_resolved) { - ZeroMemory(m_resolved, allocedBytes); - } - - // Iterate through each frame in the call stack. - for (UINT32 frame = 0; frame < m_size; frame++) - { - // Try to get the source file and line number associated with - // this program counter address. - SIZE_T programCounter = (*this)[frame]; - if (GetCallingModule(programCounter) == g_vld.m_vldBase) - continue; - - DWORD64 displacement64; - BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE]; - LPCWSTR functionName = getFunctionName(programCounter, displacement64, (SYMBOL_INFO*)&symbolBuffer, locker); - - if (skipStartupLeaks) { - if (!(m_status & (CALLSTACK_STATUS_STARTUPCRT | CALLSTACK_STATUS_NOTSTARTUPCRT))) { - m_status |= isCrtStartupFunction(functionName); - } - if (m_status & CALLSTACK_STATUS_STARTUPCRT) { - delete[] m_resolved; - m_resolved = NULL; - m_resolvedCapacity = 0; - m_resolvedLength = 0; - return 0; - } - } - - // It turns out that calls to SymGetLineFromAddrW64 may free the very memory we are scrutinizing here - // in this method. If this is the case, m_Resolved will be null after SymGetLineFromAddrW64 returns. - // When that happens there is nothing we can do except crash. - DWORD displacement = 0; - DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId()); - BOOL foundline = g_DbgHelp.SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo, locker); - - bool isFrameInternal = false; - if (foundline && !showInternalFrames) { - if (isInternalModule(sourceInfo.FileName)) { - // Don't show frames in files internal to the heap. - isFrameInternal = true; - } - } - - // show one allocation function for context - if (NumChars > 0 && !isFrameInternal && isPrevFrameInternal) { - m_resolvedLength += NumChars; - if (m_resolved) { - wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); - } - } - isPrevFrameInternal = isFrameInternal; - - if (!foundline) - displacement = (DWORD)displacement64; - NumChars = resolveFunction( programCounter, foundline ? &sourceInfo : NULL, - displacement, functionName, stack_line, _countof( stack_line )); - - if (NumChars > 0 && !isFrameInternal) { - m_resolvedLength += NumChars; - if (m_resolved) { - wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); - } - } - } // end for loop - - m_status |= CALLSTACK_STATUS_NOTSTARTUPCRT; - return unresolvedFunctionsCount; -} - -const WCHAR* CallStack::getResolvedCallstack( BOOL showinternalframes ) -{ - resolve(showinternalframes); - return m_resolved; -} - -// push_back - Pushes a frame's program counter onto the CallStack. Pushes are -// always appended to the back of the chunk list (aka the "top" chunk). -// -// Note: This function will allocate additional memory as necessary to make -// room for new program counter addresses. -// -// - programcounter (IN): The program counter address of the frame to be pushed -// onto the CallStack. -// -// Return Value: -// -// None. -// -VOID CallStack::push_back (const UINT_PTR programcounter) -{ - if (m_size == m_capacity) { - // At current capacity. Allocate additional storage. - CallStack::chunk_t *chunk = new CallStack::chunk_t; - chunk->next = NULL; - m_topChunk->next = chunk; - m_topChunk = chunk; - m_topIndex = 0; - m_capacity += CALLSTACK_CHUNK_SIZE; - } - else if (m_topIndex >= CALLSTACK_CHUNK_SIZE) { - // There is more capacity, but not in this chunk. Go to the next chunk. - // Note that this only happens if this CallStack has previously been - // cleared (clearing resets the data, but doesn't give up any allocated - // space). - m_topChunk = m_topChunk->next; - m_topIndex = 0; - } - - m_topChunk->frames[m_topIndex++] = programcounter; - m_size++; -} - -UINT CallStack::isCrtStartupFunction( LPCWSTR functionName ) const -{ - size_t len = wcslen(functionName); - - if (beginWith(functionName, len, L"_malloc_crt") - || beginWith(functionName, len, L"_calloc_crt") - || endWith(functionName, len, L"CRT_INIT") - || endWith(functionName, len, L"initterm_e") - || beginWith(functionName, len, L"_cinit") - || beginWith(functionName, len, L"std::`dynamic initializer for '") - // VS2008 Release - || (wcscmp(functionName, L"std::locale::facet::facet_Register") == 0) - // VS2010 Release - || (wcscmp(functionName, L"std::locale::facet::_Facet_Register") == 0) - // VS2012 Release - || beginWith(functionName, len, L"std::locale::_Init()") - || beginWith(functionName, len, L"std::basic_streambuf<") - // VS2015 - || beginWith(functionName, len, L"common_initialize_environment_nolock<") - || beginWith(functionName, len, L"common_configure_argv<") - || beginWith(functionName, len, L"__acrt_initialize") - || beginWith(functionName, len, L"__acrt_allocate_buffer_for_argv") - || beginWith(functionName, len, L"_register_onexit_function") - // VS2015 Release - || (wcscmp(functionName, L"setlocale") == 0) - || (wcscmp(functionName, L"_wsetlocale") == 0) - || (wcscmp(functionName, L"_Getctype") == 0) - || (wcscmp(functionName, L"std::_Facet_Register") == 0) - || endWith(functionName, len, L">::_Getcat") - ) { - return CALLSTACK_STATUS_STARTUPCRT; - } - - if (endWith(functionName, len, L"DllMainCRTStartup") - || endWith(functionName, len, L"mainCRTStartup") - || beginWith(functionName, len, L"`dynamic initializer for '")) { - // When we reach this point there is no reason going further down the stack - return CALLSTACK_STATUS_NOTSTARTUPCRT; - } - - return NULL; -} - -bool CallStack::isInternalModule( const PWSTR filename ) const -{ - size_t len = wcslen(filename); - return - // VS2015 - endWith(filename, len, L"\\atlmfc\\include\\atlsimpstr.h") || - endWith(filename, len, L"\\atlmfc\\include\\cstringt.h") || - endWith(filename, len, L"\\atlmfc\\src\\mfc\\afxmem.cpp") || - endWith(filename, len, L"\\atlmfc\\src\\mfc\\strcore.cpp") || - endWith(filename, len, L"\\vcstartup\\src\\heap\\new_scalar.cpp") || - endWith(filename, len, L"\\vcstartup\\src\\heap\\new_array.cpp") || - endWith(filename, len, L"\\vcstartup\\src\\heap\\new_debug.cpp") || - endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\align.cpp") || - endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\malloc.cpp") || - endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\debug_heap.cpp") || - // VS2013 - beginWith(filename, len, L"f:\\dd\\vctools\\crt\\crtw32\\") || - //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgheap.c") || - //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgnew.cpp") || - //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgmalloc.c") || - //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgrealloc.c") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\new.cpp") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\new2.cpp") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\malloc.c") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\realloc.c") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\calloc.c") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\calloc_impl.c") || - //endWith(filename, len, L"\\crt\\crtw32\\string\\strdup.c") || - //endWith(filename, len, L"\\crt\\crtw32\\string\\wcsdup.c") || - // VS2010 - endWith(filename, len, L"\\crt\\src\\afxmem.cpp") || - endWith(filename, len, L"\\crt\\src\\dbgheap.c") || - endWith(filename, len, L"\\crt\\src\\dbgnew.cpp") || - endWith(filename, len, L"\\crt\\src\\dbgmalloc.c") || - endWith(filename, len, L"\\crt\\src\\dbgcalloc.c") || - endWith(filename, len, L"\\crt\\src\\dbgrealloc.c") || - endWith(filename, len, L"\\crt\\src\\dbgdel.cp") || - endWith(filename, len, L"\\crt\\src\\new.cpp") || - endWith(filename, len, L"\\crt\\src\\newaop.cpp") || - endWith(filename, len, L"\\crt\\src\\malloc.c") || - endWith(filename, len, L"\\crt\\src\\realloc.c") || - endWith(filename, len, L"\\crt\\src\\free.c") || - endWith(filename, len, L"\\crt\\src\\strdup.c") || - endWith(filename, len, L"\\crt\\src\\wcsdup.c") || - endWith(filename, len, L"\\vc\\include\\xmemory0") || - // default - (false); -} - -// getStackTrace - Traces the stack as far back as possible, or until 'maxdepth' -// frames have been traced. Populates the CallStack with one entry for each -// stack frame traced. -// -// Note: This function uses a very efficient method to walk the stack from -// frame to frame, so it is quite fast. However, unconventional stack frames -// (such as those created when frame pointer omission optimization is used) -// will not be successfully walked by this function and will cause the -// stack trace to terminate prematurely. -// -// - maxdepth (IN): Maximum number of frames to trace back. -// -// - framepointer (IN): Frame (base) pointer at which to begin the stack trace. -// If NULL, then the stack trace will begin at this function. -// -// Return Value: -// -// None. -// -VOID FastCallStack::getStackTrace (UINT32 maxdepth, const context_t& context) -{ - UINT32 count = 0; - UINT_PTR function = context.func; - if (function != NULL) - { - count++; - push_back(function); - } - -/*#if defined(_M_IX86) - UINT_PTR* framePointer = (UINT_PTR*)context.BPREG; - while (count < maxdepth) { - if (*framePointer < (UINT_PTR)framePointer) { - if (*framePointer == NULL) { - // Looks like we reached the end of the stack. - break; - } - else { - // Invalid frame pointer. Frame pointer addresses should always - // increase as we move up the stack. - m_status |= CALLSTACK_STATUS_INCOMPLETE; - break; - } - } - if (*framePointer & (sizeof(UINT_PTR*) - 1)) { - // Invalid frame pointer. Frame pointer addresses should always - // be aligned to the size of a pointer. This probably means that - // we've encountered a frame that was created by a module built with - // frame pointer omission (FPO) optimization turned on. - m_status |= CALLSTACK_STATUS_INCOMPLETE; - break; - } - if (IsBadReadPtr((UINT*)*framePointer, sizeof(UINT_PTR*))) { - // Bogus frame pointer. Again, this probably means that we've - // encountered a frame built with FPO optimization. - m_status |= CALLSTACK_STATUS_INCOMPLETE; - break; - } - count++; - push_back(*(framePointer + 1)); - framePointer = (UINT_PTR*)*framePointer; - } -#elif defined(_M_X64)*/ - UINT32 maxframes = min(62, maxdepth + 10); - UINT_PTR* myFrames = new UINT_PTR[maxframes]; - ZeroMemory(myFrames, sizeof(UINT_PTR) * maxframes); - ULONG BackTraceHash; - maxframes = RtlCaptureStackBackTrace(0, maxframes, reinterpret_cast(myFrames), &BackTraceHash); - m_hashValue = BackTraceHash; - UINT32 startIndex = 0; - while (count < maxframes) { - if (myFrames[count] == 0) - break; - if (myFrames[count] == context.fp) - startIndex = count; - count++; - } - count = startIndex; - while (count < maxframes) { - if (myFrames[count] == 0) - break; - push_back(myFrames[count]); - count++; - } - delete [] myFrames; -//#endif -} - -// getStackTrace - Traces the stack as far back as possible, or until 'maxdepth' -// frames have been traced. Populates the CallStack with one entry for each -// stack frame traced. -// -// Note: This function uses a documented Windows API to walk the stack. This -// API is supposed to be the most reliable way to walk the stack. It claims -// to be able to walk stack frames that do not follow the conventional stack -// frame layout. However, this robustness comes at a cost: it is *extremely* -// slow compared to walking frames by following frame (base) pointers. -// -// - maxdepth (IN): Maximum number of frames to trace back. -// -// - framepointer (IN): Frame (base) pointer at which to begin the stack trace. -// If NULL, then the stack trace will begin at this function. -// -// Return Value: -// -// None. -// -VOID SafeCallStack::getStackTrace (UINT32 maxdepth, const context_t& context) -{ - UINT32 count = 0; - UINT_PTR function = context.func; - if (function != NULL) - { - count++; - push_back(function); - } - - if (context.IPREG == NULL) - { - return; - } - - count++; - push_back(context.IPREG); - - DWORD architecture = X86X64ARCHITECTURE; - - // Get the required values for initialization of the STACKFRAME64 structure - // to be passed to StackWalk64(). Required fields are AddrPC and AddrFrame. - CONTEXT currentContext; - memset(¤tContext, 0, sizeof(currentContext)); - currentContext.SPREG = context.SPREG; - currentContext.BPREG = context.BPREG; - currentContext.IPREG = context.IPREG; - - // Initialize the STACKFRAME64 structure. - STACKFRAME64 frame; - memset(&frame, 0x0, sizeof(frame)); - frame.AddrPC.Offset = currentContext.IPREG; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrStack.Offset = currentContext.SPREG; - frame.AddrStack.Mode = AddrModeFlat; - frame.AddrFrame.Offset = currentContext.BPREG; - frame.AddrFrame.Mode = AddrModeFlat; - frame.Virtual = TRUE; - - CriticalSectionLocker<> cs(g_heapMapLock); - CriticalSectionLocker locker(g_DbgHelp); - - // Walk the stack. - while (count < maxdepth) { - count++; - DbgTrace(L"dbghelp32.dll %i: StackWalk64\n", GetCurrentThreadId()); - if (!g_DbgHelp.StackWalk64(architecture, g_currentProcess, g_currentThread, &frame, ¤tContext, NULL, - SymFunctionTableAccess64, SymGetModuleBase64, NULL, locker)) { - // Couldn't trace back through any more frames. - break; - } - if (frame.AddrFrame.Offset == 0) { - // End of stack. - break; - } - - // Push this frame's program counter onto the CallStack. - push_back((UINT_PTR)frame.AddrPC.Offset); - } -} - -// getHashValue - Generate callstack hash value. -// -// Return Value: -// -// None. -// -DWORD SafeCallStack::getHashValue() const -{ - DWORD hashcode = 0xD202EF8D; - - // Iterate through each frame in the call stack. - for (UINT32 frame = 0; frame < m_size; frame++) { - UINT_PTR programcounter = (*this)[frame]; - hashcode = CalculateCRC32(programcounter, hashcode); - } - return hashcode; -} +//////////////////////////////////////////////////////////////////////////////// +// +// Visual Leak Detector - CallStack Class Implementations +// Copyright (c) 2005-2014 VLD Team +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#define VLDBUILD +#include "callstack.h" // This class' header. +#include "utility.h" // Provides various utility functions. +#include "vldheap.h" // Provides internal new and delete operators. +#include "vldint.h" // Provides access to VLD internals. +#include "cppformat\format.h" + +// Imported global variables. +extern HANDLE g_currentProcess; +extern HANDLE g_currentThread; +extern CriticalSection g_heapMapLock; +extern VisualLeakDetector g_vld; +extern DbgHelp g_DbgHelp; + +// Helper function to compare the begin of a string with a substring +// +template +bool beginWith(const LPCWSTR filename, size_t len, wchar_t const (&substr)[N]) +{ + size_t count = N - 1; + return ((len >= count) && wcsncmp(filename, substr, count) == 0); +} + +// Helper function to compare the end of a string with a substring +// +template +bool endWith(const LPCWSTR filename, size_t len, wchar_t const (&substr)[N]) +{ + size_t count = N - 1; + return ((len >= count) && wcsncmp(filename + len - count, substr, count) == 0); +} + +// Constructor - Initializes the CallStack with an initial size of zero and one +// Chunk of capacity. +// +CallStack::CallStack () +{ + m_capacity = CALLSTACK_CHUNK_SIZE; + m_size = 0; + m_status = 0x0; + m_store.next = NULL; + m_topChunk = &m_store; + m_topIndex = 0; + m_resolved = NULL; + m_resolvedCapacity = 0; + m_resolvedLength = 0; +} + +// Destructor - Frees all memory allocated to the CallStack. +// +CallStack::~CallStack () +{ + CallStack::chunk_t *chunk = m_store.next; + CallStack::chunk_t *temp; + + while (chunk) { + temp = chunk; + chunk = temp->next; + delete temp; + } + + delete [] m_resolved; + + m_resolved = NULL; + m_resolvedCapacity = 0; + m_resolvedLength = 0; +} + +CallStack* CallStack::Create() +{ + CallStack* result = NULL; + if (g_vld.GetOptions() & VLD_OPT_SAFE_STACK_WALK) { + result = new SafeCallStack(); + } + else { + result = new FastCallStack(); + } + return result; +} + +// operator == - Equality operator. Compares the CallStack to another CallStack +// for equality. Two CallStacks are equal if they are the same size and if +// every frame in each is identical to the corresponding frame in the other. +// +// other (IN) - Reference to the CallStack to compare the current CallStack +// against for equality. +// +// Return Value: +// +// Returns true if the two CallStacks are equal. Otherwise returns false. +// +BOOL CallStack::operator == (const CallStack &other) const +{ + if (m_size != other.m_size) { + // They can't be equal if the sizes are different. + return FALSE; + } + + // Walk the chunk list and within each chunk walk the frames array until we + // either find a mismatch, or until we reach the end of the call stacks. + const CallStack::chunk_t *prevChunk = NULL; + const CallStack::chunk_t *chunk = &m_store; + const CallStack::chunk_t *otherChunk = &other.m_store; + while (prevChunk != m_topChunk) { + UINT32 size = (chunk == m_topChunk) ? m_topIndex : CALLSTACK_CHUNK_SIZE; + for (UINT32 index = 0; index < size; index++) { + if (chunk->frames[index] != otherChunk->frames[index]) { + // Found a mismatch. They are not equal. + return FALSE; + } + } + prevChunk = chunk; + chunk = chunk->next; + otherChunk = otherChunk->next; + } + + // Reached the end of the call stacks. They are equal. + return TRUE; +} + +// operator [] - Random access operator. Retrieves the frame at the specified +// index. +// +// Note: We give up a bit of efficiency here, in favor of efficiency of push +// operations. This is because walking of a CallStack is done infrequently +// (only if a leak is found), whereas pushing is done very frequently (for +// each frame in the program's call stack when the program allocates some +// memory). +// +// - index (IN): Specifies the index of the frame to retrieve. +// +// Return Value: +// +// Returns the program counter for the frame at the specified index. If the +// specified index is out of range for the CallStack, the return value is +// undefined. +// +UINT_PTR CallStack::operator [] (UINT32 index) const +{ + UINT32 chunknumber = index / CALLSTACK_CHUNK_SIZE; + const CallStack::chunk_t *chunk = &m_store; + + for (UINT32 count = 0; count < chunknumber; count++) { + chunk = chunk->next; + } + + return chunk->frames[index % CALLSTACK_CHUNK_SIZE]; +} + +// clear - Resets the CallStack, returning it to a state where no frames have +// been pushed onto it, readying it for reuse. +// +// Note: Calling this function does not release any memory allocated to the +// CallStack. We give up a bit of memory-usage efficiency here in favor of +// performance of push operations. +// +// Return Value: +// +// None. +// +VOID CallStack::clear () +{ + m_size = 0; + m_topChunk = &m_store; + m_topIndex = 0; + if (m_resolved) + { + delete [] m_resolved; + m_resolved = NULL; + } + m_resolvedCapacity = 0; + m_resolvedLength = 0; +} + +LPCWSTR CallStack::getFunctionName(SIZE_T programCounter, DWORD64& displacement64, + SYMBOL_INFO* functionInfo, CriticalSectionLocker& locker) const +{ + // Initialize structures passed to the symbol handler. + functionInfo->SizeOfStruct = sizeof(SYMBOL_INFO); + functionInfo->MaxNameLen = MAX_SYMBOL_NAME_LENGTH; + + // Try to get the name of the function containing this program + // counter address. + displacement64 = 0; + LPCWSTR functionName; + DbgTrace(L"dbghelp32.dll %i: SymFromAddrW\n", GetCurrentThreadId()); + if (g_DbgHelp.SymFromAddrW(g_currentProcess, programCounter, &displacement64, functionInfo, locker)) { + functionName = functionInfo->Name; + } + else { + // GetFormattedMessage( GetLastError() ); + fmt::WArrayWriter wf(functionInfo->Name, MAX_SYMBOL_NAME_LENGTH); + wf.write(L"" ADDRESSCPPFORMAT, programCounter); + functionName = wf.c_str(); + displacement64 = 0; + } + return functionName; +} + +DWORD CallStack::resolveFunction(SIZE_T programCounter, IMAGEHLP_LINEW64* sourceInfo, DWORD displacement, + LPCWSTR functionName, LPWSTR stack_line, DWORD stackLineSize) const +{ + WCHAR callingModuleName[260]; + HMODULE hCallingModule = GetCallingModule(programCounter); + LPWSTR moduleName = L"(Module name unavailable)"; + if (hCallingModule && + GetModuleFileName(hCallingModule, callingModuleName, _countof(callingModuleName)) > 0) + { + moduleName = wcsrchr(callingModuleName, L'\\'); + if (moduleName == NULL) + moduleName = wcsrchr(callingModuleName, L'/'); + if (moduleName != NULL) + moduleName++; + else + moduleName = callingModuleName; + } + + fmt::WArrayWriter w(stack_line, stackLineSize); + // Display the current stack frame's information. + if (sourceInfo) + { + if (displacement == 0) + { + w.write(L" {} ({}): {}!{}()\n", + sourceInfo->FileName, sourceInfo->LineNumber, moduleName, + functionName); + } + else + { + w.write(L" {} ({}): {}!{}() + 0x{:X} bytes\n", + sourceInfo->FileName, sourceInfo->LineNumber, moduleName, + functionName, displacement); + } + } + else + { + if (displacement == 0) + { + w.write(L" {}!{}()\n", + moduleName, functionName); + } + else + { + w.write(L" {}!{}() + 0x{:X} bytes\n", + moduleName, functionName, displacement); + } + } + DWORD NumChars = (DWORD)w.size(); + stack_line[NumChars] = '\0'; + return NumChars; +} + + +// isCrtStartupAlloc - Determines whether the memory leak was generated from crt startup code. +// This is not an actual memory leaks as it is freed by crt after the VLD object has been destroyed. +// +// Return Value: +// +// true if isCrtStartupModule for any callstack frame returns true. +// +bool CallStack::isCrtStartupAlloc() +{ + if (m_status & CALLSTACK_STATUS_STARTUPCRT) { + return true; + } else if (m_status & CALLSTACK_STATUS_NOTSTARTUPCRT) { + return false; + } + + IMAGEHLP_LINE64 sourceInfo = { 0 }; + sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE] = { 0 }; + CriticalSectionLocker locker(g_DbgHelp); + + // Iterate through each frame in the call stack. + for (UINT32 frame = 0; frame < m_size; frame++) { + // Try to get the source file and line number associated with + // this program counter address. + SIZE_T programCounter = (*this)[frame]; + DWORD64 displacement64; + LPCWSTR functionName = getFunctionName(programCounter, displacement64, (SYMBOL_INFO*)&symbolBuffer, locker); + + m_status |= isCrtStartupFunction(functionName); + if (m_status & CALLSTACK_STATUS_STARTUPCRT) { + return true; + } else if (m_status & CALLSTACK_STATUS_NOTSTARTUPCRT) { + return false; + } + } + + m_status |= CALLSTACK_STATUS_NOTSTARTUPCRT; + return false; +} + + +// dump - Dumps a nicely formatted rendition of the CallStack, including +// symbolic information (function names and line numbers) if available. +// +// Note: The symbol handler must be initialized prior to calling this +// function. +// +// - showinternalframes (IN): If true, then all frames in the CallStack will be +// dumped. Otherwise, frames internal to the heap will not be dumped. +// +// Return Value: +// +// None. +// +void CallStack::dump(BOOL showInternalFrames) +{ + if (!m_resolved) { + resolve(showInternalFrames); + } + + // The stack was reoslved already + if (m_resolved) { + return Print(m_resolved); + } +} + +// Resolve - Creates a nicely formatted rendition of the CallStack, including +// symbolic information (function names and line numbers) if available. and +// saves it for later retrieval. +// +// Note: The symbol handler must be initialized prior to calling this +// function. +// +// - showInternalFrames (IN): If true, then all frames in the CallStack will be +// dumped. Otherwise, frames internal to the heap will not be dumped. +// +// Return Value: +// +// None. +// +int CallStack::resolve(BOOL showInternalFrames) +{ + if (m_resolved) + { + // already resolved, no need to do it again + // resolving twice may report an incorrect module for the stack frames + // if the memory was leaked in a dynamic library that was already unloaded. + return 0; + } + + if (m_status & CALLSTACK_STATUS_STARTUPCRT) { + // there is no need to resolve a leak that will not be reported + return 0; + } + + if (m_status & CALLSTACK_STATUS_INCOMPLETE) { + // This call stack appears to be incomplete. Using StackWalk64 may be + // more reliable. + Report(L" HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n" + L" in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n" + L" complete stack trace.\n"); + } + + int unresolvedFunctionsCount = 0; + IMAGEHLP_LINE64 sourceInfo = { 0 }; + sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + bool skipStartupLeaks = !!(g_vld.GetOptions() & VLD_OPT_SKIP_CRTSTARTUP_LEAKS); + + // Use static here to increase performance, and avoid heap allocs. + // It's thread safe because of g_heapMapLock lock. + static WCHAR stack_line[MAXREPORTLENGTH + 1] = L""; + bool isPrevFrameInternal = false; + DWORD NumChars = 0; + CriticalSectionLocker locker(g_DbgHelp); + + const size_t max_line_length = MAXREPORTLENGTH + 1; + m_resolvedCapacity = m_size * max_line_length; + const size_t allocedBytes = m_resolvedCapacity * sizeof(WCHAR); + m_resolved = new WCHAR[m_resolvedCapacity]; + if (m_resolved) { + ZeroMemory(m_resolved, allocedBytes); + } + + // Iterate through each frame in the call stack. + for (UINT32 frame = 0; frame < m_size; frame++) + { + // Try to get the source file and line number associated with + // this program counter address. + SIZE_T programCounter = (*this)[frame]; + if (GetCallingModule(programCounter) == g_vld.m_vldBase) + continue; + + DWORD64 displacement64; + BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE]; + LPCWSTR functionName = getFunctionName(programCounter, displacement64, (SYMBOL_INFO*)&symbolBuffer, locker); + + if (skipStartupLeaks) { + if (!(m_status & (CALLSTACK_STATUS_STARTUPCRT | CALLSTACK_STATUS_NOTSTARTUPCRT))) { + m_status |= isCrtStartupFunction(functionName); + } + if (m_status & CALLSTACK_STATUS_STARTUPCRT) { + delete[] m_resolved; + m_resolved = NULL; + m_resolvedCapacity = 0; + m_resolvedLength = 0; + return 0; + } + } + + // It turns out that calls to SymGetLineFromAddrW64 may free the very memory we are scrutinizing here + // in this method. If this is the case, m_Resolved will be null after SymGetLineFromAddrW64 returns. + // When that happens there is nothing we can do except crash. + DWORD displacement = 0; + DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId()); + BOOL foundline = g_DbgHelp.SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo, locker); + + bool isFrameInternal = false; + if (foundline && !showInternalFrames) { + if (isInternalModule(sourceInfo.FileName)) { + // Don't show frames in files internal to the heap. + isFrameInternal = true; + } + } + + // show one allocation function for context + if (NumChars > 0 && !isFrameInternal && isPrevFrameInternal) { + m_resolvedLength += NumChars; + if (m_resolved) { + wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); + } + } + isPrevFrameInternal = isFrameInternal; + + if (!foundline) + displacement = (DWORD)displacement64; + NumChars = resolveFunction( programCounter, foundline ? &sourceInfo : NULL, + displacement, functionName, stack_line, _countof( stack_line )); + + if (NumChars > 0 && !isFrameInternal) { + m_resolvedLength += NumChars; + if (m_resolved) { + wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); + } + } + } // end for loop + + m_status |= CALLSTACK_STATUS_NOTSTARTUPCRT; + return unresolvedFunctionsCount; +} + +const WCHAR* CallStack::getResolvedCallstack( BOOL showinternalframes ) +{ + resolve(showinternalframes); + return m_resolved; +} + +// push_back - Pushes a frame's program counter onto the CallStack. Pushes are +// always appended to the back of the chunk list (aka the "top" chunk). +// +// Note: This function will allocate additional memory as necessary to make +// room for new program counter addresses. +// +// - programcounter (IN): The program counter address of the frame to be pushed +// onto the CallStack. +// +// Return Value: +// +// None. +// +VOID CallStack::push_back (const UINT_PTR programcounter) +{ + if (m_size == m_capacity) { + // At current capacity. Allocate additional storage. + CallStack::chunk_t *chunk = new CallStack::chunk_t; + chunk->next = NULL; + m_topChunk->next = chunk; + m_topChunk = chunk; + m_topIndex = 0; + m_capacity += CALLSTACK_CHUNK_SIZE; + } + else if (m_topIndex >= CALLSTACK_CHUNK_SIZE) { + // There is more capacity, but not in this chunk. Go to the next chunk. + // Note that this only happens if this CallStack has previously been + // cleared (clearing resets the data, but doesn't give up any allocated + // space). + m_topChunk = m_topChunk->next; + m_topIndex = 0; + } + + m_topChunk->frames[m_topIndex++] = programcounter; + m_size++; +} + +UINT CallStack::isCrtStartupFunction( LPCWSTR functionName ) const +{ + size_t len = wcslen(functionName); + + if (beginWith(functionName, len, L"_malloc_crt") + || beginWith(functionName, len, L"_calloc_crt") + || endWith(functionName, len, L"CRT_INIT") + || endWith(functionName, len, L"initterm_e") + || beginWith(functionName, len, L"_cinit") + || beginWith(functionName, len, L"std::`dynamic initializer for '") + // VS2008 Release + || (wcscmp(functionName, L"std::locale::facet::facet_Register") == 0) + // VS2010 Release + || (wcscmp(functionName, L"std::locale::facet::_Facet_Register") == 0) + // VS2012 Release + || beginWith(functionName, len, L"std::locale::_Init()") + || beginWith(functionName, len, L"std::basic_streambuf<") + // VS2015 + || beginWith(functionName, len, L"common_initialize_environment_nolock<") + || beginWith(functionName, len, L"common_configure_argv<") + || beginWith(functionName, len, L"__acrt_initialize") + || beginWith(functionName, len, L"__acrt_allocate_buffer_for_argv") + || beginWith(functionName, len, L"_register_onexit_function") + // VS2015 Release + || (wcscmp(functionName, L"setlocale") == 0) + || (wcscmp(functionName, L"_wsetlocale") == 0) + || (wcscmp(functionName, L"_Getctype") == 0) + || (wcscmp(functionName, L"std::_Facet_Register") == 0) + || endWith(functionName, len, L">::_Getcat") + // Fix + || endWith(functionName, len, L"initterm") + ) { + return CALLSTACK_STATUS_STARTUPCRT; + } + + if (endWith(functionName, len, L"DllMainCRTStartup") + || endWith(functionName, len, L"mainCRTStartup") + || beginWith(functionName, len, L"`dynamic initializer for '")) { + // When we reach this point there is no reason going further down the stack + return CALLSTACK_STATUS_NOTSTARTUPCRT; + } + + return NULL; +} + +bool CallStack::isInternalModule( const PWSTR filename ) const +{ + size_t len = wcslen(filename); + return + // VS2015 + endWith(filename, len, L"\\atlmfc\\include\\atlsimpstr.h") || + endWith(filename, len, L"\\atlmfc\\include\\cstringt.h") || + endWith(filename, len, L"\\atlmfc\\src\\mfc\\afxmem.cpp") || + endWith(filename, len, L"\\atlmfc\\src\\mfc\\strcore.cpp") || + endWith(filename, len, L"\\vcstartup\\src\\heap\\new_scalar.cpp") || + endWith(filename, len, L"\\vcstartup\\src\\heap\\new_array.cpp") || + endWith(filename, len, L"\\vcstartup\\src\\heap\\new_debug.cpp") || + endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\align.cpp") || + endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\malloc.cpp") || + endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\debug_heap.cpp") || + // VS2013 + beginWith(filename, len, L"f:\\dd\\vctools\\crt\\crtw32\\") || + //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgheap.c") || + //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgnew.cpp") || + //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgmalloc.c") || + //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgrealloc.c") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\new.cpp") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\new2.cpp") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\malloc.c") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\realloc.c") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\calloc.c") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\calloc_impl.c") || + //endWith(filename, len, L"\\crt\\crtw32\\string\\strdup.c") || + //endWith(filename, len, L"\\crt\\crtw32\\string\\wcsdup.c") || + // VS2010 + endWith(filename, len, L"\\crt\\src\\afxmem.cpp") || + endWith(filename, len, L"\\crt\\src\\dbgheap.c") || + endWith(filename, len, L"\\crt\\src\\dbgnew.cpp") || + endWith(filename, len, L"\\crt\\src\\dbgmalloc.c") || + endWith(filename, len, L"\\crt\\src\\dbgcalloc.c") || + endWith(filename, len, L"\\crt\\src\\dbgrealloc.c") || + endWith(filename, len, L"\\crt\\src\\dbgdel.cp") || + endWith(filename, len, L"\\crt\\src\\new.cpp") || + endWith(filename, len, L"\\crt\\src\\newaop.cpp") || + endWith(filename, len, L"\\crt\\src\\malloc.c") || + endWith(filename, len, L"\\crt\\src\\realloc.c") || + endWith(filename, len, L"\\crt\\src\\free.c") || + endWith(filename, len, L"\\crt\\src\\strdup.c") || + endWith(filename, len, L"\\crt\\src\\wcsdup.c") || + endWith(filename, len, L"\\vc\\include\\xmemory0") || + // default + (false); +} + +// getStackTrace - Traces the stack as far back as possible, or until 'maxdepth' +// frames have been traced. Populates the CallStack with one entry for each +// stack frame traced. +// +// Note: This function uses a very efficient method to walk the stack from +// frame to frame, so it is quite fast. However, unconventional stack frames +// (such as those created when frame pointer omission optimization is used) +// will not be successfully walked by this function and will cause the +// stack trace to terminate prematurely. +// +// - maxdepth (IN): Maximum number of frames to trace back. +// +// - framepointer (IN): Frame (base) pointer at which to begin the stack trace. +// If NULL, then the stack trace will begin at this function. +// +// Return Value: +// +// None. +// +VOID FastCallStack::getStackTrace (UINT32 maxdepth, const context_t& context) +{ + UINT32 count = 0; + UINT_PTR function = context.func; + if (function != NULL) + { + count++; + push_back(function); + } + +/*#if defined(_M_IX86) + UINT_PTR* framePointer = (UINT_PTR*)context.BPREG; + while (count < maxdepth) { + if (*framePointer < (UINT_PTR)framePointer) { + if (*framePointer == NULL) { + // Looks like we reached the end of the stack. + break; + } + else { + // Invalid frame pointer. Frame pointer addresses should always + // increase as we move up the stack. + m_status |= CALLSTACK_STATUS_INCOMPLETE; + break; + } + } + if (*framePointer & (sizeof(UINT_PTR*) - 1)) { + // Invalid frame pointer. Frame pointer addresses should always + // be aligned to the size of a pointer. This probably means that + // we've encountered a frame that was created by a module built with + // frame pointer omission (FPO) optimization turned on. + m_status |= CALLSTACK_STATUS_INCOMPLETE; + break; + } + if (IsBadReadPtr((UINT*)*framePointer, sizeof(UINT_PTR*))) { + // Bogus frame pointer. Again, this probably means that we've + // encountered a frame built with FPO optimization. + m_status |= CALLSTACK_STATUS_INCOMPLETE; + break; + } + count++; + push_back(*(framePointer + 1)); + framePointer = (UINT_PTR*)*framePointer; + } +#elif defined(_M_X64)*/ + UINT32 maxframes = min(62, maxdepth + 10); + UINT_PTR* myFrames = new UINT_PTR[maxframes]; + ZeroMemory(myFrames, sizeof(UINT_PTR) * maxframes); + ULONG BackTraceHash; + maxframes = RtlCaptureStackBackTrace(0, maxframes, reinterpret_cast(myFrames), &BackTraceHash); + m_hashValue = BackTraceHash; + UINT32 startIndex = 0; + while (count < maxframes) { + if (myFrames[count] == 0) + break; + if (myFrames[count] == context.fp) + startIndex = count; + count++; + } + count = startIndex; + while (count < maxframes) { + if (myFrames[count] == 0) + break; + push_back(myFrames[count]); + count++; + } + delete [] myFrames; +//#endif +} + +// getStackTrace - Traces the stack as far back as possible, or until 'maxdepth' +// frames have been traced. Populates the CallStack with one entry for each +// stack frame traced. +// +// Note: This function uses a documented Windows API to walk the stack. This +// API is supposed to be the most reliable way to walk the stack. It claims +// to be able to walk stack frames that do not follow the conventional stack +// frame layout. However, this robustness comes at a cost: it is *extremely* +// slow compared to walking frames by following frame (base) pointers. +// +// - maxdepth (IN): Maximum number of frames to trace back. +// +// - framepointer (IN): Frame (base) pointer at which to begin the stack trace. +// If NULL, then the stack trace will begin at this function. +// +// Return Value: +// +// None. +// +VOID SafeCallStack::getStackTrace (UINT32 maxdepth, const context_t& context) +{ + UINT32 count = 0; + UINT_PTR function = context.func; + if (function != NULL) + { + count++; + push_back(function); + } + + if (context.IPREG == NULL) + { + return; + } + + count++; + push_back(context.IPREG); + + DWORD architecture = X86X64ARCHITECTURE; + + // Get the required values for initialization of the STACKFRAME64 structure + // to be passed to StackWalk64(). Required fields are AddrPC and AddrFrame. + CONTEXT currentContext; + memset(¤tContext, 0, sizeof(currentContext)); + currentContext.SPREG = context.SPREG; + currentContext.BPREG = context.BPREG; + currentContext.IPREG = context.IPREG; + + // Initialize the STACKFRAME64 structure. + STACKFRAME64 frame; + memset(&frame, 0x0, sizeof(frame)); + frame.AddrPC.Offset = currentContext.IPREG; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrStack.Offset = currentContext.SPREG; + frame.AddrStack.Mode = AddrModeFlat; + frame.AddrFrame.Offset = currentContext.BPREG; + frame.AddrFrame.Mode = AddrModeFlat; + frame.Virtual = TRUE; + + CriticalSectionLocker<> cs(g_heapMapLock); + CriticalSectionLocker locker(g_DbgHelp); + + // Walk the stack. + while (count < maxdepth) { + count++; + DbgTrace(L"dbghelp32.dll %i: StackWalk64\n", GetCurrentThreadId()); + if (!g_DbgHelp.StackWalk64(architecture, g_currentProcess, g_currentThread, &frame, ¤tContext, NULL, + SymFunctionTableAccess64, SymGetModuleBase64, NULL, locker)) { + // Couldn't trace back through any more frames. + break; + } + if (frame.AddrFrame.Offset == 0) { + // End of stack. + break; + } + + // Push this frame's program counter onto the CallStack. + push_back((UINT_PTR)frame.AddrPC.Offset); + } +} + +// getHashValue - Generate callstack hash value. +// +// Return Value: +// +// None. +// +DWORD SafeCallStack::getHashValue() const +{ + DWORD hashcode = 0xD202EF8D; + + // Iterate through each frame in the call stack. + for (UINT32 frame = 0; frame < m_size; frame++) { + UINT_PTR programcounter = (*this)[frame]; + hashcode = CalculateCRC32(programcounter, hashcode); + } + return hashcode; +} diff --git a/src/tests/static_string_test/static_string.h b/src/tests/static_string_test/static_string.h new file mode 100644 index 00000000..f1887555 --- /dev/null +++ b/src/tests/static_string_test/static_string.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace my_string +{ + const std::string the_string("foobar"); +} diff --git a/src/tests/static_string_test/static_string_test.cpp b/src/tests/static_string_test/static_string_test.cpp new file mode 100644 index 00000000..af46b69c --- /dev/null +++ b/src/tests/static_string_test/static_string_test.cpp @@ -0,0 +1,32 @@ +// static_string_test.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include "vld.h" +#include "static_string.h" + +void access_string() +{ + // Just do something with the string so it isn't optimized away + std::string copied_string = my_string::the_string; + printf("Copied string %s\n", copied_string.c_str()); +} + +int main(int argc, char **argv) +{ + access_string(); + + int leaks = static_cast(VLDGetLeaksCount()); + if (0 != leaks) + { + printf("!!! FAILED - Leaks detected: %i\n", leaks); + VLDReportLeaks(); + } + else + { + printf("PASSED\n"); + } + + + return leaks; +} diff --git a/src/tests/static_string_test/static_string_test.vcxproj b/src/tests/static_string_test/static_string_test.vcxproj new file mode 100644 index 00000000..ab508bec --- /dev/null +++ b/src/tests/static_string_test/static_string_test.vcxproj @@ -0,0 +1,343 @@ + + + + + Debug(Release)_StaticCrt + Win32 + + + Debug(Release)_StaticCrt + x64 + + + Debug(Release) + Win32 + + + Debug(Release) + x64 + + + Debug_StaticCrt + Win32 + + + Debug_StaticCrt + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release_StaticCrt + Win32 + + + Release_StaticCrt + x64 + + + Release + Win32 + + + Release + x64 + + + + {530901ED-6D5A-4BCF-9925-66F5DD51C610} + Win32Proj + static_string_test + static_string_test + 7.0 + + + + Application + Unicode + v140_xp + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + false + true + + + false + true + + + false + true + + + false + true + + + + + + + + + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ProgramDatabase + + + Console + true + + + + + Use + Level3 + Disabled + STATIC_CRT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ProgramDatabase + MultiThreadedDebug + + + Console + true + + + + + Use + Level3 + Disabled + ProgramDatabase + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Use + Level3 + Disabled + STATIC_CRT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ProgramDatabase + MultiThreadedDebug + + + Console + true + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ProgramDatabase + + + Console + true + + + + + Use + Level3 + Disabled + STATIC_CRT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ProgramDatabase + MultiThreadedDebug + + + Console + true + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ProgramDatabase + + + Console + true + + + + + Use + Level3 + Disabled + STATIC_CRT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ProgramDatabase + MultiThreadedDebug + + + Console + true + + + + + Level3 + Use + MaxSpeed + true + true + VLD_FORCE_ENABLE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + Level3 + Use + MaxSpeed + true + true + STATIC_CRT;VLD_FORCE_ENABLE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Console + true + true + true + + + + + Level3 + Use + MaxSpeed + true + true + VLD_FORCE_ENABLE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + Level3 + Use + MaxSpeed + true + true + STATIC_CRT;VLD_FORCE_ENABLE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Console + true + true + true + + + + + + + + + + + Create + + + + + {c8f6c172-56f2-4e76-b5fa-c3b423b31be7} + + + + + + \ No newline at end of file diff --git a/src/tests/static_string_test/static_string_test.vcxproj.filters b/src/tests/static_string_test/static_string_test.vcxproj.filters new file mode 100644 index 00000000..2f7606fc --- /dev/null +++ b/src/tests/static_string_test/static_string_test.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/src/tests/static_string_test/stdafx.cpp b/src/tests/static_string_test/stdafx.cpp new file mode 100644 index 00000000..27f0ee01 --- /dev/null +++ b/src/tests/static_string_test/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// basics.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/src/tests/static_string_test/stdafx.h b/src/tests/static_string_test/stdafx.h new file mode 100644 index 00000000..b005a839 --- /dev/null +++ b/src/tests/static_string_test/stdafx.h @@ -0,0 +1,15 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/src/tests/static_string_test/targetver.h b/src/tests/static_string_test/targetver.h new file mode 100644 index 00000000..87c0086d --- /dev/null +++ b/src/tests/static_string_test/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/vld_vs14.sln b/vld_vs14.sln index cbd2e466..acc17b6d 100644 --- a/vld_vs14.sln +++ b/vld_vs14.sln @@ -1,498 +1,525 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld", "src\vld.vcxproj", "{0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_basics", "src\tests\basics\basics.vcxproj", "{0943354A-41E0-4215-878A-8D0FE758052C}" - ProjectSection(ProjectDependencies) = postProject - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsuite", "src\tests\suite\testsuite.vcxproj", "{EE4A829C-5FD8-460B-8A90-B518B9BABB70}" - ProjectSection(ProjectDependencies) = postProject - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dynamic", "src\tests\dynamic_dll\dynamic.vcxproj", "{3AEA2AAF-3E9B-466F-B361-560B95AD88B4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dynamic_app", "src\tests\dynamic_app\dynamic_app.vcxproj", "{5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}" - ProjectSection(ProjectDependencies) = postProject - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4} = {3AEA2AAF-3E9B-466F-B361-560B95AD88B4} - {2178E5B2-1032-441F-A664-F3D8D1FD1913} = {2178E5B2-1032-441F-A664-F3D8D1FD1913} - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_mfc", "src\tests\mfc_dll\mfc.vcxproj", "{2178E5B2-1032-441F-A664-F3D8D1FD1913}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vldmfc", "src\tests\mfc\vldmfc.vcxproj", "{A231973E-072A-428E-982E-5363ADD1CDE2}" - ProjectSection(ProjectDependencies) = postProject - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "corruption", "src\tests\corruption\corruption.vcxproj", "{87911ED6-84BC-4526-9654-A4FF4E0EDF52}" - ProjectSection(ProjectDependencies) = postProject - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{281D5ACB-9ED2-496B-B19E-A75F4D4DA111}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgtest", "lib\gtest\msvc\gtest.vcxproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libs", "Libs", "{9FD1911C-3FAB-48DE-BE31-9F2C7B1EB58C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libformat", "lib\cppformat\format.vcxproj", "{4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld_main", "src\tests\vld_main\vld_main_vs14.vcxproj", "{8C732490-DC1A-40C0-923F-1555B9141B80}" - ProjectSection(ProjectDependencies) = postProject - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld_unload", "src\tests\vld_unload\vld_unload_vs14.vcxproj", "{A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}" - ProjectSection(ProjectDependencies) = postProject - {50C94B05-8C3E-49ED-B2B9-5715EB624D14} = {50C94B05-8C3E-49ED-B2B9-5715EB624D14} - {33F98E06-F44C-4E22-9E16-4C20F8238A95} = {33F98E06-F44C-4E22-9E16-4C20F8238A95} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld_dll1", "src\tests\vld_dll1\vld_dll1_vs14.vcxproj", "{50C94B05-8C3E-49ED-B2B9-5715EB624D14}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld_dll2", "src\tests\vld_dll2\vld_dll2_vs14.vcxproj", "{33F98E06-F44C-4E22-9E16-4C20F8238A95}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ComTest", "src\tests\vld_ComTest\ComTest_vs14.vcxproj", "{3719F504-3DF0-45F8-BC7A-4415804AC7C9}" - ProjectSection(ProjectDependencies) = postProject - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld_main_test", "src\tests\vld_main_test\vld_main_test_vs14.vcxproj", "{BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}" - ProjectSection(ProjectDependencies) = postProject - {8C732490-DC1A-40C0-923F-1555B9141B80} = {8C732490-DC1A-40C0-923F-1555B9141B80} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug_StaticCrt|Win32 = Debug_StaticCrt|Win32 - Debug_StaticCrt|x64 = Debug_StaticCrt|x64 - Debug_VldRelease_StaticCrt|Win32 = Debug_VldRelease_StaticCrt|Win32 - Debug_VldRelease_StaticCrt|x64 = Debug_VldRelease_StaticCrt|x64 - Debug_VldRelease|Win32 = Debug_VldRelease|Win32 - Debug_VldRelease|x64 = Debug_VldRelease|x64 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release_StaticCrt|Win32 = Release_StaticCrt|Win32 - Release_StaticCrt|x64 = Release_StaticCrt|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_StaticCrt|Win32.ActiveCfg = Debug|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_StaticCrt|Win32.Build.0 = Debug|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_StaticCrt|x64.ActiveCfg = Debug|x64 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_StaticCrt|x64.Build.0 = Debug|x64 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Release|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Release|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Release|x64 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease_StaticCrt|x64.Build.0 = Release|x64 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease|Win32.ActiveCfg = Release|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease|Win32.Build.0 = Release|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease|x64.ActiveCfg = Release|x64 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease|x64.Build.0 = Release|x64 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug|Win32.ActiveCfg = Debug|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug|Win32.Build.0 = Debug|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug|x64.ActiveCfg = Debug|x64 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug|x64.Build.0 = Debug|x64 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release_StaticCrt|Win32.ActiveCfg = Release|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release_StaticCrt|Win32.Build.0 = Release|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release_StaticCrt|x64.ActiveCfg = Release|x64 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release_StaticCrt|x64.Build.0 = Release|x64 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release|Win32.ActiveCfg = Release|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release|Win32.Build.0 = Release|Win32 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release|x64.ActiveCfg = Release|x64 - {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release|x64.Build.0 = Release|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug|Win32.ActiveCfg = Debug|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug|Win32.Build.0 = Debug|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug|x64.ActiveCfg = Debug|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Debug|x64.Build.0 = Debug|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Release|Win32.ActiveCfg = Release|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Release|Win32.Build.0 = Release|Win32 - {0943354A-41E0-4215-878A-8D0FE758052C}.Release|x64.ActiveCfg = Release|x64 - {0943354A-41E0-4215-878A-8D0FE758052C}.Release|x64.Build.0 = Release|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_StaticCrt|x64.Deploy.0 = Debug_StaticCrt|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug|Win32.ActiveCfg = Debug|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug|Win32.Build.0 = Debug|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug|x64.ActiveCfg = Debug|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug|x64.Build.0 = Debug|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release|Win32.ActiveCfg = Release|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release|Win32.Build.0 = Release|Win32 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release|x64.ActiveCfg = Release|x64 - {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release|x64.Build.0 = Release|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug|Win32.ActiveCfg = Debug|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug|Win32.Build.0 = Debug|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug|x64.ActiveCfg = Debug|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug|x64.Build.0 = Debug|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release|Win32.ActiveCfg = Release|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release|Win32.Build.0 = Release|Win32 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release|x64.ActiveCfg = Release|x64 - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release|x64.Build.0 = Release|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug|Win32.ActiveCfg = Debug|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug|Win32.Build.0 = Debug|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug|x64.ActiveCfg = Debug|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug|x64.Build.0 = Debug|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release|Win32.ActiveCfg = Release|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release|Win32.Build.0 = Release|Win32 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release|x64.ActiveCfg = Release|x64 - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release|x64.Build.0 = Release|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug|Win32.ActiveCfg = Debug|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug|Win32.Build.0 = Debug|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug|x64.ActiveCfg = Debug|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug|x64.Build.0 = Debug|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release|Win32.ActiveCfg = Release|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release|Win32.Build.0 = Release|Win32 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release|x64.ActiveCfg = Release|x64 - {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release|x64.Build.0 = Release|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease|Win32.ActiveCfg = Release|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease|Win32.Build.0 = Release|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease|x64.ActiveCfg = Release|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease|x64.Build.0 = Release|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug|Win32.ActiveCfg = Debug|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug|Win32.Build.0 = Debug|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug|x64.ActiveCfg = Debug|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug|x64.Build.0 = Debug|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Release|Win32.ActiveCfg = Release|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Release|Win32.Build.0 = Release|Win32 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Release|x64.ActiveCfg = Release|x64 - {A231973E-072A-428E-982E-5363ADD1CDE2}.Release|x64.Build.0 = Release|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug|Win32.ActiveCfg = Debug|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug|Win32.Build.0 = Debug|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug|x64.ActiveCfg = Debug|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug|x64.Build.0 = Debug|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release|Win32.ActiveCfg = Release|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release|Win32.Build.0 = Release|Win32 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release|x64.ActiveCfg = Release|x64 - {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release|x64.Build.0 = Release|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease|Win32.ActiveCfg = Debug|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease|Win32.Build.0 = Debug|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease|x64.ActiveCfg = Debug|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease|x64.Build.0 = Debug|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.ActiveCfg = Debug|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.Build.0 = Debug|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|x64.ActiveCfg = Debug|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|x64.Build.0 = Debug|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.ActiveCfg = Release|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.Build.0 = Release|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|x64.ActiveCfg = Release|x64 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|x64.Build.0 = Release|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_StaticCrt|Win32.ActiveCfg = Debug|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_StaticCrt|Win32.Build.0 = Debug|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_StaticCrt|x64.ActiveCfg = Debug|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_StaticCrt|x64.Build.0 = Debug|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Release|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Release|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Release|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease_StaticCrt|x64.Build.0 = Release|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease|Win32.ActiveCfg = Release|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease|Win32.Build.0 = Release|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease|x64.ActiveCfg = Release|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease|x64.Build.0 = Release|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug|Win32.ActiveCfg = Debug|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug|Win32.Build.0 = Debug|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug|x64.ActiveCfg = Debug|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug|x64.Build.0 = Debug|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release_StaticCrt|Win32.ActiveCfg = Release|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release_StaticCrt|Win32.Build.0 = Release|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release_StaticCrt|x64.ActiveCfg = Release|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release_StaticCrt|x64.Build.0 = Release|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release|Win32.ActiveCfg = Release|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release|Win32.Build.0 = Release|Win32 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release|x64.ActiveCfg = Release|x64 - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release|x64.Build.0 = Release|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug|Win32.ActiveCfg = Debug|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug|Win32.Build.0 = Debug|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug|x64.ActiveCfg = Debug|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug|x64.Build.0 = Debug|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Release|Win32.ActiveCfg = Release|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Release|Win32.Build.0 = Release|Win32 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Release|x64.ActiveCfg = Release|x64 - {8C732490-DC1A-40C0-923F-1555B9141B80}.Release|x64.Build.0 = Release|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug|Win32.ActiveCfg = Debug|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug|Win32.Build.0 = Debug|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug|x64.ActiveCfg = Debug|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug|x64.Build.0 = Debug|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release|Win32.ActiveCfg = Release|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release|Win32.Build.0 = Release|Win32 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release|x64.ActiveCfg = Release|x64 - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release|x64.Build.0 = Release|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug|Win32.ActiveCfg = Debug|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug|Win32.Build.0 = Debug|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug|x64.ActiveCfg = Debug|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug|x64.Build.0 = Debug|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release|Win32.ActiveCfg = Release|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release|Win32.Build.0 = Release|Win32 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release|x64.ActiveCfg = Release|x64 - {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release|x64.Build.0 = Release|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug|Win32.ActiveCfg = Debug|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug|Win32.Build.0 = Debug|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug|x64.ActiveCfg = Debug|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug|x64.Build.0 = Debug|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release|Win32.ActiveCfg = Release|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release|Win32.Build.0 = Release|Win32 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release|x64.ActiveCfg = Release|x64 - {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release|x64.Build.0 = Release|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug|Win32.ActiveCfg = Debug|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug|Win32.Build.0 = Debug|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug|x64.ActiveCfg = Debug|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug|x64.Build.0 = Debug|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release|Win32.ActiveCfg = Release|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release|Win32.Build.0 = Release|Win32 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release|x64.ActiveCfg = Release|x64 - {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release|x64.Build.0 = Release|x64 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug|Win32.ActiveCfg = Debug|Win32 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug|Win32.Build.0 = Debug|Win32 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug|x64.ActiveCfg = Debug|x64 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug|x64.Build.0 = Debug|x64 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release|Win32.ActiveCfg = Release|Win32 - {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 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {0943354A-41E0-4215-878A-8D0FE758052C} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} - {EE4A829C-5FD8-460B-8A90-B518B9BABB70} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} - {3AEA2AAF-3E9B-466F-B361-560B95AD88B4} = {281D5ACB-9ED2-496B-B19E-A75F4D4DA111} - {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} - {2178E5B2-1032-441F-A664-F3D8D1FD1913} = {281D5ACB-9ED2-496B-B19E-A75F4D4DA111} - {A231973E-072A-428E-982E-5363ADD1CDE2} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} - {87911ED6-84BC-4526-9654-A4FF4E0EDF52} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} - {281D5ACB-9ED2-496B-B19E-A75F4D4DA111} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {9FD1911C-3FAB-48DE-BE31-9F2C7B1EB58C} - {9FD1911C-3FAB-48DE-BE31-9F2C7B1EB58C} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} - {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17} = {9FD1911C-3FAB-48DE-BE31-9F2C7B1EB58C} - {8C732490-DC1A-40C0-923F-1555B9141B80} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} - {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} - {50C94B05-8C3E-49ED-B2B9-5715EB624D14} = {281D5ACB-9ED2-496B-B19E-A75F4D4DA111} - {33F98E06-F44C-4E22-9E16-4C20F8238A95} = {281D5ACB-9ED2-496B-B19E-A75F4D4DA111} - {3719F504-3DF0-45F8-BC7A-4415804AC7C9} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} - {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.24720.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld", "src\vld.vcxproj", "{0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_basics", "src\tests\basics\basics.vcxproj", "{0943354A-41E0-4215-878A-8D0FE758052C}" + ProjectSection(ProjectDependencies) = postProject + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsuite", "src\tests\suite\testsuite.vcxproj", "{EE4A829C-5FD8-460B-8A90-B518B9BABB70}" + ProjectSection(ProjectDependencies) = postProject + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dynamic", "src\tests\dynamic_dll\dynamic.vcxproj", "{3AEA2AAF-3E9B-466F-B361-560B95AD88B4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dynamic_app", "src\tests\dynamic_app\dynamic_app.vcxproj", "{5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}" + ProjectSection(ProjectDependencies) = postProject + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4} = {3AEA2AAF-3E9B-466F-B361-560B95AD88B4} + {2178E5B2-1032-441F-A664-F3D8D1FD1913} = {2178E5B2-1032-441F-A664-F3D8D1FD1913} + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_mfc", "src\tests\mfc_dll\mfc.vcxproj", "{2178E5B2-1032-441F-A664-F3D8D1FD1913}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vldmfc", "src\tests\mfc\vldmfc.vcxproj", "{A231973E-072A-428E-982E-5363ADD1CDE2}" + ProjectSection(ProjectDependencies) = postProject + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "corruption", "src\tests\corruption\corruption.vcxproj", "{87911ED6-84BC-4526-9654-A4FF4E0EDF52}" + ProjectSection(ProjectDependencies) = postProject + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{281D5ACB-9ED2-496B-B19E-A75F4D4DA111}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgtest", "lib\gtest\msvc\gtest.vcxproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libs", "Libs", "{9FD1911C-3FAB-48DE-BE31-9F2C7B1EB58C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libformat", "lib\cppformat\format.vcxproj", "{4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld_main", "src\tests\vld_main\vld_main_vs14.vcxproj", "{8C732490-DC1A-40C0-923F-1555B9141B80}" + ProjectSection(ProjectDependencies) = postProject + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld_unload", "src\tests\vld_unload\vld_unload_vs14.vcxproj", "{A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}" + ProjectSection(ProjectDependencies) = postProject + {50C94B05-8C3E-49ED-B2B9-5715EB624D14} = {50C94B05-8C3E-49ED-B2B9-5715EB624D14} + {33F98E06-F44C-4E22-9E16-4C20F8238A95} = {33F98E06-F44C-4E22-9E16-4C20F8238A95} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld_dll1", "src\tests\vld_dll1\vld_dll1_vs14.vcxproj", "{50C94B05-8C3E-49ED-B2B9-5715EB624D14}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld_dll2", "src\tests\vld_dll2\vld_dll2_vs14.vcxproj", "{33F98E06-F44C-4E22-9E16-4C20F8238A95}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ComTest", "src\tests\vld_ComTest\ComTest_vs14.vcxproj", "{3719F504-3DF0-45F8-BC7A-4415804AC7C9}" + ProjectSection(ProjectDependencies) = postProject + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} = {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vld_main_test", "src\tests\vld_main_test\vld_main_test_vs14.vcxproj", "{BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}" + ProjectSection(ProjectDependencies) = postProject + {8C732490-DC1A-40C0-923F-1555B9141B80} = {8C732490-DC1A-40C0-923F-1555B9141B80} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "static_string_test", "src\tests\static_string_test\static_string_test.vcxproj", "{530901ED-6D5A-4BCF-9925-66F5DD51C610}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_StaticCrt|Win32 = Debug_StaticCrt|Win32 + Debug_StaticCrt|x64 = Debug_StaticCrt|x64 + Debug_VldRelease_StaticCrt|Win32 = Debug_VldRelease_StaticCrt|Win32 + Debug_VldRelease_StaticCrt|x64 = Debug_VldRelease_StaticCrt|x64 + Debug_VldRelease|Win32 = Debug_VldRelease|Win32 + Debug_VldRelease|x64 = Debug_VldRelease|x64 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release_StaticCrt|Win32 = Release_StaticCrt|Win32 + Release_StaticCrt|x64 = Release_StaticCrt|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_StaticCrt|Win32.ActiveCfg = Debug|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_StaticCrt|Win32.Build.0 = Debug|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_StaticCrt|x64.ActiveCfg = Debug|x64 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_StaticCrt|x64.Build.0 = Debug|x64 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Release|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Release|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Release|x64 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease_StaticCrt|x64.Build.0 = Release|x64 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease|Win32.ActiveCfg = Release|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease|Win32.Build.0 = Release|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease|x64.ActiveCfg = Release|x64 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug_VldRelease|x64.Build.0 = Release|x64 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug|Win32.ActiveCfg = Debug|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug|Win32.Build.0 = Debug|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug|x64.ActiveCfg = Debug|x64 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Debug|x64.Build.0 = Debug|x64 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release_StaticCrt|Win32.ActiveCfg = Release|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release_StaticCrt|Win32.Build.0 = Release|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release_StaticCrt|x64.ActiveCfg = Release|x64 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release_StaticCrt|x64.Build.0 = Release|x64 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release|Win32.ActiveCfg = Release|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release|Win32.Build.0 = Release|Win32 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release|x64.ActiveCfg = Release|x64 + {0D30FFCB-45DA-4D2B-8E3C-81BC145BF2DE}.Release|x64.Build.0 = Release|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug|Win32.ActiveCfg = Debug|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug|Win32.Build.0 = Debug|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug|x64.ActiveCfg = Debug|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Debug|x64.Build.0 = Debug|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Release|Win32.ActiveCfg = Release|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Release|Win32.Build.0 = Release|Win32 + {0943354A-41E0-4215-878A-8D0FE758052C}.Release|x64.ActiveCfg = Release|x64 + {0943354A-41E0-4215-878A-8D0FE758052C}.Release|x64.Build.0 = Release|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_StaticCrt|x64.Deploy.0 = Debug_StaticCrt|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug|Win32.ActiveCfg = Debug|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug|Win32.Build.0 = Debug|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug|x64.ActiveCfg = Debug|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Debug|x64.Build.0 = Debug|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release|Win32.ActiveCfg = Release|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release|Win32.Build.0 = Release|Win32 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release|x64.ActiveCfg = Release|x64 + {EE4A829C-5FD8-460B-8A90-B518B9BABB70}.Release|x64.Build.0 = Release|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug|Win32.ActiveCfg = Debug|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug|Win32.Build.0 = Debug|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug|x64.ActiveCfg = Debug|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Debug|x64.Build.0 = Debug|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release|Win32.ActiveCfg = Release|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release|Win32.Build.0 = Release|Win32 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release|x64.ActiveCfg = Release|x64 + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4}.Release|x64.Build.0 = Release|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug|Win32.ActiveCfg = Debug|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug|Win32.Build.0 = Debug|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug|x64.ActiveCfg = Debug|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Debug|x64.Build.0 = Debug|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release|Win32.ActiveCfg = Release|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release|Win32.Build.0 = Release|Win32 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release|x64.ActiveCfg = Release|x64 + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA}.Release|x64.Build.0 = Release|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug|Win32.ActiveCfg = Debug|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug|Win32.Build.0 = Debug|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug|x64.ActiveCfg = Debug|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Debug|x64.Build.0 = Debug|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release|Win32.ActiveCfg = Release|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release|Win32.Build.0 = Release|Win32 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release|x64.ActiveCfg = Release|x64 + {2178E5B2-1032-441F-A664-F3D8D1FD1913}.Release|x64.Build.0 = Release|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease|Win32.ActiveCfg = Release|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease|Win32.Build.0 = Release|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease|x64.ActiveCfg = Release|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug_VldRelease|x64.Build.0 = Release|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug|Win32.ActiveCfg = Debug|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug|Win32.Build.0 = Debug|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug|x64.ActiveCfg = Debug|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Debug|x64.Build.0 = Debug|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Release|Win32.ActiveCfg = Release|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Release|Win32.Build.0 = Release|Win32 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Release|x64.ActiveCfg = Release|x64 + {A231973E-072A-428E-982E-5363ADD1CDE2}.Release|x64.Build.0 = Release|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug|Win32.ActiveCfg = Debug|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug|Win32.Build.0 = Debug|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug|x64.ActiveCfg = Debug|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Debug|x64.Build.0 = Debug|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release|Win32.ActiveCfg = Release|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release|Win32.Build.0 = Release|Win32 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release|x64.ActiveCfg = Release|x64 + {87911ED6-84BC-4526-9654-A4FF4E0EDF52}.Release|x64.Build.0 = Release|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease|Win32.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease|Win32.Build.0 = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease|x64.ActiveCfg = Debug|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug_VldRelease|x64.Build.0 = Debug|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.Build.0 = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|x64.ActiveCfg = Debug|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|x64.Build.0 = Debug|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.ActiveCfg = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.Build.0 = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|x64.ActiveCfg = Release|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|x64.Build.0 = Release|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_StaticCrt|Win32.ActiveCfg = Debug|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_StaticCrt|Win32.Build.0 = Debug|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_StaticCrt|x64.ActiveCfg = Debug|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_StaticCrt|x64.Build.0 = Debug|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Release|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Release|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Release|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease_StaticCrt|x64.Build.0 = Release|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease|Win32.ActiveCfg = Release|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease|Win32.Build.0 = Release|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease|x64.ActiveCfg = Release|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug_VldRelease|x64.Build.0 = Release|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug|Win32.ActiveCfg = Debug|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug|Win32.Build.0 = Debug|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug|x64.ActiveCfg = Debug|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Debug|x64.Build.0 = Debug|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release_StaticCrt|Win32.ActiveCfg = Release|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release_StaticCrt|Win32.Build.0 = Release|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release_StaticCrt|x64.ActiveCfg = Release|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release_StaticCrt|x64.Build.0 = Release|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release|Win32.ActiveCfg = Release|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release|Win32.Build.0 = Release|Win32 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release|x64.ActiveCfg = Release|x64 + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17}.Release|x64.Build.0 = Release|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug|Win32.ActiveCfg = Debug|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug|Win32.Build.0 = Debug|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug|x64.ActiveCfg = Debug|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Debug|x64.Build.0 = Debug|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Release|Win32.ActiveCfg = Release|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Release|Win32.Build.0 = Release|Win32 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Release|x64.ActiveCfg = Release|x64 + {8C732490-DC1A-40C0-923F-1555B9141B80}.Release|x64.Build.0 = Release|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug|Win32.ActiveCfg = Debug|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug|Win32.Build.0 = Debug|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug|x64.ActiveCfg = Debug|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Debug|x64.Build.0 = Debug|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release|Win32.ActiveCfg = Release|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release|Win32.Build.0 = Release|Win32 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release|x64.ActiveCfg = Release|x64 + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814}.Release|x64.Build.0 = Release|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug|Win32.ActiveCfg = Debug|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug|Win32.Build.0 = Debug|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug|x64.ActiveCfg = Debug|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Debug|x64.Build.0 = Debug|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release|Win32.ActiveCfg = Release|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release|Win32.Build.0 = Release|Win32 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release|x64.ActiveCfg = Release|x64 + {50C94B05-8C3E-49ED-B2B9-5715EB624D14}.Release|x64.Build.0 = Release|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug|Win32.ActiveCfg = Debug|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug|Win32.Build.0 = Debug|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug|x64.ActiveCfg = Debug|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Debug|x64.Build.0 = Debug|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release|Win32.ActiveCfg = Release|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release|Win32.Build.0 = Release|Win32 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release|x64.ActiveCfg = Release|x64 + {33F98E06-F44C-4E22-9E16-4C20F8238A95}.Release|x64.Build.0 = Release|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug|Win32.ActiveCfg = Debug|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug|Win32.Build.0 = Debug|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug|x64.ActiveCfg = Debug|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Debug|x64.Build.0 = Debug|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release|Win32.ActiveCfg = Release|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release|Win32.Build.0 = Release|Win32 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release|x64.ActiveCfg = Release|x64 + {3719F504-3DF0-45F8-BC7A-4415804AC7C9}.Release|x64.Build.0 = Release|x64 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_StaticCrt|Win32.ActiveCfg = Debug_StaticCrt|Win32 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_StaticCrt|Win32.Build.0 = Debug_StaticCrt|Win32 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_StaticCrt|x64.ActiveCfg = Debug_StaticCrt|x64 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_StaticCrt|x64.Build.0 = Debug_StaticCrt|x64 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Debug(Release)_StaticCrt|Win32 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Debug(Release)_StaticCrt|Win32 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Debug(Release)_StaticCrt|x64 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease_StaticCrt|x64.Build.0 = Debug(Release)_StaticCrt|x64 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease|Win32.ActiveCfg = Debug(Release)|Win32 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease|Win32.Build.0 = Debug(Release)|Win32 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease|x64.ActiveCfg = Debug(Release)|x64 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug_VldRelease|x64.Build.0 = Debug(Release)|x64 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug|Win32.ActiveCfg = Debug|Win32 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug|Win32.Build.0 = Debug|Win32 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug|x64.ActiveCfg = Debug|x64 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Debug|x64.Build.0 = Debug|x64 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release_StaticCrt|Win32.ActiveCfg = Release_StaticCrt|Win32 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release_StaticCrt|Win32.Build.0 = Release_StaticCrt|Win32 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release_StaticCrt|x64.ActiveCfg = Release_StaticCrt|x64 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release_StaticCrt|x64.Build.0 = Release_StaticCrt|x64 + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E}.Release|Win32.ActiveCfg = Release|Win32 + {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 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_StaticCrt|Win32.ActiveCfg = Debug|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_StaticCrt|Win32.Build.0 = Debug|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_StaticCrt|x64.ActiveCfg = Debug|x64 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_StaticCrt|x64.Build.0 = Debug|x64 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_VldRelease_StaticCrt|Win32.ActiveCfg = Release|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_VldRelease_StaticCrt|Win32.Build.0 = Release|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_VldRelease_StaticCrt|x64.ActiveCfg = Release|x64 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_VldRelease_StaticCrt|x64.Build.0 = Release|x64 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_VldRelease|Win32.ActiveCfg = Release|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_VldRelease|Win32.Build.0 = Release|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_VldRelease|x64.ActiveCfg = Release|x64 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug_VldRelease|x64.Build.0 = Release|x64 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug|Win32.ActiveCfg = Debug|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug|Win32.Build.0 = Debug|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug|x64.ActiveCfg = Debug|x64 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Debug|x64.Build.0 = Debug|x64 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Release_StaticCrt|Win32.ActiveCfg = Release|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Release_StaticCrt|Win32.Build.0 = Release|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Release_StaticCrt|x64.ActiveCfg = Release|x64 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Release_StaticCrt|x64.Build.0 = Release|x64 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Release|Win32.ActiveCfg = Release|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Release|Win32.Build.0 = Release|Win32 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Release|x64.ActiveCfg = Release|x64 + {530901ED-6D5A-4BCF-9925-66F5DD51C610}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {0943354A-41E0-4215-878A-8D0FE758052C} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + {EE4A829C-5FD8-460B-8A90-B518B9BABB70} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + {3AEA2AAF-3E9B-466F-B361-560B95AD88B4} = {281D5ACB-9ED2-496B-B19E-A75F4D4DA111} + {5C25E1C8-00CB-4E0A-9BEC-952F0A6E5DCA} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + {2178E5B2-1032-441F-A664-F3D8D1FD1913} = {281D5ACB-9ED2-496B-B19E-A75F4D4DA111} + {A231973E-072A-428E-982E-5363ADD1CDE2} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + {87911ED6-84BC-4526-9654-A4FF4E0EDF52} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + {281D5ACB-9ED2-496B-B19E-A75F4D4DA111} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {9FD1911C-3FAB-48DE-BE31-9F2C7B1EB58C} + {9FD1911C-3FAB-48DE-BE31-9F2C7B1EB58C} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + {4ADFD279-56C6-4B1D-BA9E-B815E81C1B17} = {9FD1911C-3FAB-48DE-BE31-9F2C7B1EB58C} + {8C732490-DC1A-40C0-923F-1555B9141B80} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + {A8EEDB38-1E5A-4D6E-A3E0-F15EF1F2E814} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + {50C94B05-8C3E-49ED-B2B9-5715EB624D14} = {281D5ACB-9ED2-496B-B19E-A75F4D4DA111} + {33F98E06-F44C-4E22-9E16-4C20F8238A95} = {281D5ACB-9ED2-496B-B19E-A75F4D4DA111} + {3719F504-3DF0-45F8-BC7A-4415804AC7C9} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + {BB99EDE9-D039-4169-B26B-6BFD93C6AF8E} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + {530901ED-6D5A-4BCF-9925-66F5DD51C610} = {9F9CFA3A-F154-4069-89E3-19BDC6BD3A7D} + EndGlobalSection +EndGlobal From 9575a42083d41e8d9cff292fa83c0ad7b4a894f3 Mon Sep 17 00:00:00 2001 From: Matt Durak Date: Thu, 31 Jan 2019 13:26:36 -0800 Subject: [PATCH 2/2] Fix formatting of file --- src/callstack.cpp | 1582 ++++++++++++++++++++++----------------------- 1 file changed, 791 insertions(+), 791 deletions(-) diff --git a/src/callstack.cpp b/src/callstack.cpp index b8971f3f..e51c570f 100644 --- a/src/callstack.cpp +++ b/src/callstack.cpp @@ -1,791 +1,791 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Visual Leak Detector - CallStack Class Implementations -// Copyright (c) 2005-2014 VLD Team -// -// 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. -// -//////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#define VLDBUILD -#include "callstack.h" // This class' header. -#include "utility.h" // Provides various utility functions. -#include "vldheap.h" // Provides internal new and delete operators. -#include "vldint.h" // Provides access to VLD internals. -#include "cppformat\format.h" - -// Imported global variables. -extern HANDLE g_currentProcess; -extern HANDLE g_currentThread; -extern CriticalSection g_heapMapLock; -extern VisualLeakDetector g_vld; -extern DbgHelp g_DbgHelp; - -// Helper function to compare the begin of a string with a substring -// -template -bool beginWith(const LPCWSTR filename, size_t len, wchar_t const (&substr)[N]) -{ - size_t count = N - 1; - return ((len >= count) && wcsncmp(filename, substr, count) == 0); -} - -// Helper function to compare the end of a string with a substring -// -template -bool endWith(const LPCWSTR filename, size_t len, wchar_t const (&substr)[N]) -{ - size_t count = N - 1; - return ((len >= count) && wcsncmp(filename + len - count, substr, count) == 0); -} - -// Constructor - Initializes the CallStack with an initial size of zero and one -// Chunk of capacity. -// -CallStack::CallStack () -{ - m_capacity = CALLSTACK_CHUNK_SIZE; - m_size = 0; - m_status = 0x0; - m_store.next = NULL; - m_topChunk = &m_store; - m_topIndex = 0; - m_resolved = NULL; - m_resolvedCapacity = 0; - m_resolvedLength = 0; -} - -// Destructor - Frees all memory allocated to the CallStack. -// -CallStack::~CallStack () -{ - CallStack::chunk_t *chunk = m_store.next; - CallStack::chunk_t *temp; - - while (chunk) { - temp = chunk; - chunk = temp->next; - delete temp; - } - - delete [] m_resolved; - - m_resolved = NULL; - m_resolvedCapacity = 0; - m_resolvedLength = 0; -} - -CallStack* CallStack::Create() -{ - CallStack* result = NULL; - if (g_vld.GetOptions() & VLD_OPT_SAFE_STACK_WALK) { - result = new SafeCallStack(); - } - else { - result = new FastCallStack(); - } - return result; -} - -// operator == - Equality operator. Compares the CallStack to another CallStack -// for equality. Two CallStacks are equal if they are the same size and if -// every frame in each is identical to the corresponding frame in the other. -// -// other (IN) - Reference to the CallStack to compare the current CallStack -// against for equality. -// -// Return Value: -// -// Returns true if the two CallStacks are equal. Otherwise returns false. -// -BOOL CallStack::operator == (const CallStack &other) const -{ - if (m_size != other.m_size) { - // They can't be equal if the sizes are different. - return FALSE; - } - - // Walk the chunk list and within each chunk walk the frames array until we - // either find a mismatch, or until we reach the end of the call stacks. - const CallStack::chunk_t *prevChunk = NULL; - const CallStack::chunk_t *chunk = &m_store; - const CallStack::chunk_t *otherChunk = &other.m_store; - while (prevChunk != m_topChunk) { - UINT32 size = (chunk == m_topChunk) ? m_topIndex : CALLSTACK_CHUNK_SIZE; - for (UINT32 index = 0; index < size; index++) { - if (chunk->frames[index] != otherChunk->frames[index]) { - // Found a mismatch. They are not equal. - return FALSE; - } - } - prevChunk = chunk; - chunk = chunk->next; - otherChunk = otherChunk->next; - } - - // Reached the end of the call stacks. They are equal. - return TRUE; -} - -// operator [] - Random access operator. Retrieves the frame at the specified -// index. -// -// Note: We give up a bit of efficiency here, in favor of efficiency of push -// operations. This is because walking of a CallStack is done infrequently -// (only if a leak is found), whereas pushing is done very frequently (for -// each frame in the program's call stack when the program allocates some -// memory). -// -// - index (IN): Specifies the index of the frame to retrieve. -// -// Return Value: -// -// Returns the program counter for the frame at the specified index. If the -// specified index is out of range for the CallStack, the return value is -// undefined. -// -UINT_PTR CallStack::operator [] (UINT32 index) const -{ - UINT32 chunknumber = index / CALLSTACK_CHUNK_SIZE; - const CallStack::chunk_t *chunk = &m_store; - - for (UINT32 count = 0; count < chunknumber; count++) { - chunk = chunk->next; - } - - return chunk->frames[index % CALLSTACK_CHUNK_SIZE]; -} - -// clear - Resets the CallStack, returning it to a state where no frames have -// been pushed onto it, readying it for reuse. -// -// Note: Calling this function does not release any memory allocated to the -// CallStack. We give up a bit of memory-usage efficiency here in favor of -// performance of push operations. -// -// Return Value: -// -// None. -// -VOID CallStack::clear () -{ - m_size = 0; - m_topChunk = &m_store; - m_topIndex = 0; - if (m_resolved) - { - delete [] m_resolved; - m_resolved = NULL; - } - m_resolvedCapacity = 0; - m_resolvedLength = 0; -} - -LPCWSTR CallStack::getFunctionName(SIZE_T programCounter, DWORD64& displacement64, - SYMBOL_INFO* functionInfo, CriticalSectionLocker& locker) const -{ - // Initialize structures passed to the symbol handler. - functionInfo->SizeOfStruct = sizeof(SYMBOL_INFO); - functionInfo->MaxNameLen = MAX_SYMBOL_NAME_LENGTH; - - // Try to get the name of the function containing this program - // counter address. - displacement64 = 0; - LPCWSTR functionName; - DbgTrace(L"dbghelp32.dll %i: SymFromAddrW\n", GetCurrentThreadId()); - if (g_DbgHelp.SymFromAddrW(g_currentProcess, programCounter, &displacement64, functionInfo, locker)) { - functionName = functionInfo->Name; - } - else { - // GetFormattedMessage( GetLastError() ); - fmt::WArrayWriter wf(functionInfo->Name, MAX_SYMBOL_NAME_LENGTH); - wf.write(L"" ADDRESSCPPFORMAT, programCounter); - functionName = wf.c_str(); - displacement64 = 0; - } - return functionName; -} - -DWORD CallStack::resolveFunction(SIZE_T programCounter, IMAGEHLP_LINEW64* sourceInfo, DWORD displacement, - LPCWSTR functionName, LPWSTR stack_line, DWORD stackLineSize) const -{ - WCHAR callingModuleName[260]; - HMODULE hCallingModule = GetCallingModule(programCounter); - LPWSTR moduleName = L"(Module name unavailable)"; - if (hCallingModule && - GetModuleFileName(hCallingModule, callingModuleName, _countof(callingModuleName)) > 0) - { - moduleName = wcsrchr(callingModuleName, L'\\'); - if (moduleName == NULL) - moduleName = wcsrchr(callingModuleName, L'/'); - if (moduleName != NULL) - moduleName++; - else - moduleName = callingModuleName; - } - - fmt::WArrayWriter w(stack_line, stackLineSize); - // Display the current stack frame's information. - if (sourceInfo) - { - if (displacement == 0) - { - w.write(L" {} ({}): {}!{}()\n", - sourceInfo->FileName, sourceInfo->LineNumber, moduleName, - functionName); - } - else - { - w.write(L" {} ({}): {}!{}() + 0x{:X} bytes\n", - sourceInfo->FileName, sourceInfo->LineNumber, moduleName, - functionName, displacement); - } - } - else - { - if (displacement == 0) - { - w.write(L" {}!{}()\n", - moduleName, functionName); - } - else - { - w.write(L" {}!{}() + 0x{:X} bytes\n", - moduleName, functionName, displacement); - } - } - DWORD NumChars = (DWORD)w.size(); - stack_line[NumChars] = '\0'; - return NumChars; -} - - -// isCrtStartupAlloc - Determines whether the memory leak was generated from crt startup code. -// This is not an actual memory leaks as it is freed by crt after the VLD object has been destroyed. -// -// Return Value: -// -// true if isCrtStartupModule for any callstack frame returns true. -// -bool CallStack::isCrtStartupAlloc() -{ - if (m_status & CALLSTACK_STATUS_STARTUPCRT) { - return true; - } else if (m_status & CALLSTACK_STATUS_NOTSTARTUPCRT) { - return false; - } - - IMAGEHLP_LINE64 sourceInfo = { 0 }; - sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - - BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE] = { 0 }; - CriticalSectionLocker locker(g_DbgHelp); - - // Iterate through each frame in the call stack. - for (UINT32 frame = 0; frame < m_size; frame++) { - // Try to get the source file and line number associated with - // this program counter address. - SIZE_T programCounter = (*this)[frame]; - DWORD64 displacement64; - LPCWSTR functionName = getFunctionName(programCounter, displacement64, (SYMBOL_INFO*)&symbolBuffer, locker); - - m_status |= isCrtStartupFunction(functionName); - if (m_status & CALLSTACK_STATUS_STARTUPCRT) { - return true; - } else if (m_status & CALLSTACK_STATUS_NOTSTARTUPCRT) { - return false; - } - } - - m_status |= CALLSTACK_STATUS_NOTSTARTUPCRT; - return false; -} - - -// dump - Dumps a nicely formatted rendition of the CallStack, including -// symbolic information (function names and line numbers) if available. -// -// Note: The symbol handler must be initialized prior to calling this -// function. -// -// - showinternalframes (IN): If true, then all frames in the CallStack will be -// dumped. Otherwise, frames internal to the heap will not be dumped. -// -// Return Value: -// -// None. -// -void CallStack::dump(BOOL showInternalFrames) -{ - if (!m_resolved) { - resolve(showInternalFrames); - } - - // The stack was reoslved already - if (m_resolved) { - return Print(m_resolved); - } -} - -// Resolve - Creates a nicely formatted rendition of the CallStack, including -// symbolic information (function names and line numbers) if available. and -// saves it for later retrieval. -// -// Note: The symbol handler must be initialized prior to calling this -// function. -// -// - showInternalFrames (IN): If true, then all frames in the CallStack will be -// dumped. Otherwise, frames internal to the heap will not be dumped. -// -// Return Value: -// -// None. -// -int CallStack::resolve(BOOL showInternalFrames) -{ - if (m_resolved) - { - // already resolved, no need to do it again - // resolving twice may report an incorrect module for the stack frames - // if the memory was leaked in a dynamic library that was already unloaded. - return 0; - } - - if (m_status & CALLSTACK_STATUS_STARTUPCRT) { - // there is no need to resolve a leak that will not be reported - return 0; - } - - if (m_status & CALLSTACK_STATUS_INCOMPLETE) { - // This call stack appears to be incomplete. Using StackWalk64 may be - // more reliable. - Report(L" HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n" - L" in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n" - L" complete stack trace.\n"); - } - - int unresolvedFunctionsCount = 0; - IMAGEHLP_LINE64 sourceInfo = { 0 }; - sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - - bool skipStartupLeaks = !!(g_vld.GetOptions() & VLD_OPT_SKIP_CRTSTARTUP_LEAKS); - - // Use static here to increase performance, and avoid heap allocs. - // It's thread safe because of g_heapMapLock lock. - static WCHAR stack_line[MAXREPORTLENGTH + 1] = L""; - bool isPrevFrameInternal = false; - DWORD NumChars = 0; - CriticalSectionLocker locker(g_DbgHelp); - - const size_t max_line_length = MAXREPORTLENGTH + 1; - m_resolvedCapacity = m_size * max_line_length; - const size_t allocedBytes = m_resolvedCapacity * sizeof(WCHAR); - m_resolved = new WCHAR[m_resolvedCapacity]; - if (m_resolved) { - ZeroMemory(m_resolved, allocedBytes); - } - - // Iterate through each frame in the call stack. - for (UINT32 frame = 0; frame < m_size; frame++) - { - // Try to get the source file and line number associated with - // this program counter address. - SIZE_T programCounter = (*this)[frame]; - if (GetCallingModule(programCounter) == g_vld.m_vldBase) - continue; - - DWORD64 displacement64; - BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE]; - LPCWSTR functionName = getFunctionName(programCounter, displacement64, (SYMBOL_INFO*)&symbolBuffer, locker); - - if (skipStartupLeaks) { - if (!(m_status & (CALLSTACK_STATUS_STARTUPCRT | CALLSTACK_STATUS_NOTSTARTUPCRT))) { - m_status |= isCrtStartupFunction(functionName); - } - if (m_status & CALLSTACK_STATUS_STARTUPCRT) { - delete[] m_resolved; - m_resolved = NULL; - m_resolvedCapacity = 0; - m_resolvedLength = 0; - return 0; - } - } - - // It turns out that calls to SymGetLineFromAddrW64 may free the very memory we are scrutinizing here - // in this method. If this is the case, m_Resolved will be null after SymGetLineFromAddrW64 returns. - // When that happens there is nothing we can do except crash. - DWORD displacement = 0; - DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId()); - BOOL foundline = g_DbgHelp.SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo, locker); - - bool isFrameInternal = false; - if (foundline && !showInternalFrames) { - if (isInternalModule(sourceInfo.FileName)) { - // Don't show frames in files internal to the heap. - isFrameInternal = true; - } - } - - // show one allocation function for context - if (NumChars > 0 && !isFrameInternal && isPrevFrameInternal) { - m_resolvedLength += NumChars; - if (m_resolved) { - wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); - } - } - isPrevFrameInternal = isFrameInternal; - - if (!foundline) - displacement = (DWORD)displacement64; - NumChars = resolveFunction( programCounter, foundline ? &sourceInfo : NULL, - displacement, functionName, stack_line, _countof( stack_line )); - - if (NumChars > 0 && !isFrameInternal) { - m_resolvedLength += NumChars; - if (m_resolved) { - wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); - } - } - } // end for loop - - m_status |= CALLSTACK_STATUS_NOTSTARTUPCRT; - return unresolvedFunctionsCount; -} - -const WCHAR* CallStack::getResolvedCallstack( BOOL showinternalframes ) -{ - resolve(showinternalframes); - return m_resolved; -} - -// push_back - Pushes a frame's program counter onto the CallStack. Pushes are -// always appended to the back of the chunk list (aka the "top" chunk). -// -// Note: This function will allocate additional memory as necessary to make -// room for new program counter addresses. -// -// - programcounter (IN): The program counter address of the frame to be pushed -// onto the CallStack. -// -// Return Value: -// -// None. -// -VOID CallStack::push_back (const UINT_PTR programcounter) -{ - if (m_size == m_capacity) { - // At current capacity. Allocate additional storage. - CallStack::chunk_t *chunk = new CallStack::chunk_t; - chunk->next = NULL; - m_topChunk->next = chunk; - m_topChunk = chunk; - m_topIndex = 0; - m_capacity += CALLSTACK_CHUNK_SIZE; - } - else if (m_topIndex >= CALLSTACK_CHUNK_SIZE) { - // There is more capacity, but not in this chunk. Go to the next chunk. - // Note that this only happens if this CallStack has previously been - // cleared (clearing resets the data, but doesn't give up any allocated - // space). - m_topChunk = m_topChunk->next; - m_topIndex = 0; - } - - m_topChunk->frames[m_topIndex++] = programcounter; - m_size++; -} - -UINT CallStack::isCrtStartupFunction( LPCWSTR functionName ) const -{ - size_t len = wcslen(functionName); - - if (beginWith(functionName, len, L"_malloc_crt") - || beginWith(functionName, len, L"_calloc_crt") - || endWith(functionName, len, L"CRT_INIT") - || endWith(functionName, len, L"initterm_e") - || beginWith(functionName, len, L"_cinit") - || beginWith(functionName, len, L"std::`dynamic initializer for '") - // VS2008 Release - || (wcscmp(functionName, L"std::locale::facet::facet_Register") == 0) - // VS2010 Release - || (wcscmp(functionName, L"std::locale::facet::_Facet_Register") == 0) - // VS2012 Release - || beginWith(functionName, len, L"std::locale::_Init()") - || beginWith(functionName, len, L"std::basic_streambuf<") - // VS2015 - || beginWith(functionName, len, L"common_initialize_environment_nolock<") - || beginWith(functionName, len, L"common_configure_argv<") - || beginWith(functionName, len, L"__acrt_initialize") - || beginWith(functionName, len, L"__acrt_allocate_buffer_for_argv") - || beginWith(functionName, len, L"_register_onexit_function") - // VS2015 Release - || (wcscmp(functionName, L"setlocale") == 0) - || (wcscmp(functionName, L"_wsetlocale") == 0) - || (wcscmp(functionName, L"_Getctype") == 0) - || (wcscmp(functionName, L"std::_Facet_Register") == 0) - || endWith(functionName, len, L">::_Getcat") - // Fix - || endWith(functionName, len, L"initterm") - ) { - return CALLSTACK_STATUS_STARTUPCRT; - } - - if (endWith(functionName, len, L"DllMainCRTStartup") - || endWith(functionName, len, L"mainCRTStartup") - || beginWith(functionName, len, L"`dynamic initializer for '")) { - // When we reach this point there is no reason going further down the stack - return CALLSTACK_STATUS_NOTSTARTUPCRT; - } - - return NULL; -} - -bool CallStack::isInternalModule( const PWSTR filename ) const -{ - size_t len = wcslen(filename); - return - // VS2015 - endWith(filename, len, L"\\atlmfc\\include\\atlsimpstr.h") || - endWith(filename, len, L"\\atlmfc\\include\\cstringt.h") || - endWith(filename, len, L"\\atlmfc\\src\\mfc\\afxmem.cpp") || - endWith(filename, len, L"\\atlmfc\\src\\mfc\\strcore.cpp") || - endWith(filename, len, L"\\vcstartup\\src\\heap\\new_scalar.cpp") || - endWith(filename, len, L"\\vcstartup\\src\\heap\\new_array.cpp") || - endWith(filename, len, L"\\vcstartup\\src\\heap\\new_debug.cpp") || - endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\align.cpp") || - endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\malloc.cpp") || - endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\debug_heap.cpp") || - // VS2013 - beginWith(filename, len, L"f:\\dd\\vctools\\crt\\crtw32\\") || - //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgheap.c") || - //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgnew.cpp") || - //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgmalloc.c") || - //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgrealloc.c") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\new.cpp") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\new2.cpp") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\malloc.c") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\realloc.c") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\calloc.c") || - //endWith(filename, len, L"\\crt\\crtw32\\heap\\calloc_impl.c") || - //endWith(filename, len, L"\\crt\\crtw32\\string\\strdup.c") || - //endWith(filename, len, L"\\crt\\crtw32\\string\\wcsdup.c") || - // VS2010 - endWith(filename, len, L"\\crt\\src\\afxmem.cpp") || - endWith(filename, len, L"\\crt\\src\\dbgheap.c") || - endWith(filename, len, L"\\crt\\src\\dbgnew.cpp") || - endWith(filename, len, L"\\crt\\src\\dbgmalloc.c") || - endWith(filename, len, L"\\crt\\src\\dbgcalloc.c") || - endWith(filename, len, L"\\crt\\src\\dbgrealloc.c") || - endWith(filename, len, L"\\crt\\src\\dbgdel.cp") || - endWith(filename, len, L"\\crt\\src\\new.cpp") || - endWith(filename, len, L"\\crt\\src\\newaop.cpp") || - endWith(filename, len, L"\\crt\\src\\malloc.c") || - endWith(filename, len, L"\\crt\\src\\realloc.c") || - endWith(filename, len, L"\\crt\\src\\free.c") || - endWith(filename, len, L"\\crt\\src\\strdup.c") || - endWith(filename, len, L"\\crt\\src\\wcsdup.c") || - endWith(filename, len, L"\\vc\\include\\xmemory0") || - // default - (false); -} - -// getStackTrace - Traces the stack as far back as possible, or until 'maxdepth' -// frames have been traced. Populates the CallStack with one entry for each -// stack frame traced. -// -// Note: This function uses a very efficient method to walk the stack from -// frame to frame, so it is quite fast. However, unconventional stack frames -// (such as those created when frame pointer omission optimization is used) -// will not be successfully walked by this function and will cause the -// stack trace to terminate prematurely. -// -// - maxdepth (IN): Maximum number of frames to trace back. -// -// - framepointer (IN): Frame (base) pointer at which to begin the stack trace. -// If NULL, then the stack trace will begin at this function. -// -// Return Value: -// -// None. -// -VOID FastCallStack::getStackTrace (UINT32 maxdepth, const context_t& context) -{ - UINT32 count = 0; - UINT_PTR function = context.func; - if (function != NULL) - { - count++; - push_back(function); - } - -/*#if defined(_M_IX86) - UINT_PTR* framePointer = (UINT_PTR*)context.BPREG; - while (count < maxdepth) { - if (*framePointer < (UINT_PTR)framePointer) { - if (*framePointer == NULL) { - // Looks like we reached the end of the stack. - break; - } - else { - // Invalid frame pointer. Frame pointer addresses should always - // increase as we move up the stack. - m_status |= CALLSTACK_STATUS_INCOMPLETE; - break; - } - } - if (*framePointer & (sizeof(UINT_PTR*) - 1)) { - // Invalid frame pointer. Frame pointer addresses should always - // be aligned to the size of a pointer. This probably means that - // we've encountered a frame that was created by a module built with - // frame pointer omission (FPO) optimization turned on. - m_status |= CALLSTACK_STATUS_INCOMPLETE; - break; - } - if (IsBadReadPtr((UINT*)*framePointer, sizeof(UINT_PTR*))) { - // Bogus frame pointer. Again, this probably means that we've - // encountered a frame built with FPO optimization. - m_status |= CALLSTACK_STATUS_INCOMPLETE; - break; - } - count++; - push_back(*(framePointer + 1)); - framePointer = (UINT_PTR*)*framePointer; - } -#elif defined(_M_X64)*/ - UINT32 maxframes = min(62, maxdepth + 10); - UINT_PTR* myFrames = new UINT_PTR[maxframes]; - ZeroMemory(myFrames, sizeof(UINT_PTR) * maxframes); - ULONG BackTraceHash; - maxframes = RtlCaptureStackBackTrace(0, maxframes, reinterpret_cast(myFrames), &BackTraceHash); - m_hashValue = BackTraceHash; - UINT32 startIndex = 0; - while (count < maxframes) { - if (myFrames[count] == 0) - break; - if (myFrames[count] == context.fp) - startIndex = count; - count++; - } - count = startIndex; - while (count < maxframes) { - if (myFrames[count] == 0) - break; - push_back(myFrames[count]); - count++; - } - delete [] myFrames; -//#endif -} - -// getStackTrace - Traces the stack as far back as possible, or until 'maxdepth' -// frames have been traced. Populates the CallStack with one entry for each -// stack frame traced. -// -// Note: This function uses a documented Windows API to walk the stack. This -// API is supposed to be the most reliable way to walk the stack. It claims -// to be able to walk stack frames that do not follow the conventional stack -// frame layout. However, this robustness comes at a cost: it is *extremely* -// slow compared to walking frames by following frame (base) pointers. -// -// - maxdepth (IN): Maximum number of frames to trace back. -// -// - framepointer (IN): Frame (base) pointer at which to begin the stack trace. -// If NULL, then the stack trace will begin at this function. -// -// Return Value: -// -// None. -// -VOID SafeCallStack::getStackTrace (UINT32 maxdepth, const context_t& context) -{ - UINT32 count = 0; - UINT_PTR function = context.func; - if (function != NULL) - { - count++; - push_back(function); - } - - if (context.IPREG == NULL) - { - return; - } - - count++; - push_back(context.IPREG); - - DWORD architecture = X86X64ARCHITECTURE; - - // Get the required values for initialization of the STACKFRAME64 structure - // to be passed to StackWalk64(). Required fields are AddrPC and AddrFrame. - CONTEXT currentContext; - memset(¤tContext, 0, sizeof(currentContext)); - currentContext.SPREG = context.SPREG; - currentContext.BPREG = context.BPREG; - currentContext.IPREG = context.IPREG; - - // Initialize the STACKFRAME64 structure. - STACKFRAME64 frame; - memset(&frame, 0x0, sizeof(frame)); - frame.AddrPC.Offset = currentContext.IPREG; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrStack.Offset = currentContext.SPREG; - frame.AddrStack.Mode = AddrModeFlat; - frame.AddrFrame.Offset = currentContext.BPREG; - frame.AddrFrame.Mode = AddrModeFlat; - frame.Virtual = TRUE; - - CriticalSectionLocker<> cs(g_heapMapLock); - CriticalSectionLocker locker(g_DbgHelp); - - // Walk the stack. - while (count < maxdepth) { - count++; - DbgTrace(L"dbghelp32.dll %i: StackWalk64\n", GetCurrentThreadId()); - if (!g_DbgHelp.StackWalk64(architecture, g_currentProcess, g_currentThread, &frame, ¤tContext, NULL, - SymFunctionTableAccess64, SymGetModuleBase64, NULL, locker)) { - // Couldn't trace back through any more frames. - break; - } - if (frame.AddrFrame.Offset == 0) { - // End of stack. - break; - } - - // Push this frame's program counter onto the CallStack. - push_back((UINT_PTR)frame.AddrPC.Offset); - } -} - -// getHashValue - Generate callstack hash value. -// -// Return Value: -// -// None. -// -DWORD SafeCallStack::getHashValue() const -{ - DWORD hashcode = 0xD202EF8D; - - // Iterate through each frame in the call stack. - for (UINT32 frame = 0; frame < m_size; frame++) { - UINT_PTR programcounter = (*this)[frame]; - hashcode = CalculateCRC32(programcounter, hashcode); - } - return hashcode; -} +//////////////////////////////////////////////////////////////////////////////// +// +// Visual Leak Detector - CallStack Class Implementations +// Copyright (c) 2005-2014 VLD Team +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#define VLDBUILD +#include "callstack.h" // This class' header. +#include "utility.h" // Provides various utility functions. +#include "vldheap.h" // Provides internal new and delete operators. +#include "vldint.h" // Provides access to VLD internals. +#include "cppformat\format.h" + +// Imported global variables. +extern HANDLE g_currentProcess; +extern HANDLE g_currentThread; +extern CriticalSection g_heapMapLock; +extern VisualLeakDetector g_vld; +extern DbgHelp g_DbgHelp; + +// Helper function to compare the begin of a string with a substring +// +template +bool beginWith(const LPCWSTR filename, size_t len, wchar_t const (&substr)[N]) +{ + size_t count = N - 1; + return ((len >= count) && wcsncmp(filename, substr, count) == 0); +} + +// Helper function to compare the end of a string with a substring +// +template +bool endWith(const LPCWSTR filename, size_t len, wchar_t const (&substr)[N]) +{ + size_t count = N - 1; + return ((len >= count) && wcsncmp(filename + len - count, substr, count) == 0); +} + +// Constructor - Initializes the CallStack with an initial size of zero and one +// Chunk of capacity. +// +CallStack::CallStack () +{ + m_capacity = CALLSTACK_CHUNK_SIZE; + m_size = 0; + m_status = 0x0; + m_store.next = NULL; + m_topChunk = &m_store; + m_topIndex = 0; + m_resolved = NULL; + m_resolvedCapacity = 0; + m_resolvedLength = 0; +} + +// Destructor - Frees all memory allocated to the CallStack. +// +CallStack::~CallStack () +{ + CallStack::chunk_t *chunk = m_store.next; + CallStack::chunk_t *temp; + + while (chunk) { + temp = chunk; + chunk = temp->next; + delete temp; + } + + delete [] m_resolved; + + m_resolved = NULL; + m_resolvedCapacity = 0; + m_resolvedLength = 0; +} + +CallStack* CallStack::Create() +{ + CallStack* result = NULL; + if (g_vld.GetOptions() & VLD_OPT_SAFE_STACK_WALK) { + result = new SafeCallStack(); + } + else { + result = new FastCallStack(); + } + return result; +} + +// operator == - Equality operator. Compares the CallStack to another CallStack +// for equality. Two CallStacks are equal if they are the same size and if +// every frame in each is identical to the corresponding frame in the other. +// +// other (IN) - Reference to the CallStack to compare the current CallStack +// against for equality. +// +// Return Value: +// +// Returns true if the two CallStacks are equal. Otherwise returns false. +// +BOOL CallStack::operator == (const CallStack &other) const +{ + if (m_size != other.m_size) { + // They can't be equal if the sizes are different. + return FALSE; + } + + // Walk the chunk list and within each chunk walk the frames array until we + // either find a mismatch, or until we reach the end of the call stacks. + const CallStack::chunk_t *prevChunk = NULL; + const CallStack::chunk_t *chunk = &m_store; + const CallStack::chunk_t *otherChunk = &other.m_store; + while (prevChunk != m_topChunk) { + UINT32 size = (chunk == m_topChunk) ? m_topIndex : CALLSTACK_CHUNK_SIZE; + for (UINT32 index = 0; index < size; index++) { + if (chunk->frames[index] != otherChunk->frames[index]) { + // Found a mismatch. They are not equal. + return FALSE; + } + } + prevChunk = chunk; + chunk = chunk->next; + otherChunk = otherChunk->next; + } + + // Reached the end of the call stacks. They are equal. + return TRUE; +} + +// operator [] - Random access operator. Retrieves the frame at the specified +// index. +// +// Note: We give up a bit of efficiency here, in favor of efficiency of push +// operations. This is because walking of a CallStack is done infrequently +// (only if a leak is found), whereas pushing is done very frequently (for +// each frame in the program's call stack when the program allocates some +// memory). +// +// - index (IN): Specifies the index of the frame to retrieve. +// +// Return Value: +// +// Returns the program counter for the frame at the specified index. If the +// specified index is out of range for the CallStack, the return value is +// undefined. +// +UINT_PTR CallStack::operator [] (UINT32 index) const +{ + UINT32 chunknumber = index / CALLSTACK_CHUNK_SIZE; + const CallStack::chunk_t *chunk = &m_store; + + for (UINT32 count = 0; count < chunknumber; count++) { + chunk = chunk->next; + } + + return chunk->frames[index % CALLSTACK_CHUNK_SIZE]; +} + +// clear - Resets the CallStack, returning it to a state where no frames have +// been pushed onto it, readying it for reuse. +// +// Note: Calling this function does not release any memory allocated to the +// CallStack. We give up a bit of memory-usage efficiency here in favor of +// performance of push operations. +// +// Return Value: +// +// None. +// +VOID CallStack::clear () +{ + m_size = 0; + m_topChunk = &m_store; + m_topIndex = 0; + if (m_resolved) + { + delete [] m_resolved; + m_resolved = NULL; + } + m_resolvedCapacity = 0; + m_resolvedLength = 0; +} + +LPCWSTR CallStack::getFunctionName(SIZE_T programCounter, DWORD64& displacement64, + SYMBOL_INFO* functionInfo, CriticalSectionLocker& locker) const +{ + // Initialize structures passed to the symbol handler. + functionInfo->SizeOfStruct = sizeof(SYMBOL_INFO); + functionInfo->MaxNameLen = MAX_SYMBOL_NAME_LENGTH; + + // Try to get the name of the function containing this program + // counter address. + displacement64 = 0; + LPCWSTR functionName; + DbgTrace(L"dbghelp32.dll %i: SymFromAddrW\n", GetCurrentThreadId()); + if (g_DbgHelp.SymFromAddrW(g_currentProcess, programCounter, &displacement64, functionInfo, locker)) { + functionName = functionInfo->Name; + } + else { + // GetFormattedMessage( GetLastError() ); + fmt::WArrayWriter wf(functionInfo->Name, MAX_SYMBOL_NAME_LENGTH); + wf.write(L"" ADDRESSCPPFORMAT, programCounter); + functionName = wf.c_str(); + displacement64 = 0; + } + return functionName; +} + +DWORD CallStack::resolveFunction(SIZE_T programCounter, IMAGEHLP_LINEW64* sourceInfo, DWORD displacement, + LPCWSTR functionName, LPWSTR stack_line, DWORD stackLineSize) const +{ + WCHAR callingModuleName[260]; + HMODULE hCallingModule = GetCallingModule(programCounter); + LPWSTR moduleName = L"(Module name unavailable)"; + if (hCallingModule && + GetModuleFileName(hCallingModule, callingModuleName, _countof(callingModuleName)) > 0) + { + moduleName = wcsrchr(callingModuleName, L'\\'); + if (moduleName == NULL) + moduleName = wcsrchr(callingModuleName, L'/'); + if (moduleName != NULL) + moduleName++; + else + moduleName = callingModuleName; + } + + fmt::WArrayWriter w(stack_line, stackLineSize); + // Display the current stack frame's information. + if (sourceInfo) + { + if (displacement == 0) + { + w.write(L" {} ({}): {}!{}()\n", + sourceInfo->FileName, sourceInfo->LineNumber, moduleName, + functionName); + } + else + { + w.write(L" {} ({}): {}!{}() + 0x{:X} bytes\n", + sourceInfo->FileName, sourceInfo->LineNumber, moduleName, + functionName, displacement); + } + } + else + { + if (displacement == 0) + { + w.write(L" {}!{}()\n", + moduleName, functionName); + } + else + { + w.write(L" {}!{}() + 0x{:X} bytes\n", + moduleName, functionName, displacement); + } + } + DWORD NumChars = (DWORD)w.size(); + stack_line[NumChars] = '\0'; + return NumChars; +} + + +// isCrtStartupAlloc - Determines whether the memory leak was generated from crt startup code. +// This is not an actual memory leaks as it is freed by crt after the VLD object has been destroyed. +// +// Return Value: +// +// true if isCrtStartupModule for any callstack frame returns true. +// +bool CallStack::isCrtStartupAlloc() +{ + if (m_status & CALLSTACK_STATUS_STARTUPCRT) { + return true; + } else if (m_status & CALLSTACK_STATUS_NOTSTARTUPCRT) { + return false; + } + + IMAGEHLP_LINE64 sourceInfo = { 0 }; + sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE] = { 0 }; + CriticalSectionLocker locker(g_DbgHelp); + + // Iterate through each frame in the call stack. + for (UINT32 frame = 0; frame < m_size; frame++) { + // Try to get the source file and line number associated with + // this program counter address. + SIZE_T programCounter = (*this)[frame]; + DWORD64 displacement64; + LPCWSTR functionName = getFunctionName(programCounter, displacement64, (SYMBOL_INFO*)&symbolBuffer, locker); + + m_status |= isCrtStartupFunction(functionName); + if (m_status & CALLSTACK_STATUS_STARTUPCRT) { + return true; + } else if (m_status & CALLSTACK_STATUS_NOTSTARTUPCRT) { + return false; + } + } + + m_status |= CALLSTACK_STATUS_NOTSTARTUPCRT; + return false; +} + + +// dump - Dumps a nicely formatted rendition of the CallStack, including +// symbolic information (function names and line numbers) if available. +// +// Note: The symbol handler must be initialized prior to calling this +// function. +// +// - showinternalframes (IN): If true, then all frames in the CallStack will be +// dumped. Otherwise, frames internal to the heap will not be dumped. +// +// Return Value: +// +// None. +// +void CallStack::dump(BOOL showInternalFrames) +{ + if (!m_resolved) { + resolve(showInternalFrames); + } + + // The stack was reoslved already + if (m_resolved) { + return Print(m_resolved); + } +} + +// Resolve - Creates a nicely formatted rendition of the CallStack, including +// symbolic information (function names and line numbers) if available. and +// saves it for later retrieval. +// +// Note: The symbol handler must be initialized prior to calling this +// function. +// +// - showInternalFrames (IN): If true, then all frames in the CallStack will be +// dumped. Otherwise, frames internal to the heap will not be dumped. +// +// Return Value: +// +// None. +// +int CallStack::resolve(BOOL showInternalFrames) +{ + if (m_resolved) + { + // already resolved, no need to do it again + // resolving twice may report an incorrect module for the stack frames + // if the memory was leaked in a dynamic library that was already unloaded. + return 0; + } + + if (m_status & CALLSTACK_STATUS_STARTUPCRT) { + // there is no need to resolve a leak that will not be reported + return 0; + } + + if (m_status & CALLSTACK_STATUS_INCOMPLETE) { + // This call stack appears to be incomplete. Using StackWalk64 may be + // more reliable. + Report(L" HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n" + L" in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n" + L" complete stack trace.\n"); + } + + int unresolvedFunctionsCount = 0; + IMAGEHLP_LINE64 sourceInfo = { 0 }; + sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + bool skipStartupLeaks = !!(g_vld.GetOptions() & VLD_OPT_SKIP_CRTSTARTUP_LEAKS); + + // Use static here to increase performance, and avoid heap allocs. + // It's thread safe because of g_heapMapLock lock. + static WCHAR stack_line[MAXREPORTLENGTH + 1] = L""; + bool isPrevFrameInternal = false; + DWORD NumChars = 0; + CriticalSectionLocker locker(g_DbgHelp); + + const size_t max_line_length = MAXREPORTLENGTH + 1; + m_resolvedCapacity = m_size * max_line_length; + const size_t allocedBytes = m_resolvedCapacity * sizeof(WCHAR); + m_resolved = new WCHAR[m_resolvedCapacity]; + if (m_resolved) { + ZeroMemory(m_resolved, allocedBytes); + } + + // Iterate through each frame in the call stack. + for (UINT32 frame = 0; frame < m_size; frame++) + { + // Try to get the source file and line number associated with + // this program counter address. + SIZE_T programCounter = (*this)[frame]; + if (GetCallingModule(programCounter) == g_vld.m_vldBase) + continue; + + DWORD64 displacement64; + BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE]; + LPCWSTR functionName = getFunctionName(programCounter, displacement64, (SYMBOL_INFO*)&symbolBuffer, locker); + + if (skipStartupLeaks) { + if (!(m_status & (CALLSTACK_STATUS_STARTUPCRT | CALLSTACK_STATUS_NOTSTARTUPCRT))) { + m_status |= isCrtStartupFunction(functionName); + } + if (m_status & CALLSTACK_STATUS_STARTUPCRT) { + delete[] m_resolved; + m_resolved = NULL; + m_resolvedCapacity = 0; + m_resolvedLength = 0; + return 0; + } + } + + // It turns out that calls to SymGetLineFromAddrW64 may free the very memory we are scrutinizing here + // in this method. If this is the case, m_Resolved will be null after SymGetLineFromAddrW64 returns. + // When that happens there is nothing we can do except crash. + DWORD displacement = 0; + DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId()); + BOOL foundline = g_DbgHelp.SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo, locker); + + bool isFrameInternal = false; + if (foundline && !showInternalFrames) { + if (isInternalModule(sourceInfo.FileName)) { + // Don't show frames in files internal to the heap. + isFrameInternal = true; + } + } + + // show one allocation function for context + if (NumChars > 0 && !isFrameInternal && isPrevFrameInternal) { + m_resolvedLength += NumChars; + if (m_resolved) { + wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); + } + } + isPrevFrameInternal = isFrameInternal; + + if (!foundline) + displacement = (DWORD)displacement64; + NumChars = resolveFunction( programCounter, foundline ? &sourceInfo : NULL, + displacement, functionName, stack_line, _countof( stack_line )); + + if (NumChars > 0 && !isFrameInternal) { + m_resolvedLength += NumChars; + if (m_resolved) { + wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); + } + } + } // end for loop + + m_status |= CALLSTACK_STATUS_NOTSTARTUPCRT; + return unresolvedFunctionsCount; +} + +const WCHAR* CallStack::getResolvedCallstack( BOOL showinternalframes ) +{ + resolve(showinternalframes); + return m_resolved; +} + +// push_back - Pushes a frame's program counter onto the CallStack. Pushes are +// always appended to the back of the chunk list (aka the "top" chunk). +// +// Note: This function will allocate additional memory as necessary to make +// room for new program counter addresses. +// +// - programcounter (IN): The program counter address of the frame to be pushed +// onto the CallStack. +// +// Return Value: +// +// None. +// +VOID CallStack::push_back (const UINT_PTR programcounter) +{ + if (m_size == m_capacity) { + // At current capacity. Allocate additional storage. + CallStack::chunk_t *chunk = new CallStack::chunk_t; + chunk->next = NULL; + m_topChunk->next = chunk; + m_topChunk = chunk; + m_topIndex = 0; + m_capacity += CALLSTACK_CHUNK_SIZE; + } + else if (m_topIndex >= CALLSTACK_CHUNK_SIZE) { + // There is more capacity, but not in this chunk. Go to the next chunk. + // Note that this only happens if this CallStack has previously been + // cleared (clearing resets the data, but doesn't give up any allocated + // space). + m_topChunk = m_topChunk->next; + m_topIndex = 0; + } + + m_topChunk->frames[m_topIndex++] = programcounter; + m_size++; +} + +UINT CallStack::isCrtStartupFunction( LPCWSTR functionName ) const +{ + size_t len = wcslen(functionName); + + if (beginWith(functionName, len, L"_malloc_crt") + || beginWith(functionName, len, L"_calloc_crt") + || endWith(functionName, len, L"CRT_INIT") + || endWith(functionName, len, L"initterm_e") + || beginWith(functionName, len, L"_cinit") + || beginWith(functionName, len, L"std::`dynamic initializer for '") + // VS2008 Release + || (wcscmp(functionName, L"std::locale::facet::facet_Register") == 0) + // VS2010 Release + || (wcscmp(functionName, L"std::locale::facet::_Facet_Register") == 0) + // VS2012 Release + || beginWith(functionName, len, L"std::locale::_Init()") + || beginWith(functionName, len, L"std::basic_streambuf<") + // VS2015 + || beginWith(functionName, len, L"common_initialize_environment_nolock<") + || beginWith(functionName, len, L"common_configure_argv<") + || beginWith(functionName, len, L"__acrt_initialize") + || beginWith(functionName, len, L"__acrt_allocate_buffer_for_argv") + || beginWith(functionName, len, L"_register_onexit_function") + // VS2015 Release + || (wcscmp(functionName, L"setlocale") == 0) + || (wcscmp(functionName, L"_wsetlocale") == 0) + || (wcscmp(functionName, L"_Getctype") == 0) + || (wcscmp(functionName, L"std::_Facet_Register") == 0) + || endWith(functionName, len, L">::_Getcat") + // Fix + || endWith(functionName, len, L"initterm") + ) { + return CALLSTACK_STATUS_STARTUPCRT; + } + + if (endWith(functionName, len, L"DllMainCRTStartup") + || endWith(functionName, len, L"mainCRTStartup") + || beginWith(functionName, len, L"`dynamic initializer for '")) { + // When we reach this point there is no reason going further down the stack + return CALLSTACK_STATUS_NOTSTARTUPCRT; + } + + return NULL; +} + +bool CallStack::isInternalModule( const PWSTR filename ) const +{ + size_t len = wcslen(filename); + return + // VS2015 + endWith(filename, len, L"\\atlmfc\\include\\atlsimpstr.h") || + endWith(filename, len, L"\\atlmfc\\include\\cstringt.h") || + endWith(filename, len, L"\\atlmfc\\src\\mfc\\afxmem.cpp") || + endWith(filename, len, L"\\atlmfc\\src\\mfc\\strcore.cpp") || + endWith(filename, len, L"\\vcstartup\\src\\heap\\new_scalar.cpp") || + endWith(filename, len, L"\\vcstartup\\src\\heap\\new_array.cpp") || + endWith(filename, len, L"\\vcstartup\\src\\heap\\new_debug.cpp") || + endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\align.cpp") || + endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\malloc.cpp") || + endWith(filename, len, L"\\ucrt\\src\\appcrt\\heap\\debug_heap.cpp") || + // VS2013 + beginWith(filename, len, L"f:\\dd\\vctools\\crt\\crtw32\\") || + //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgheap.c") || + //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgnew.cpp") || + //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgmalloc.c") || + //endWith(filename, len, L"\\crt\\crtw32\\misc\\dbgrealloc.c") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\new.cpp") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\new2.cpp") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\malloc.c") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\realloc.c") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\calloc.c") || + //endWith(filename, len, L"\\crt\\crtw32\\heap\\calloc_impl.c") || + //endWith(filename, len, L"\\crt\\crtw32\\string\\strdup.c") || + //endWith(filename, len, L"\\crt\\crtw32\\string\\wcsdup.c") || + // VS2010 + endWith(filename, len, L"\\crt\\src\\afxmem.cpp") || + endWith(filename, len, L"\\crt\\src\\dbgheap.c") || + endWith(filename, len, L"\\crt\\src\\dbgnew.cpp") || + endWith(filename, len, L"\\crt\\src\\dbgmalloc.c") || + endWith(filename, len, L"\\crt\\src\\dbgcalloc.c") || + endWith(filename, len, L"\\crt\\src\\dbgrealloc.c") || + endWith(filename, len, L"\\crt\\src\\dbgdel.cp") || + endWith(filename, len, L"\\crt\\src\\new.cpp") || + endWith(filename, len, L"\\crt\\src\\newaop.cpp") || + endWith(filename, len, L"\\crt\\src\\malloc.c") || + endWith(filename, len, L"\\crt\\src\\realloc.c") || + endWith(filename, len, L"\\crt\\src\\free.c") || + endWith(filename, len, L"\\crt\\src\\strdup.c") || + endWith(filename, len, L"\\crt\\src\\wcsdup.c") || + endWith(filename, len, L"\\vc\\include\\xmemory0") || + // default + (false); +} + +// getStackTrace - Traces the stack as far back as possible, or until 'maxdepth' +// frames have been traced. Populates the CallStack with one entry for each +// stack frame traced. +// +// Note: This function uses a very efficient method to walk the stack from +// frame to frame, so it is quite fast. However, unconventional stack frames +// (such as those created when frame pointer omission optimization is used) +// will not be successfully walked by this function and will cause the +// stack trace to terminate prematurely. +// +// - maxdepth (IN): Maximum number of frames to trace back. +// +// - framepointer (IN): Frame (base) pointer at which to begin the stack trace. +// If NULL, then the stack trace will begin at this function. +// +// Return Value: +// +// None. +// +VOID FastCallStack::getStackTrace (UINT32 maxdepth, const context_t& context) +{ + UINT32 count = 0; + UINT_PTR function = context.func; + if (function != NULL) + { + count++; + push_back(function); + } + +/*#if defined(_M_IX86) + UINT_PTR* framePointer = (UINT_PTR*)context.BPREG; + while (count < maxdepth) { + if (*framePointer < (UINT_PTR)framePointer) { + if (*framePointer == NULL) { + // Looks like we reached the end of the stack. + break; + } + else { + // Invalid frame pointer. Frame pointer addresses should always + // increase as we move up the stack. + m_status |= CALLSTACK_STATUS_INCOMPLETE; + break; + } + } + if (*framePointer & (sizeof(UINT_PTR*) - 1)) { + // Invalid frame pointer. Frame pointer addresses should always + // be aligned to the size of a pointer. This probably means that + // we've encountered a frame that was created by a module built with + // frame pointer omission (FPO) optimization turned on. + m_status |= CALLSTACK_STATUS_INCOMPLETE; + break; + } + if (IsBadReadPtr((UINT*)*framePointer, sizeof(UINT_PTR*))) { + // Bogus frame pointer. Again, this probably means that we've + // encountered a frame built with FPO optimization. + m_status |= CALLSTACK_STATUS_INCOMPLETE; + break; + } + count++; + push_back(*(framePointer + 1)); + framePointer = (UINT_PTR*)*framePointer; + } +#elif defined(_M_X64)*/ + UINT32 maxframes = min(62, maxdepth + 10); + UINT_PTR* myFrames = new UINT_PTR[maxframes]; + ZeroMemory(myFrames, sizeof(UINT_PTR) * maxframes); + ULONG BackTraceHash; + maxframes = RtlCaptureStackBackTrace(0, maxframes, reinterpret_cast(myFrames), &BackTraceHash); + m_hashValue = BackTraceHash; + UINT32 startIndex = 0; + while (count < maxframes) { + if (myFrames[count] == 0) + break; + if (myFrames[count] == context.fp) + startIndex = count; + count++; + } + count = startIndex; + while (count < maxframes) { + if (myFrames[count] == 0) + break; + push_back(myFrames[count]); + count++; + } + delete [] myFrames; +//#endif +} + +// getStackTrace - Traces the stack as far back as possible, or until 'maxdepth' +// frames have been traced. Populates the CallStack with one entry for each +// stack frame traced. +// +// Note: This function uses a documented Windows API to walk the stack. This +// API is supposed to be the most reliable way to walk the stack. It claims +// to be able to walk stack frames that do not follow the conventional stack +// frame layout. However, this robustness comes at a cost: it is *extremely* +// slow compared to walking frames by following frame (base) pointers. +// +// - maxdepth (IN): Maximum number of frames to trace back. +// +// - framepointer (IN): Frame (base) pointer at which to begin the stack trace. +// If NULL, then the stack trace will begin at this function. +// +// Return Value: +// +// None. +// +VOID SafeCallStack::getStackTrace (UINT32 maxdepth, const context_t& context) +{ + UINT32 count = 0; + UINT_PTR function = context.func; + if (function != NULL) + { + count++; + push_back(function); + } + + if (context.IPREG == NULL) + { + return; + } + + count++; + push_back(context.IPREG); + + DWORD architecture = X86X64ARCHITECTURE; + + // Get the required values for initialization of the STACKFRAME64 structure + // to be passed to StackWalk64(). Required fields are AddrPC and AddrFrame. + CONTEXT currentContext; + memset(¤tContext, 0, sizeof(currentContext)); + currentContext.SPREG = context.SPREG; + currentContext.BPREG = context.BPREG; + currentContext.IPREG = context.IPREG; + + // Initialize the STACKFRAME64 structure. + STACKFRAME64 frame; + memset(&frame, 0x0, sizeof(frame)); + frame.AddrPC.Offset = currentContext.IPREG; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrStack.Offset = currentContext.SPREG; + frame.AddrStack.Mode = AddrModeFlat; + frame.AddrFrame.Offset = currentContext.BPREG; + frame.AddrFrame.Mode = AddrModeFlat; + frame.Virtual = TRUE; + + CriticalSectionLocker<> cs(g_heapMapLock); + CriticalSectionLocker locker(g_DbgHelp); + + // Walk the stack. + while (count < maxdepth) { + count++; + DbgTrace(L"dbghelp32.dll %i: StackWalk64\n", GetCurrentThreadId()); + if (!g_DbgHelp.StackWalk64(architecture, g_currentProcess, g_currentThread, &frame, ¤tContext, NULL, + SymFunctionTableAccess64, SymGetModuleBase64, NULL, locker)) { + // Couldn't trace back through any more frames. + break; + } + if (frame.AddrFrame.Offset == 0) { + // End of stack. + break; + } + + // Push this frame's program counter onto the CallStack. + push_back((UINT_PTR)frame.AddrPC.Offset); + } +} + +// getHashValue - Generate callstack hash value. +// +// Return Value: +// +// None. +// +DWORD SafeCallStack::getHashValue() const +{ + DWORD hashcode = 0xD202EF8D; + + // Iterate through each frame in the call stack. + for (UINT32 frame = 0; frame < m_size; frame++) { + UINT_PTR programcounter = (*this)[frame]; + hashcode = CalculateCRC32(programcounter, hashcode); + } + return hashcode; +}