diff --git a/src/crtmfcpatch.h b/src/crtmfcpatch.h index 9064ab13..6320d11f 100644 --- a/src/crtmfcpatch.h +++ b/src/crtmfcpatch.h @@ -179,13 +179,16 @@ void* CrtPatch::crtd__calloc_dbg (size_t num, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _calloc_dbg_t pcrtxxd__calloc_dbg = (_calloc_dbg_t)data.pcrtd__calloc_dbg; assert(pcrtxxd__calloc_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__calloc_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__calloc_dbg); - return g_vld.__calloc_dbg(pcrtxxd__calloc_dbg, context, debug, num, size, type, file, line); + return pcrtxxd__calloc_dbg(num, size, type, file, line); } // crtd__malloc_dbg - Calls to _malloc_dbg from msvcrXXd.dll are patched @@ -210,13 +213,16 @@ void* CrtPatch::crtd__malloc_dbg (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _malloc_dbg_t pcrtxxd__malloc_dbg = (_malloc_dbg_t)data.pcrtd__malloc_dbg; assert(pcrtxxd__malloc_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__malloc_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__malloc_dbg); - return g_vld.__malloc_dbg(pcrtxxd__malloc_dbg, context, debug, size, type, file, line); + return pcrtxxd__malloc_dbg(size, type, file, line); } // crtd__realloc_dbg - Calls to _realloc_dbg from msvcrXXd.dll are patched @@ -244,13 +250,16 @@ void* CrtPatch::crtd__realloc_dbg (void *mem, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _realloc_dbg_t pcrtxxd__realloc_dbg = (_realloc_dbg_t)data.pcrtd__realloc_dbg; assert(pcrtxxd__realloc_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__realloc_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__realloc_dbg); - return g_vld.__realloc_dbg(pcrtxxd__realloc_dbg, context, debug, mem, size, type, file, line); + return pcrtxxd__realloc_dbg(mem, size, type, file, line); } // crtd__recalloc_dbg - Calls to _recalloc_dbg from msvcrXXd.dll are patched @@ -279,13 +288,16 @@ void* CrtPatch::crtd__recalloc_dbg (void *mem, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _recalloc_dbg_t pcrtxxd__recalloc_dbg = (_recalloc_dbg_t)data.pcrtd__recalloc_dbg; assert(pcrtxxd__recalloc_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__recalloc_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__recalloc_dbg); - return g_vld.__recalloc_dbg(pcrtxxd__recalloc_dbg, context, debug, mem, num, size, type, file, line); + return pcrtxxd__recalloc_dbg(mem, num, size, type, file, line); } @@ -295,13 +307,16 @@ char* CrtPatch::crtd__strdup_dbg (const char* src, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _strdup_dbg_t pcrtxxd__strdup_dbg = (_strdup_dbg_t)data.pcrtd__strdup_dbg; assert(pcrtxxd__strdup_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__strdup_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__strdup_dbg); - return g_vld.__strdup_dbg(pcrtxxd__strdup_dbg, context, debug, src, type, file, line); + return pcrtxxd__strdup_dbg(src, type, file, line); } @@ -311,13 +326,16 @@ wchar_t* CrtPatch::crtd__wcsdup_dbg (const wchar_t* src, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _wcsdup_dbg_t pcrtxxd__wcsdup_dbg = (_wcsdup_dbg_t)data.pcrtd__wcsdup_dbg; assert(pcrtxxd__wcsdup_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__wcsdup_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__wcsdup_dbg); - return g_vld.__wcsdup_dbg(pcrtxxd__wcsdup_dbg, context, debug, src, type, file, line); + return pcrtxxd__wcsdup_dbg(src, type, file, line); } // crtd__scalar_new_dbg - Calls to the CRT's debug scalar new operator from @@ -342,13 +360,16 @@ void* CrtPatch::crtd__scalar_new_dbg (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_dbg_crt_t pcrtxxd_new_dbg = (new_dbg_crt_t)data.pcrtd__scalar_new_dbg; assert(pcrtxxd_new_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_new_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_new_dbg); - return g_vld.__new_dbg_crt(pcrtxxd_new_dbg, context, debug, size, type, file, line); + return pcrtxxd_new_dbg(size, type, file, line); } // crtd__vector_new_dbg - Calls to the CRT's debug vector new operator from @@ -373,13 +394,16 @@ void* CrtPatch::crtd__vector_new_dbg (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_dbg_crt_t pcrtxxd_new_dbg = (new_dbg_crt_t)data.pcrtd__vector_new_dbg; assert(pcrtxxd_new_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_new_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_new_dbg); - return g_vld.__new_dbg_crt(pcrtxxd_new_dbg, context, debug, size, type, file, line); + return pcrtxxd_new_dbg(size, type, file, line); } // crtd_calloc - Calls to calloc from msvcrXXd.dll are patched through to @@ -398,13 +422,16 @@ void* CrtPatch::crtd__vector_new_dbg (size_t size, template void* CrtPatch::crtd_calloc (size_t num, size_t size) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif calloc_t pcrtxxd_calloc = (calloc_t)data.pcrtd_calloc; assert(pcrtxxd_calloc); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_calloc); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_calloc); - return g_vld._calloc(pcrtxxd_calloc, context, debug, num, size); + return pcrtxxd_calloc(num, size); } // crtd_malloc - Calls to malloc from msvcrXXd.dll are patched through to @@ -421,13 +448,16 @@ void* CrtPatch::crtd_calloc (size_t num, size_t size) template void* CrtPatch::crtd_malloc (size_t size) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif malloc_t pcrtxxd_malloc = (malloc_t)data.pcrtd_malloc; assert(pcrtxxd_malloc); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_malloc); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_malloc); - return g_vld._malloc(pcrtxxd_malloc, context, debug, size); + return pcrtxxd_malloc(size); } // crtd_realloc - Calls to realloc from msvcrXXd.dll are patched through to @@ -446,13 +476,16 @@ void* CrtPatch::crtd_malloc (size_t size) template void* CrtPatch::crtd_realloc (void *mem, size_t size) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif realloc_t pcrtxxd_realloc = (realloc_t)data.pcrtd_realloc; assert(pcrtxxd_realloc); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_realloc); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_realloc); - return g_vld._realloc(pcrtxxd_realloc, context, debug, mem, size); + return pcrtxxd_realloc(mem, size); } // crtd__recalloc - Calls to _recalloc from msvcrXXd.dll are patched through to @@ -471,38 +504,47 @@ void* CrtPatch::crtd_realloc (void *mem, size_t size) template void* CrtPatch::crtd__recalloc (void *mem, size_t num, size_t size) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _recalloc_t pcrtxxd_recalloc = (_recalloc_t)data.pcrtd_recalloc; assert(pcrtxxd_recalloc); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_recalloc); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_recalloc); - return g_vld.__recalloc(pcrtxxd_recalloc, context, debug, mem, num, size); + return pcrtxxd_recalloc(mem, num, size); } template char* CrtPatch::crtd__strdup (const char* src) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _strdup_t pcrtxxd_strdup = (_strdup_t)data.pcrtd__strdup; assert(pcrtxxd_strdup); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_strdup); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_strdup); - return g_vld.__strdup(pcrtxxd_strdup, context, debug, src); + return pcrtxxd_strdup(src); } template wchar_t* CrtPatch::crtd__wcsdup (const wchar_t* src) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _wcsdup_t pcrtxxd_wcsdup = (_wcsdup_t)data.pcrtd__wcsdup; assert(pcrtxxd_wcsdup); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_wcsdup); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_wcsdup); - return g_vld.__wcsdup(pcrtxxd_wcsdup, context, debug, src); + return pcrtxxd_wcsdup(src); } // crtd__aligned_malloc_dbg - Calls to _aligned_malloc_dbg from msvcrXXd.dll are patched @@ -528,13 +570,16 @@ void* CrtPatch::crtd__aligned_malloc_dbg (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_malloc_dbg_t pcrtxxd__aligned_malloc_dbg = (_aligned_malloc_dbg_t)data.pcrtd__aligned_malloc_dbg; assert(pcrtxxd__aligned_malloc_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__aligned_malloc_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__aligned_malloc_dbg); - return g_vld.__aligned_malloc_dbg(pcrtxxd__aligned_malloc_dbg, context, debug, size, alignment, type, file, line); + return pcrtxxd__aligned_malloc_dbg(size, alignment, type, file, line); } // crtd__aligned_offset_malloc_dbg - Calls to _aligned_offset_malloc_dbg from msvcrXXd.dll are patched @@ -561,13 +606,16 @@ void* CrtPatch::crtd__aligned_offset_malloc_dbg (size_t char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_offset_malloc_dbg_t pcrtxxd__malloc_dbg = (_aligned_offset_malloc_dbg_t)data.pcrtd__aligned_offset_malloc_dbg; assert(pcrtxxd__malloc_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__malloc_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__malloc_dbg); - return g_vld.__aligned_offset_malloc_dbg(pcrtxxd__malloc_dbg, context, debug, size, alignment, offset, type, file, line); + return pcrtxxd__malloc_dbg(size, alignment, offset, type, file, line); } // crtd__aligned_realloc_dbg - Calls to _aligned_realloc_dbg from msvcrXXd.dll are patched @@ -596,13 +644,16 @@ void* CrtPatch::crtd__aligned_realloc_dbg (void *mem, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_realloc_dbg_t pcrtxxd__realloc_dbg = (_aligned_realloc_dbg_t)data.pcrtd__aligned_realloc_dbg; assert(pcrtxxd__realloc_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__realloc_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__realloc_dbg); - return g_vld.__aligned_realloc_dbg(pcrtxxd__realloc_dbg, context, debug, mem, size, alignment, type, file, line); + return pcrtxxd__realloc_dbg(mem, size, alignment, type, file, line); } // crtd__aligned_offset_realloc_dbg - Calls to _aligned_offset_realloc_dbg from msvcrXXd.dll are patched @@ -632,13 +683,16 @@ void* CrtPatch::crtd__aligned_offset_realloc_dbg (void char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_offset_realloc_dbg_t pcrtxxd__realloc_dbg = (_aligned_offset_realloc_dbg_t)data.pcrtd__aligned_offset_realloc_dbg; assert(pcrtxxd__realloc_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__realloc_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__realloc_dbg); - return g_vld.__aligned_offset_realloc_dbg(pcrtxxd__realloc_dbg, context, debug, mem, size, alignment, offset, type, file, line); + return pcrtxxd__realloc_dbg(mem, size, alignment, offset, type, file, line); } // crtd__aligned_recalloc_dbg - Calls to _aligned_recalloc_dbg from msvcrXXd.dll are patched @@ -670,13 +724,16 @@ void* CrtPatch::crtd__aligned_recalloc_dbg (void *mem, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_recalloc_dbg_t pcrtxxd__recalloc_dbg = (_aligned_recalloc_dbg_t)data.pcrtd__aligned_recalloc_dbg; assert(pcrtxxd__recalloc_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__recalloc_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__recalloc_dbg); - return g_vld.__aligned_recalloc_dbg(pcrtxxd__recalloc_dbg, context, debug, mem, num, size, alignment, type, file, line); + return pcrtxxd__recalloc_dbg(mem, num, size, alignment, type, file, line); } // crtd__aligned_offset_recalloc_dbg - Calls to _aligned_offset_realloc_dbg from msvcrXXd.dll are patched @@ -709,13 +766,16 @@ void* CrtPatch::crtd__aligned_offset_recalloc_dbg (void char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_offset_recalloc_dbg_t pcrtxxd__recalloc_dbg = (_aligned_offset_recalloc_dbg_t)data.pcrtd__aligned_offset_recalloc_dbg; assert(pcrtxxd__recalloc_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd__recalloc_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd__recalloc_dbg); - return g_vld.__aligned_offset_recalloc_dbg(pcrtxxd__recalloc_dbg, context, debug, mem, num, size, alignment, offset, type, file, line); + return pcrtxxd__recalloc_dbg(mem, num, size, alignment, offset, type, file, line); } // crtd__aligned_malloc - Calls to malloc from msvcrXXd.dll are patched through to @@ -732,13 +792,16 @@ void* CrtPatch::crtd__aligned_offset_recalloc_dbg (void template void* CrtPatch::crtd__aligned_malloc (size_t size, size_t alignment) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_malloc_t pcrtxxd_malloc = (_aligned_malloc_t)data.pcrtd_aligned_malloc; assert(pcrtxxd_malloc); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_malloc); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_malloc); - return g_vld.__aligned_malloc(pcrtxxd_malloc, context, debug, size, alignment); + return pcrtxxd_malloc(size, alignment); } // crtd__aligned_offset_malloc - Calls to malloc from msvcrXXd.dll are patched through to @@ -755,13 +818,16 @@ void* CrtPatch::crtd__aligned_malloc (size_t size, size_t ali template void* CrtPatch::crtd__aligned_offset_malloc (size_t size, size_t alignment, size_t offset) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_offset_malloc_t pcrtxxd_malloc = (_aligned_offset_malloc_t)data.pcrtd_aligned_offset_malloc; assert(pcrtxxd_malloc); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_malloc); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_malloc); - return g_vld.__aligned_offset_malloc(pcrtxxd_malloc, context, debug, size, alignment, offset); + return pcrtxxd_malloc(size, alignment, offset); } // crtd__aligned_realloc - Calls to realloc from msvcrXXd.dll are patched through to @@ -780,13 +846,16 @@ void* CrtPatch::crtd__aligned_offset_malloc (size_t size, siz template void* CrtPatch::crtd__aligned_realloc (void *mem, size_t size, size_t alignment) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_realloc_t pcrtxxd_realloc = (_aligned_realloc_t)data.pcrtd_aligned_realloc; assert(pcrtxxd_realloc); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_realloc); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_realloc); - return g_vld.__aligned_realloc(pcrtxxd_realloc, context, debug, mem, size, alignment); + return pcrtxxd_realloc(mem, size, alignment); } // crtd__aligned_offset_realloc - Calls to realloc from msvcrXXd.dll are patched through to @@ -805,13 +874,16 @@ void* CrtPatch::crtd__aligned_realloc (void *mem, size_t size template void* CrtPatch::crtd__aligned_offset_realloc (void *mem, size_t size, size_t alignment, size_t offset) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_offset_realloc_t pcrtxxd_realloc = (_aligned_offset_realloc_t)data.pcrtd_aligned_offset_realloc; assert(pcrtxxd_realloc); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_realloc); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_realloc); - return g_vld.__aligned_offset_realloc(pcrtxxd_realloc, context, debug, mem, size, alignment, offset); + return pcrtxxd_realloc(mem, size, alignment, offset); } // crtd__aligned_recalloc - Calls to realloc from msvcrXXd.dll are patched through to @@ -832,13 +904,16 @@ void* CrtPatch::crtd__aligned_offset_realloc (void *mem, size template void* CrtPatch::crtd__aligned_recalloc (void *mem, size_t num, size_t size, size_t alignment) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_recalloc_t pcrtxxd_recalloc = (_aligned_recalloc_t)data.pcrtd_aligned_recalloc; assert(pcrtxxd_recalloc); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_recalloc); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_recalloc); - return g_vld.__aligned_recalloc(pcrtxxd_recalloc, context, debug, mem, num, size, alignment); + return pcrtxxd_recalloc(mem, num, size, alignment); } // crtd__aligned_offset_recalloc - Calls to realloc from msvcrXXd.dll are patched through to @@ -859,13 +934,16 @@ void* CrtPatch::crtd__aligned_recalloc (void *mem, size_t num template void* CrtPatch::crtd__aligned_offset_recalloc (void *mem, size_t num, size_t size, size_t alignment, size_t offset) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif _aligned_offset_recalloc_t pcrtxxd_recalloc = (_aligned_offset_recalloc_t)data.pcrtd_aligned_offset_recalloc; assert(pcrtxxd_recalloc); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_recalloc); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_recalloc); - return g_vld.__aligned_offset_recalloc(pcrtxxd_recalloc, context, debug, mem, num, size, alignment, offset); + return pcrtxxd_recalloc(mem, num, size, alignment, offset); } // crtd_scalar_new - Calls to the CRT's scalar new operator from msvcrXXd.dll @@ -880,13 +958,16 @@ void* CrtPatch::crtd__aligned_offset_recalloc (void *mem, siz template void* CrtPatch::crtd_scalar_new (size_t size) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_t pcrtxxd_scalar_new = (new_t)data.pcrtd_scalar_new; assert(pcrtxxd_scalar_new); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_scalar_new); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_scalar_new); - return g_vld._new(pcrtxxd_scalar_new, context, debug, size); + return pcrtxxd_scalar_new(size); } // crtd_vector_new - Calls to the CRT's vector new operator from msvcrXXd.dll @@ -901,13 +982,16 @@ void* CrtPatch::crtd_scalar_new (size_t size) template void* CrtPatch::crtd_vector_new (size_t size) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_t pcrtxxd_vector_new = (new_t)data.pcrtd_vector_new; assert(pcrtxxd_vector_new); context_t context; - CaptureContext cc(context, debug, (void*)pcrtxxd_vector_new); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pcrtxxd_vector_new); - return g_vld._new(pcrtxxd_vector_new, context, debug, size); + return pcrtxxd_vector_new(size); } //////////////////////////////////////////////////////////////////////////////// @@ -938,13 +1022,16 @@ void* MfcPatch::mfcd__scalar_new_dbg_4p (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_dbg_crt_t pmfcxxd__new_dbg = (new_dbg_crt_t)data.pmfcd__scalar_new_dbg_4p; assert(pmfcxxd__new_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd__new_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd__new_dbg); - return g_vld.__new_dbg_mfc(pmfcxxd__new_dbg, context, size, type, file, line); + return pmfcxxd__new_dbg(size, type, file, line); } // mfcd__scalar_new_dbg_3p - Calls to the MFC debug scalar new operator from @@ -966,13 +1053,16 @@ void* MfcPatch::mfcd__scalar_new_dbg_3p (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_dbg_mfc_t pmfcxxd__new_dbg = (new_dbg_mfc_t)data.pmfcd__scalar_new_dbg_3p; assert(pmfcxxd__new_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd__new_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd__new_dbg); - return g_vld.__new_dbg_mfc(pmfcxxd__new_dbg, context, size, file, line); + return pmfcxxd__new_dbg(size, file, line); } // mfcd__vector_new_dbg_4p - Calls to the MFC debug vector new operator from @@ -997,13 +1087,16 @@ void* MfcPatch::mfcd__vector_new_dbg_4p (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_dbg_crt_t pmfcxxd__new_dbg = (new_dbg_crt_t)data.pmfcd__vector_new_dbg_4p; assert(pmfcxxd__new_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd__new_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd__new_dbg); - return g_vld.__new_dbg_mfc(pmfcxxd__new_dbg, context, size, type, file, line); + return pmfcxxd__new_dbg(size, type, file, line); } // mfcd__vector_new_dbg_3p - Calls to the MFC debug vector new operator from @@ -1025,13 +1118,16 @@ void* MfcPatch::mfcd__vector_new_dbg_3p (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_dbg_mfc_t pmfcxxd__new_dbg = (new_dbg_mfc_t)data.pmfcd__vector_new_dbg_3p; assert(pmfcxxd__new_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd__new_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd__new_dbg); - return g_vld.__new_dbg_mfc(pmfcxxd__new_dbg, context, size, file, line); + return pmfcxxd__new_dbg(size, file, line); } // mfcd_scalar_new - Calls to the MFC scalar new operator from mfcXXd.dll are @@ -1046,13 +1142,16 @@ void* MfcPatch::mfcd__vector_new_dbg_3p (size_t size, template void* MfcPatch::mfcd_scalar_new (size_t size) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_t pmfcxxd_new = (new_t)data.pmfcd_scalar_new; assert(pmfcxxd_new); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd_new); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd_new); - return g_vld._new(pmfcxxd_new, context, debug, size); + return pmfcxxd_new(size); } // mfcd_vector_new - Calls to the MFC vector new operator from mfcXXd.dll are @@ -1067,13 +1166,16 @@ void* MfcPatch::mfcd_scalar_new (size_t size) template void* MfcPatch::mfcd_vector_new (size_t size) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_t pmfcxxd_new = (new_t)data.pmfcd_vector_new; assert(pmfcxxd_new); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd_new); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd_new); - return g_vld._new(pmfcxxd_new, context, debug, size); + return pmfcxxd_new(size); } // mfcud__scalar_new_dbg_4p - Calls to the MFC debug scalar new operator from @@ -1098,13 +1200,16 @@ void* MfcPatch::mfcud__scalar_new_dbg_4p (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_dbg_crt_t pmfcxxd__new_dbg = (new_dbg_crt_t)data.pmfcud__scalar_new_dbg_4p; assert(pmfcxxd__new_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd__new_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd__new_dbg); - return g_vld.__new_dbg_mfc(pmfcxxd__new_dbg, context, size, type, file, line); + return pmfcxxd__new_dbg(size, type, file, line); } // mfcud__scalar_new_dbg_3p - Calls to the MFC debug scalar new operator from @@ -1126,13 +1231,16 @@ void* MfcPatch::mfcud__scalar_new_dbg_3p (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_dbg_mfc_t pmfcxxd__new_dbg = (new_dbg_mfc_t)data.pmfcud__scalar_new_dbg_3p; assert(pmfcxxd__new_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd__new_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd__new_dbg); - return g_vld.__new_dbg_mfc(pmfcxxd__new_dbg, context, size, file, line); + return pmfcxxd__new_dbg(size, file, line); } // mfcud__vector_new_dbg_4p - Calls to the MFC debug vector new operator from @@ -1157,13 +1265,16 @@ void* MfcPatch::mfcud__vector_new_dbg_4p (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_dbg_crt_t pmfcxxd__new_dbg = (new_dbg_crt_t)data.pmfcud__vector_new_dbg_4p; assert(pmfcxxd__new_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd__new_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd__new_dbg); - return g_vld.__new_dbg_mfc(pmfcxxd__new_dbg, context, size, type, file, line); + return pmfcxxd__new_dbg(size, type, file, line); } // mfcud__vector_new_dbg_3p - Calls to the MFC debug vector new operator from @@ -1185,13 +1296,16 @@ void* MfcPatch::mfcud__vector_new_dbg_3p (size_t size, char const *file, int line) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_dbg_mfc_t pmfcxxd__new_dbg = (new_dbg_mfc_t)data.pmfcud__vector_new_dbg_3p; assert(pmfcxxd__new_dbg); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd__new_dbg); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd__new_dbg); - return g_vld.__new_dbg_mfc(pmfcxxd__new_dbg, context, size, file, line); + return pmfcxxd__new_dbg(size, file, line); } // mfcud_scalar_new - Calls to the MFC scalar new operator from mfcXXud.dll are @@ -1206,13 +1320,16 @@ void* MfcPatch::mfcud__vector_new_dbg_3p (size_t size, template void* MfcPatch::mfcud_scalar_new (size_t size) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_t pmfcxxd_new = (new_t)data.pmfcud_scalar_new; assert(pmfcxxd_new); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd_new); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd_new); - return g_vld._new(pmfcxxd_new, context, debug, size); + return pmfcxxd_new(size); } // mfcud_vector_new - Calls to the MFC vector new operator from mfcXXud.dll are @@ -1227,13 +1344,16 @@ void* MfcPatch::mfcud_scalar_new (size_t size) template void* MfcPatch::mfcud_vector_new (size_t size) { +#ifdef PRINTHOOKCALLS + DbgReport(_T(__FUNCTION__) _T("\n")); +#endif new_t pmfcxxd_new = (new_t)data.pmfcud_vector_new; assert(pmfcxxd_new); context_t context; - CaptureContext cc(context, debug, (void*)pmfcxxd_new); + CaptureContext cc(context, debug, (CRTVersion >= 140), (void*)pmfcxxd_new); - return g_vld._new(pmfcxxd_new, context, debug, size); + return pmfcxxd_new(size); } // Visual Studio 6.0 diff --git a/src/vld.cpp b/src/vld.cpp index cbb3ea32..14875157 100644 --- a/src/vld.cpp +++ b/src/vld.cpp @@ -1328,7 +1328,7 @@ tls_t* VisualLeakDetector::getTls () // // None. // -VOID VisualLeakDetector::mapBlock (HANDLE heap, LPCVOID mem, SIZE_T size, bool debugcrtalloc, DWORD threadId, blockinfo_t* &pblockInfo) +VOID VisualLeakDetector::mapBlock (HANDLE heap, LPCVOID mem, SIZE_T size, bool debugcrtalloc, bool ucrt, DWORD threadId, blockinfo_t* &pblockInfo) { CriticalSectionLocker<> cs(g_heapMapLock); @@ -1341,6 +1341,7 @@ VOID VisualLeakDetector::mapBlock (HANDLE heap, LPCVOID mem, SIZE_T size, bool d blockinfo->size = size; blockinfo->reported = false; blockinfo->debugCrtAlloc = debugcrtalloc; + blockinfo->ucrt = ucrt; if (SIZE_MAX - m_totalAlloc > size) m_totalAlloc += size; @@ -1543,7 +1544,7 @@ VOID VisualLeakDetector::unmapHeap (HANDLE heap) // None. // VOID VisualLeakDetector::remapBlock (HANDLE heap, LPCVOID mem, LPCVOID newmem, SIZE_T size, - bool debugcrtalloc, DWORD threadId, blockinfo_t* &pblockInfo, const context_t &context) + bool debugcrtalloc, bool ucrt, DWORD threadId, blockinfo_t* &pblockInfo, const context_t &context) { CriticalSectionLocker<> cs(g_heapMapLock); @@ -1551,7 +1552,7 @@ VOID VisualLeakDetector::remapBlock (HANDLE heap, LPCVOID mem, LPCVOID newmem, S // The block was not reallocated in-place. Instead the old block was // freed and a new block allocated to satisfy the new size. unmapBlock(heap, mem, context); - mapBlock(heap, newmem, size, debugcrtalloc, threadId, pblockInfo); + mapBlock(heap, newmem, size, debugcrtalloc, ucrt, threadId, pblockInfo); return; } @@ -1563,7 +1564,7 @@ VOID VisualLeakDetector::remapBlock (HANDLE heap, LPCVOID mem, LPCVOID newmem, S // block has also not been mapped to a blockinfo_t entry yet either, // so treat this reallocation as a brand-new allocation (this will // also map the heap to a new block map). - mapBlock(heap, newmem, size, debugcrtalloc, threadId, pblockInfo); + mapBlock(heap, newmem, size, debugcrtalloc, ucrt, threadId, pblockInfo); return; } @@ -1573,7 +1574,7 @@ VOID VisualLeakDetector::remapBlock (HANDLE heap, LPCVOID mem, LPCVOID newmem, S if (blockit == blockmap->end()) { // The block hasn't been mapped to a blockinfo_t entry yet. // Treat this reallocation as a new allocation. - mapBlock(heap, newmem, size, debugcrtalloc, threadId, pblockInfo); + mapBlock(heap, newmem, size, debugcrtalloc, ucrt, threadId, pblockInfo); return; } @@ -1661,6 +1662,32 @@ VOID VisualLeakDetector::reportConfig () } } +bool VisualLeakDetector::isDebugCrtAlloc( LPCVOID block, blockinfo_t* info ) +{ + // Autodetection allocations from statically linked CRT + if (!info->debugCrtAlloc) { + crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block; + SIZE_T nSize = sizeof(crtdbgblockheader_t) + crtheader->size + GAPSIZE; + int nValid = _CrtIsValidPointer(block, (unsigned int)info->size, TRUE); + if (_BLOCK_TYPE_IS_VALID(crtheader->use) && nValid && (nSize == info->size)) { + info->debugCrtAlloc = true; + info->ucrt = false; + } + } + + if (!info->debugCrtAlloc) { + crtdbgblockheaderucrt_t* crtheader = (crtdbgblockheaderucrt_t*)block; + SIZE_T nSize = sizeof(crtdbgblockheaderucrt_t) + crtheader->size + GAPSIZE; + int nValid = _CrtIsValidPointer(block, (unsigned int)info->size, TRUE); + if (_BLOCK_TYPE_IS_VALID(crtheader->use) && nValid && (nSize == info->size)) { + info->debugCrtAlloc = true; + info->ucrt = true; + } + } + + return info->debugCrtAlloc; +} + // getleakscount - Calculate number of memory leaks. // // - heap (IN): Handle to the heap for which to generate a memory leak @@ -1687,23 +1714,14 @@ SIZE_T VisualLeakDetector::getLeaksCount (heapinfo_t* heapinfo, DWORD threadId) if (threadId != ((DWORD)-1) && info->threadId != threadId) continue; - if (!info->debugCrtAlloc) { - crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block; - SIZE_T nSize = sizeof(crtdbgblockheader_t) + crtheader->size + GAPSIZE; - int nValid = _CrtIsValidPointer(block, (unsigned int)info->size, TRUE); - if (_BLOCK_TYPE_IS_VALID(crtheader->use) && nValid && (nSize == info->size)) { - info->debugCrtAlloc = true; - } - } - - if (info->debugCrtAlloc) { + if (isDebugCrtAlloc(block, info)) { // This block is allocated to a CRT heap, so the block has a CRT // memory block header pretended to it. - crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block; + int blockUse = getCrtBlockUse(block, info->ucrt); // Leaks identified as CRT_USE_IGNORE should not be ignored here otherwise // DynamicLoader/Thread test will randomly fail with less leaks being reported. - if (CRT_USE_TYPE(crtheader->use) == CRT_USE_FREE || - CRT_USE_TYPE(crtheader->use) == CRT_USE_INTERNAL) { + if (CRT_USE_TYPE(blockUse) == CRT_USE_FREE || + CRT_USE_TYPE(blockUse) == CRT_USE_INTERNAL) { // This block is marked as being used internally by the CRT. // The CRT will free the block after VLD is destroyed. continue; @@ -1759,6 +1777,34 @@ SIZE_T VisualLeakDetector::reportHeapLeaks (HANDLE heap) return leaks_count; } +int VisualLeakDetector::getCrtBlockUse(LPCVOID block, bool ucrt) +{ + if (!ucrt) + { + crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block; + return crtheader->use; + } + else + { + crtdbgblockheaderucrt_t* crtheader = (crtdbgblockheaderucrt_t*)block; + return crtheader->use; + } +} + +size_t VisualLeakDetector::getCrtBlockSize(LPCVOID block, bool ucrt) +{ + if (!ucrt) + { + crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block; + return crtheader->size; + } + else + { + crtdbgblockheaderucrt_t* crtheader = (crtdbgblockheaderucrt_t*)block; + return crtheader->size; + } +} + SIZE_T VisualLeakDetector::reportLeaks (heapinfo_t* heapinfo, bool &firstLeak, Set &aggregatedLeaks, DWORD threadId) { BlockMap* blockmap = &heapinfo->blockMap; @@ -1783,23 +1829,14 @@ SIZE_T VisualLeakDetector::reportLeaks (heapinfo_t* heapinfo, bool &firstLeak, S LPCVOID address = block; SIZE_T size = info->size; - if (!info->debugCrtAlloc) { - crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block; - SIZE_T nSize = sizeof(crtdbgblockheader_t) + crtheader->size + GAPSIZE; - int nValid = _CrtIsValidPointer(block, (unsigned int)info->size, TRUE); - if (_BLOCK_TYPE_IS_VALID(crtheader->use) && nValid && (nSize == info->size)) { - info->debugCrtAlloc = true; - } - } - - if (info->debugCrtAlloc) { + if (isDebugCrtAlloc( block, info )) { // This block is allocated to a CRT heap, so the block has a CRT // memory block header pretended to it. - crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block; + int blockUse = getCrtBlockUse( block, info->ucrt ); // Leaks identified as CRT_USE_IGNORE should not be ignored here otherwise // DynamicLoader/Thread test will randomly fail with less leaks being reported. - if (CRT_USE_TYPE(crtheader->use) == CRT_USE_FREE || - CRT_USE_TYPE(crtheader->use) == CRT_USE_INTERNAL) + if (CRT_USE_TYPE(blockUse) == CRT_USE_FREE || + CRT_USE_TYPE(blockUse) == CRT_USE_INTERNAL) { // This block is marked as being used internally by the CRT. // The CRT will free the block after VLD is destroyed. @@ -1811,7 +1848,7 @@ SIZE_T VisualLeakDetector::reportLeaks (heapinfo_t* heapinfo, bool &firstLeak, S // more useful to the user. Accordingly, that's the information // we'll include in the report. address = CRTDBGBLOCKDATA(block); - size = crtheader->size; + size = getCrtBlockSize(block, info->ucrt); } if (m_options & VLD_OPT_SKIP_CRTSTARTUP_LEAKS) { @@ -1834,7 +1871,7 @@ SIZE_T VisualLeakDetector::reportLeaks (heapinfo_t* heapinfo, bool &firstLeak, S { crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block; Report(L" CRT Alloc ID: %Iu\n", crtheader->request); - assert(size == crtheader->size); + assert(size == getCrtBlockSize(block, info->ucrt)); } #endif assert(info->callStack); @@ -2747,16 +2784,7 @@ int VisualLeakDetector::resolveStacks(heapinfo_t* heapinfo) const void* address = block; assert(address != NULL); - if (!info->debugCrtAlloc) { - crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block; - SIZE_T nSize = sizeof(crtdbgblockheader_t) + crtheader->size + GAPSIZE; - int nValid = _CrtIsValidPointer(block, (unsigned int)info->size, TRUE); - if (_BLOCK_TYPE_IS_VALID(crtheader->use) && nValid && (nSize == info->size)) { - info->debugCrtAlloc = true; - } - } - - if (info->debugCrtAlloc) { + if (isDebugCrtAlloc(block, info)) { // This block is allocated to a CRT heap, so the block has a CRT // memory block header prepended to it. crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block; @@ -2807,14 +2835,17 @@ int VisualLeakDetector::ResolveCallstacks() return unresolvedFunctionsCount; } - -CaptureContext::CaptureContext(context_t &context, BOOL debug, void* func, UINT_PTR fp) : m_func(func), m_fp(fp) { +CaptureContext::CaptureContext(context_t &context, BOOL debug, BOOL ucrt, void* func, UINT_PTR fp) : m_fp(fp), m_func(func) { m_tls = g_vld.getTls(); if (debug) { m_tls->flags |= VLD_TLS_DEBUGCRTALLOC; } + if (ucrt) { + m_tls->flags |= VLD_TLS_UCRT; + } + m_bFirst = (GET_RETURN_ADDRESS(m_tls->context) == NULL); if (m_bFirst) { // This is the first call to enter VLD for the current allocation. @@ -2826,35 +2857,53 @@ CaptureContext::CaptureContext(context_t &context, BOOL debug, void* func, UINT_ } } -CaptureContext::~CaptureContext() { +CaptureContext::CaptureContext(context_t &context, void* func, UINT_PTR fp) : m_fp(fp), m_func(func) { + m_tls = g_vld.getTls(); + + m_bFirst = (GET_RETURN_ADDRESS(m_tls->context) == NULL); if (m_bFirst) { - if ((m_tls->blockWithoutGuard) && (!IsExcludedModule())) { - blockinfo_t* pblockInfo = NULL; - if (m_tls->newBlockWithoutGuard == NULL) { - g_vld.mapBlock(m_tls->heap, - m_tls->blockWithoutGuard, - m_tls->size, - (m_tls->flags & VLD_TLS_DEBUGCRTALLOC), - m_tls->threadId, - pblockInfo); - } else { - g_vld.remapBlock(m_tls->heap, - m_tls->blockWithoutGuard, - m_tls->newBlockWithoutGuard, - m_tls->size, - (m_tls->flags & VLD_TLS_DEBUGCRTALLOC), - m_tls->threadId, - pblockInfo, m_tls->context); - } + // This is the first call to enter VLD for the current allocation. + // Record the current frame pointer. + if (func) { + Capture(context); + } + m_tls->context = context; + } +} + +CaptureContext::~CaptureContext() { + if (!m_bFirst) + return; - CallStack* callstack = CallStack::Create(); - callstack->getStackTrace(g_vld.m_maxTraceFrames, m_tls->context); - pblockInfo->callStack.reset(callstack); + if ((m_tls->blockWithoutGuard) && (!IsExcludedModule())) { + blockinfo_t* pblockInfo = NULL; + if (m_tls->newBlockWithoutGuard == NULL) { + g_vld.mapBlock(m_tls->heap, + m_tls->blockWithoutGuard, + m_tls->size, + (m_tls->flags & VLD_TLS_DEBUGCRTALLOC) != 0, + (m_tls->flags & VLD_TLS_UCRT) != 0, + m_tls->threadId, + pblockInfo); + } + else { + g_vld.remapBlock(m_tls->heap, + m_tls->blockWithoutGuard, + m_tls->newBlockWithoutGuard, + m_tls->size, + (m_tls->flags & VLD_TLS_DEBUGCRTALLOC) != 0, + (m_tls->flags & VLD_TLS_UCRT) != 0, + m_tls->threadId, + pblockInfo, m_tls->context); } - // Reset thread local flags and variables for the next allocation. - Reset(); + CallStack* callstack = CallStack::Create(); + callstack->getStackTrace(g_vld.m_maxTraceFrames, m_tls->context); + pblockInfo->callStack.reset(callstack); } + + // Reset thread local flags and variables for the next allocation. + Reset(); } void CaptureContext::Capture(context_t &context) { @@ -2897,7 +2946,7 @@ void CaptureContext::Reset() { #elif defined(_M_X64) m_tls->context.Rbp = m_tls->context.Rsp = m_tls->context.Rip = NULL; #endif - m_tls->flags &= ~VLD_TLS_DEBUGCRTALLOC; + m_tls->flags &= ~(VLD_TLS_DEBUGCRTALLOC | VLD_TLS_UCRT); Set(NULL, NULL, NULL, NULL); } diff --git a/src/vld_hooks.cpp b/src/vld_hooks.cpp index 38c95429..c267f6d6 100644 --- a/src/vld_hooks.cpp +++ b/src/vld_hooks.cpp @@ -46,631 +46,6 @@ extern HANDLE g_currentProcess; extern CriticalSection g_heapMapLock; extern DbgHelp g_DbgHelp; -//////////////////////////////////////////////////////////////////////////////// -// -// Standard CRT and MFC IAT Replacement Functions -// -// The addresses of these functions are not actually directly patched into the -// import address tables, but these functions do get indirectly called by the -// patch functions that are placed in the import address tables. -// -//////////////////////////////////////////////////////////////////////////////// - -// _calloc - This function is just a wrapper around the real calloc that sets -// appropriate flags to be consulted when the memory is actually allocated by -// RtlAllocateHeap. -// -// - pcalloc (IN): Pointer to the particular calloc implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - num (IN): The number of blocks, of size 'size', to be allocated. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// Return Value: -// -// Returns the value returned from the specified calloc. -// -void* VisualLeakDetector::_calloc (calloc_t pcalloc, - context_t& context, - bool debugRuntime, - size_t num, - size_t size) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return pcalloc(num, size); -} - -// _malloc - This function is just a wrapper around the real malloc that sets -// appropriate flags to be consulted when the memory is actually allocated by -// RtlAllocateHeap. -// -// - pmalloc (IN): Pointer to the particular malloc implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// Return Value: -// -// Returns the value returned from the specified malloc. -// -void *VisualLeakDetector::_malloc (malloc_t pmalloc, context_t& context, bool debugRuntime, size_t size) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return pmalloc(size); -} - -// _new - This function is just a wrapper around the real CRT and MFC new -// operators that sets appropriate flags to be consulted when the memory is -// actually allocated by RtlAllocateHeap. -// -// - pnew (IN): Pointer to the particular new implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// Return Value: -// -// Returns the value returned by the specified CRT new operator. -// -void* VisualLeakDetector::_new (new_t pnew, context_t& context, bool debugRuntime, size_t size) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return pnew(size); -} - -// _realloc - This function is just a wrapper around the real realloc that sets -// appropriate flags to be consulted when the memory is actually allocated by -// RtlAllocateHeap. -// -// - prealloc (IN): Pointer to the particular realloc implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to reallocate. -// -// - size (IN): Size of the memory block to reallocate. -// -// Return Value: -// -// Returns the value returned from the specified realloc. -// -void* VisualLeakDetector::_realloc (realloc_t prealloc, - context_t& context, - bool debugRuntime, - void *mem, - size_t size) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return prealloc(mem, size); -} - -// _recalloc - This function is just a wrapper around the real _recalloc that sets -// appropriate flags to be consulted when the memory is actually allocated by -// RtlAllocateHeap. -// -// - prealloc (IN): Pointer to the particular realloc implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to reallocate. -// -// - size (IN): Size of the memory block to reallocate. -// -// Return Value: -// -// Returns the value returned from the specified realloc. -// -void* VisualLeakDetector::__recalloc (_recalloc_t precalloc, - context_t& context, - bool debugRuntime, - void *mem, - size_t num, - size_t size) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return precalloc(mem, num, size); -} - -char* VisualLeakDetector::__strdup( _strdup_t pstrdup, context_t& context, bool debugRuntime, const char* src ) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return pstrdup(src); -} - -wchar_t* VisualLeakDetector::__wcsdup( _wcsdup_t pwcsdup, context_t& context, bool debugRuntime, const wchar_t* src ) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return pwcsdup(src); -} - -// __aligned_malloc - This function is just a wrapper around the real malloc that sets -// appropriate flags to be consulted when the memory is actually allocated by -// RtlAllocateHeap. -// -// - pmalloc (IN): Pointer to the particular malloc implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// Return Value: -// -// Returns the value returned from the specified malloc. -// -void *VisualLeakDetector::__aligned_malloc (_aligned_malloc_t pmalloc, context_t& context, bool debugRuntime, - size_t size, size_t alignment) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return pmalloc(size, alignment); -} - -// __aligned_offset_malloc - This function is just a wrapper around the real malloc that sets -// appropriate flags to be consulted when the memory is actually allocated by -// RtlAllocateHeap. -// -// - pmalloc (IN): Pointer to the particular malloc implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// Return Value: -// -// Returns the value returned from the specified _aligned_offset_malloc. -// -void *VisualLeakDetector::__aligned_offset_malloc (_aligned_offset_malloc_t pmalloc, context_t& context, bool debugRuntime, - size_t size, size_t alignment, size_t offset) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return pmalloc(size, alignment, offset); -} - -// __aligned_realloc - This function is just a wrapper around the real realloc that sets -// appropriate flags to be consulted when the memory is actually allocated by -// RtlAllocateHeap. -// -// - prealloc (IN): Pointer to the particular realloc implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to reallocate. -// -// - size (IN): Size of the memory block to reallocate. -// -// Return Value: -// -// Returns the value returned from the specified _aligned_realloc. -// -void* VisualLeakDetector::__aligned_realloc (_aligned_realloc_t prealloc, - context_t& context, - bool debugRuntime, - void *mem, - size_t size, - size_t alignment) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return prealloc(mem, size, alignment); -} - -// __aligned_offset_realloc - This function is just a wrapper around the real realloc that sets -// appropriate flags to be consulted when the memory is actually allocated by -// RtlAllocateHeap. -// -// - prealloc (IN): Pointer to the particular realloc implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to reallocate. -// -// - size (IN): Size of the memory block to reallocate. -// -// Return Value: -// -// Returns the value returned from the specified _aligned_offset_realloc. -// -void* VisualLeakDetector::__aligned_offset_realloc (_aligned_offset_realloc_t prealloc, - context_t& context, - bool debugRuntime, - void *mem, - size_t size, - size_t alignment, - size_t offset) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return prealloc(mem, size, alignment, offset); -} - -// __aligned_recalloc - This function is just a wrapper around the real recalloc that sets -// appropriate flags to be consulted when the memory is actually allocated by -// RtlAllocateHeap. -// -// - precalloc (IN): Pointer to the particular recalloc implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to reallocate. -// -// - num (IN): Count of the memory block to reallocate. -// -// - size (IN): Size of the memory block to reallocate. -// -// Return Value: -// -// Returns the value returned from the specified _aligned_realloc. -// -void* VisualLeakDetector::__aligned_recalloc (_aligned_recalloc_t precalloc, - context_t& context, - bool debugRuntime, - void *mem, - size_t num, - size_t size, - size_t alignment) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return precalloc(mem, num, size, alignment); -} - -// __aligned_offset_recalloc - This function is just a wrapper around the real recalloc that sets -// appropriate flags to be consulted when the memory is actually allocated by -// RtlAllocateHeap. -// -// - precalloc (IN): Pointer to the particular realloc implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to reallocate. -// -// - num (IN): Count of the memory block to reallocate. -// -// - size (IN): Size of the memory block to reallocate. -// -// Return Value: -// -// Returns the value returned from the specified _aligned_offset_realloc. -// -void* VisualLeakDetector::__aligned_offset_recalloc (_aligned_offset_recalloc_t precalloc, - context_t& context, - bool debugRuntime, - void *mem, - size_t num, - size_t size, - size_t alignment, - size_t offset) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return precalloc(mem, num, size, alignment, offset); -} - -// __aligned_malloc_dbg - This function is just a wrapper around the real _aligned_malloc_dbg -// that sets appropriate flags to be consulted when the memory is actually -// allocated by RtlAllocateHeap. -// -// - p_malloc_dbg (IN): Pointer to the particular _malloc_dbg implementation to -// call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// - type (IN): The CRT "use type" of the block to be allocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified _aligned_malloc_dbg. -// -void* VisualLeakDetector::__aligned_malloc_dbg (_aligned_malloc_dbg_t p_malloc_dbg, - context_t& context, - bool debugRuntime, - size_t size, - size_t alignment, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return p_malloc_dbg(size, alignment, type, file, line); -} - -// __aligned_offset_malloc_dbg - This function is just a wrapper around the real -// _aligned_offset_malloc_dbg that sets appropriate flags to be consulted when -// the memory is actually allocated by RtlAllocateHeap. -// -// - p_malloc_dbg (IN): Pointer to the particular _malloc_dbg implementation to -// call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// - type (IN): The CRT "use type" of the block to be allocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified _aligned_malloc_dbg. -// -void* VisualLeakDetector::__aligned_offset_malloc_dbg (_aligned_offset_malloc_dbg_t p_malloc_dbg, - context_t& context, - bool debugRuntime, - size_t size, - size_t alignment, - size_t offset, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return p_malloc_dbg(size, alignment, offset, type, file, line); -} - -// _aligned_realloc_debug - This function is just a wrapper around the real -// _aligned_realloc_dbg that sets appropriate flags to be consulted when the memory is -// actually allocated by RtlAllocateHeap. -// -// - p_realloc_dbg (IN): Pointer to the particular __realloc_dbg implementation -// to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to be reallocated. -// -// - size (IN): The size of the memory block to reallocate. -// -// - type (IN): The CRT "use type" of the block to be reallocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified _realloc_dbg. -// -void* VisualLeakDetector::__aligned_realloc_dbg (_aligned_realloc_dbg_t p_realloc_dbg, - context_t& context, - bool debugRuntime, - void *mem, - size_t size, - size_t alignment, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return p_realloc_dbg(mem, size, alignment, type, file, line); -} - -// _aligned_offset_realloc_debug - This function is just a wrapper around the real -// _aligned_offset_realloc_dbg that sets appropriate flags to be consulted when -// the memory is actually allocated by RtlAllocateHeap. -// -// - p_realloc_dbg (IN): Pointer to the particular __realloc_dbg implementation -// to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to be reallocated. -// -// - size (IN): The size of the memory block to reallocate. -// -// - type (IN): The CRT "use type" of the block to be reallocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified _realloc_dbg. -// -void* VisualLeakDetector::__aligned_offset_realloc_dbg (_aligned_offset_realloc_dbg_t p_realloc_dbg, - context_t& context, - bool debugRuntime, - void *mem, - size_t size, - size_t alignment, - size_t offset, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return p_realloc_dbg(mem, size, alignment, offset, type, file, line); -} - -// _aligned_recalloc_debug - This function is just a wrapper around the real -// _aligned_realloc_dbg that sets appropriate flags to be consulted when the memory is -// actually allocated by RtlAllocateHeap. -// -// - p_recalloc_dbg (IN): Pointer to the particular __recalloc_dbg implementation -// to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to be reallocated. -// -// - num (IN): The number of memory blocks to reallocate. -// -// - size (IN): The size of the memory block to reallocate. -// -// - type (IN): The CRT "use type" of the block to be reallocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified _realloc_dbg. -// -void* VisualLeakDetector::__aligned_recalloc_dbg (_aligned_recalloc_dbg_t p_recalloc_dbg, - context_t& context, - bool debugRuntime, - void *mem, - size_t num, - size_t size, - size_t alignment, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return p_recalloc_dbg(mem, num, size, alignment, type, file, line); -} - -// _aligned_offset_recalloc_debug - This function is just a wrapper around the real -// _aligned_offset_recalloc_dbg that sets appropriate flags to be consulted when -// the memory is actually allocated by RtlAllocateHeap. -// -// - p_recalloc_dbg (IN): Pointer to the particular __recalloc_dbg implementation -// to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to be reallocated. -// -// - num (IN): The number of memory blocks to reallocate. -// -// - size (IN): The size of the memory block to reallocate. -// -// - type (IN): The CRT "use type" of the block to be reallocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified _realloc_dbg. -// -void* VisualLeakDetector::__aligned_offset_recalloc_dbg (_aligned_offset_recalloc_dbg_t p_recalloc_dbg, - context_t& context, - bool debugRuntime, - void *mem, - size_t num, - size_t size, - size_t alignment, - size_t offset, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return p_recalloc_dbg(mem, num, size, alignment, offset, type, file, line); -} - //////////////////////////////////////////////////////////////////////////////// // // Debug CRT and MFC IAT Replacement Functions @@ -681,316 +56,6 @@ void* VisualLeakDetector::__aligned_offset_recalloc_dbg (_aligned_offset_recallo // //////////////////////////////////////////////////////////////////////////////// -// __calloc_dbg - This function is just a wrapper around the real _calloc_dbg -// that sets appropriate flags to be consulted when the memory is actually -// allocated by RtlAllocateHeap. -// -// - p_calloc_dbg: Pointer to the particular _calloc_dbg implementation to -// call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// - type (IN): The CRT "use type" of the block to be allocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified _calloc_dbg. -// -void* VisualLeakDetector::__calloc_dbg (_calloc_dbg_t p_calloc_dbg, - context_t& context, - bool debugRuntime, - size_t num, - size_t size, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return p_calloc_dbg(num, size, type, file, line); -} - -// __malloc_dbg - This function is just a wrapper around the real _malloc_dbg -// that sets appropriate flags to be consulted when the memory is actually -// allocated by RtlAllocateHeap. -// -// - p_malloc_dbg (IN): Pointer to the particular _malloc_dbg implementation to -// call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// - type (IN): The CRT "use type" of the block to be allocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified _malloc_dbg. -// -void* VisualLeakDetector::__malloc_dbg (_malloc_dbg_t p_malloc_dbg, - context_t& context, - bool debugRuntime, - size_t size, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return p_malloc_dbg(size, type, file, line); -} - -char* VisualLeakDetector::__strdup_dbg (_strdup_dbg_t p_strdup_dbg, - context_t& context, - bool debugRuntime, - const char* src, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return p_strdup_dbg(src, type, file, line); -} - -wchar_t* VisualLeakDetector::__wcsdup_dbg (_wcsdup_dbg_t p_wcsdup_dbg, - context_t& context, - bool debugRuntime, - const wchar_t* src, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return p_wcsdup_dbg(src, type, file, line); -} - -// new_dbg_crt - This function is just a wrapper around the real CRT debug new -// operators that sets appropriate flags to be consulted when the memory is -// actually allocated by RtlAllocateHeap. -// -// - pnew_dbg_crt (IN): Pointer to the particular CRT new operator -// implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// - type (IN): The CRT "use type" of the block to be allocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified CRT debug new operator. -// -void* VisualLeakDetector::__new_dbg_crt (new_dbg_crt_t pnew_dbg_crt, - context_t& context, - bool debugRuntime, - size_t size, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return pnew_dbg_crt(size, type, file, line); -} - -// new_dbg_mfc - This function is just a wrapper around the real MFC debug new -// operators that sets appropriate flags to be consulted when the memory is -// actually allocated by RtlAllocateHeap. -// -// - pnew_dbg (IN): Pointer to the particular CRT new operator -// implementation to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// - type (IN): The CRT "use type" of the block to be allocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified CRT debug new operator. -// -void* VisualLeakDetector::__new_dbg_mfc (new_dbg_crt_t pnew_dbg, - context_t& context, - size_t size, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, FALSE, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return pnew_dbg(size, type, file, line); -} - -// new_dbg_mfc - This function is just a wrapper around the real MFC debug new -// operators that sets appropriate flags to be consulted when the memory is -// actually allocated by RtlAllocateHeap. -// -// - pnew_dbg_mfc (IN): Pointer to the particular MFC new operator -// implementation to call. -// -// - fp (IN): Frame pointer of the call that initiated this allocation. -// -// - size (IN): The size, in bytes, of the memory block to be allocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified MFC debug new operator. -// -void* VisualLeakDetector::__new_dbg_mfc (new_dbg_mfc_t pnew_dbg_mfc, - context_t& context, - size_t size, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, FALSE, NULL); - - // Do the allocation. The block will be mapped by _RtlAllocateHeap. - return pnew_dbg_mfc(size, file, line); -} - -// __realloc_debug - This function is just a wrapper around the real -// _realloc_dbg that sets appropriate flags to be consulted when the memory is -// actually allocated by RtlAllocateHeap. -// -// - p_realloc_dbg (IN): Pointer to the particular __realloc_dbg implementation -// to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to be reallocated. -// -// - size (IN): The size of the memory block to reallocate. -// -// - type (IN): The CRT "use type" of the block to be reallocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified _realloc_dbg. -// -void* VisualLeakDetector::__realloc_dbg (_realloc_dbg_t p_realloc_dbg, - context_t& context, - bool debugRuntime, - void *mem, - size_t size, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return p_realloc_dbg(mem, size, type, file, line); -} - -// __recalloc_debug - This function is just a wrapper around the real -// _recalloc_dbg that sets appropriate flags to be consulted when the memory is -// actually allocated by RtlAllocateHeap. -// -// - p_recalloc_dbg (IN): Pointer to the particular __realloc_dbg implementation -// to call. -// -// - fp (IN): Frame pointer from the call that initiated this allocation. -// -// - mem (IN): Pointer to the memory block to be reallocated. -// -// - size (IN): The size of the memory block to reallocate. -// -// - type (IN): The CRT "use type" of the block to be reallocated. -// -// - file (IN): The name of the file from which this function is being called. -// -// - line (IN): The line number, in the above file, at which this function is -// being called. -// -// Return Value: -// -// Returns the value returned by the specified _realloc_dbg. -// -void* VisualLeakDetector::__recalloc_dbg (_recalloc_dbg_t p_recalloc_dbg, - context_t& context, - bool debugRuntime, - void *mem, - size_t num, - size_t size, - int type, - char const *file, - int line) -{ -#ifdef PRINTHOOKCALLS - DbgReport(_T(__FUNCTION__) _T( "\n")); -#endif - CaptureContext cc(context, debugRuntime, NULL); - - // Do the allocation. The block will be mapped by _RtlReAllocateHeap. - return p_recalloc_dbg(mem, num, size, type, file, line); -} - // GetProcessHeap - Calls to GetProcessHeap are patched through to this function. This // function is just a wrapper around the real GetProcessHeap. // @@ -1106,7 +171,7 @@ LPVOID VisualLeakDetector::_RtlAllocateHeap (HANDLE heap, DWORD flags, SIZE_T si if (!g_DbgHelp.IsLockedByCurrentThread()) { // skip dbghelp.dll calls context_t context; - CaptureContext cc(context, FALSE, RtlAllocateHeap); + CaptureContext cc(context, RtlAllocateHeap); cc.Set(heap, block, NULL, size); } @@ -1127,7 +192,7 @@ LPVOID VisualLeakDetector::_HeapAlloc (HANDLE heap, DWORD flags, SIZE_T size) if (!g_DbgHelp.IsLockedByCurrentThread()) { // skip dbghelp.dll calls context_t context; - CaptureContext cc(context, FALSE, HeapAlloc); + CaptureContext cc(context, HeapAlloc); cc.Set(heap, block, NULL, size); } @@ -1227,7 +292,7 @@ LPVOID VisualLeakDetector::_RtlReAllocateHeap (HANDLE heap, DWORD flags, LPVOID if (!g_DbgHelp.IsLockedByCurrentThread()) { // skip dbghelp.dll calls context_t context; - CaptureContext cc(context, FALSE, RtlReAllocateHeap); + CaptureContext cc(context, RtlReAllocateHeap); cc.Set(heap, mem, newmem, size); } @@ -1248,7 +313,7 @@ LPVOID VisualLeakDetector::_HeapReAlloc (HANDLE heap, DWORD flags, LPVOID mem, S if (!g_DbgHelp.IsLockedByCurrentThread()) { // skip dbghelp.dll calls context_t context; - CaptureContext cc(context, FALSE, HeapReAlloc); + CaptureContext cc(context, HeapReAlloc); cc.Set(heap, mem, newmem, size); } @@ -1348,7 +413,7 @@ LPVOID VisualLeakDetector::_CoTaskMemAlloc (SIZE_T size) } context_t context; - CaptureContext cc(context, FALSE, (void*)pCoTaskMemAlloc); + CaptureContext cc(context, (void*)pCoTaskMemAlloc); // Do the allocation. The block will be mapped by _RtlAllocateHeap. return pCoTaskMemAlloc(size); @@ -1382,7 +447,7 @@ LPVOID VisualLeakDetector::_CoTaskMemRealloc (LPVOID mem, SIZE_T size) } context_t context; - CaptureContext cc(context, FALSE, (void*)pCoTaskMemRealloc); + CaptureContext cc(context, (void*)pCoTaskMemRealloc); // Do the allocation. The block will be mapped by _RtlReAllocateHeap. return pCoTaskMemRealloc(mem, size); @@ -1436,7 +501,7 @@ LPVOID VisualLeakDetector::Alloc (_In_ SIZE_T size) context_t context; UINT_PTR* cVtablePtr = (UINT_PTR*)((UINT_PTR*)m_iMalloc)[0]; UINT_PTR iMallocAlloc = cVtablePtr[3]; - CaptureContext cc(context, FALSE, (void*)iMallocAlloc); + CaptureContext cc(context, (void*)iMallocAlloc); // Do the allocation. The block will be mapped by _RtlAllocateHeap. assert(m_iMalloc != NULL); @@ -1560,7 +625,7 @@ LPVOID VisualLeakDetector::Realloc (_In_opt_ LPVOID mem, _In_ SIZE_T size) context_t context; UINT_PTR* cVtablePtr = (UINT_PTR*)((UINT_PTR*)m_iMalloc)[0]; UINT_PTR iMallocRealloc = cVtablePtr[4]; - CaptureContext cc(context, FALSE, (void*)iMallocRealloc); + CaptureContext cc(context, (void*)iMallocRealloc); // Do the allocation. The block will be mapped by _RtlReAllocateHeap. assert(m_iMalloc != NULL); diff --git a/src/vldheap.h b/src/vldheap.h index beb86887..34469d6c 100644 --- a/src/vldheap.h +++ b/src/vldheap.h @@ -62,6 +62,25 @@ struct crtdbgblockheader_t typedef char checkDebugHeapBlockAlignment[ (sizeof(crtdbgblockheader_t) % MEMORY_ALLOCATION_ALIGNMENT == 0) ? 1 : -1]; +// Same for UCRT. +struct crtdbgblockheaderucrt_t +{ + struct crtdbgblockheaderucrt_t *next; // Pointer to the next block in the list of blocks allocated from the CRT heap. + struct crtdbgblockheaderucrt_t *prev; // Pointer to the previous block in the list of blocks allocated from the CRT heap. + char const *file; // Source file where this block was allocated. + int line; // Line of code, within the above file, where this block was allocated. + int use; // This block's "use type": see below. + size_t size; // Size of the data portion of the block. + long request; // This block's "request" number. Basically a serial number. + unsigned char gap[GAPSIZE]; // No-man's land buffer zone, for buffer overrun/underrun checking. +}; + +typedef char checkDebugUcrtHeapBlockAlignment[ + (sizeof(crtdbgblockheaderucrt_t) % MEMORY_ALLOCATION_ALIGNMENT == 0) ? 1 : -1]; + +typedef char checkDebugHeapBlockSize[ + (sizeof(crtdbgblockheader_t) == sizeof(crtdbgblockheaderucrt_t)) ? 1 : -1]; + // Macro to strip off any sub-type information stored in a block's "use type". #define CRT_USE_TYPE(use) (use & 0xFFFF) #define _BLOCK_TYPE_IS_VALID(use) (_BLOCK_TYPE(use) == _CLIENT_BLOCK || (use) == _NORMAL_BLOCK || _BLOCK_TYPE(use) == _CRT_BLOCK || (use) == _IGNORE_BLOCK) @@ -80,10 +99,10 @@ struct vldblockheader_t }; // Data-to-Header and Header-to-Data conversion -#define CRTDBGBLOCKHEADER(d) (crtdbgblockheader_t*)(((PBYTE)d) - sizeof(crtdbgblockheader_t)) -#define CRTDBGBLOCKDATA(h) (LPVOID)(((PBYTE)h) + sizeof(crtdbgblockheader_t)) #define VLDBLOCKHEADER(d) (vldblockheader_t*)(((PBYTE)d) - sizeof(vldblockheader_t)) #define VLDBLOCKDATA(h) (LPVOID)(((PBYTE)h) + sizeof(vldblockheader_t)) +#define CRTDBGBLOCKHEADER(d) (crtdbgblockheader_t*)(((PBYTE)d) - sizeof(crtdbgblockheader_t)) +#define CRTDBGBLOCKDATA(h) (LPVOID)(((PBYTE)h) + sizeof(crtdbgblockheader_t)) // new and delete operators for allocating from VLD's private heap. void operator delete (void *block); diff --git a/src/vldint.h b/src/vldint.h index bee2f924..c56580b5 100644 --- a/src/vldint.h +++ b/src/vldint.h @@ -110,6 +110,7 @@ struct blockinfo_t { SIZE_T size; bool reported; bool debugCrtAlloc; + bool ucrt; }; // BlockMaps map memory blocks (via their addresses) to blockinfo_t structures. @@ -162,9 +163,10 @@ typedef Set ReportHookSet; struct tls_t { context_t context; // Address of return address at the first call that entered VLD's code for the current allocation. UINT32 flags; // Thread-local status flags: -#define VLD_TLS_DEBUGCRTALLOC 0x1 // If set, the current allocation is a CRT allocation. +#define VLD_TLS_DEBUGCRTALLOC 0x1 // If set, the current allocation is a CRT allocation. #define VLD_TLS_DISABLED 0x2 // If set, memory leak detection is disabled for the current thread. #define VLD_TLS_ENABLED 0x4 // If set, memory leak detection is enabled for the current thread. +#define VLD_TLS_UCRT 0x8 // If set, the current allocation is a UCRT allocation. UINT32 oldFlags; // Thread-local status old flags DWORD threadId; // Thread ID of the thread that owns this TLS structure. HANDLE heap; @@ -184,7 +186,8 @@ typedef Map TlsMap; class CaptureContext { public: - CaptureContext(context_t &context, BOOL debug, void* func, UINT_PTR fp = (UINT_PTR)_ReturnAddress()); + CaptureContext(context_t &context, BOOL debug, BOOL ucrt, void* func, UINT_PTR fp = (UINT_PTR)_ReturnAddress()); + CaptureContext(context_t &context, void* func, UINT_PTR fp = (UINT_PTR)_ReturnAddress()); ~CaptureContext(); __forceinline void Set(HANDLE heap, LPVOID mem, LPVOID newmem, SIZE_T size); private: @@ -240,47 +243,6 @@ class VisualLeakDetector : public IMalloc VisualLeakDetector(); ~VisualLeakDetector(); - //////////////////////////////////////////////////////////////////////////////// - // Public CRT and MFC Common Handlers - // - // Many heap functions are indirectly rerouted to these handlers. One common - // function exists for each heap function with a given signature. These - // handlers are not direct IAT replacements, but are called by the individual - // IAT replacement functions. - //////////////////////////////////////////////////////////////////////////////// - // Standard CRT and MFC common handlers - void* _calloc (calloc_t pcalloc, context_t& context, bool debugRuntime, size_t num, size_t size); - void* _malloc (malloc_t pmalloc, context_t& context, bool debugRuntime, size_t size); - void* _new (new_t pnew, context_t& context, bool debugRuntime, size_t size); - void* _realloc (realloc_t prealloc, context_t& context, bool debugRuntime, void *mem, size_t size); - void* __recalloc (_recalloc_t precalloc, context_t& context, bool debugRuntime, void *mem, size_t num, size_t size); - char* __strdup(_strdup_t pstrdup, context_t& context, bool debugRuntime, const char* src); - wchar_t* __wcsdup(_wcsdup_t pwcsdup, context_t& context, bool debugRuntime, const wchar_t* src); - - // Debug CRT and MFC common handlers - void* __calloc_dbg (_calloc_dbg_t p_calloc_dbg, context_t& context, bool debugRuntime, size_t num, size_t size, int type, char const *file, int line); - void* __malloc_dbg (_malloc_dbg_t p_malloc_dbg, context_t& context, bool debugRuntime, size_t size, int type, char const *file, int line); - void* __new_dbg_crt (new_dbg_crt_t pnew_dbg_crt, context_t& context, bool debugRuntime, size_t size, int type, char const *file, int line); - void* __new_dbg_mfc (new_dbg_crt_t pnew_dbg, context_t& context, size_t size, int type, char const *file, int line); - void* __new_dbg_mfc (new_dbg_mfc_t pnew_dbg_mfc, context_t& context, size_t size, char const *file, int line); - void* __realloc_dbg (_realloc_dbg_t p_realloc_dbg, context_t& context, bool debugRuntime, void *mem, size_t size, int type, char const *file, int line); - void* __recalloc_dbg (_recalloc_dbg_t p_recalloc_dbg, context_t& context, bool debugRuntime, void *mem, size_t num, size_t size, int type, char const *file, int line); - char* __strdup_dbg(_strdup_dbg_t pstrdup, context_t& context, bool debugRuntime, const char* src, int type, char const *file, int line); - wchar_t* __wcsdup_dbg(_wcsdup_dbg_t pwcsdup, context_t& context, bool debugRuntime, const wchar_t* src, int type, char const *file, int line); - - void *__aligned_malloc (_aligned_malloc_t p_aligned_malloc, context_t& context, bool debugRuntime, size_t size, size_t alignment); - void *__aligned_offset_malloc (_aligned_offset_malloc_t p_aligned_offset_malloc, context_t& context, bool debugRuntime, size_t size, size_t alignment, size_t offset); - void *__aligned_realloc (_aligned_realloc_t p_aligned_realloc, context_t& context, bool debugRuntime, void *mem, size_t size, size_t alignment); - void *__aligned_offset_realloc (_aligned_offset_realloc_t p_aligned_offset_realloc, context_t& context, bool debugRuntime, void *mem, size_t size, size_t alignment, size_t offset); - void *__aligned_recalloc (_aligned_recalloc_t p_aligned_recalloc, context_t& context, bool debugRuntime, void *mem, size_t num, size_t size, size_t alignment); - void *__aligned_offset_recalloc (_aligned_offset_recalloc_t p_aligned_offset_recalloc, context_t& context, bool debugRuntime, void *mem, size_t num, size_t size, size_t alignment, size_t offset); - void* __aligned_malloc_dbg (_aligned_malloc_dbg_t p_aligned_malloc_dbg, context_t& context, bool debugRuntime, size_t size, size_t alignment, int type, char const *file, int line); - void* __aligned_offset_malloc_dbg (_aligned_offset_malloc_dbg_t p_aligned_offset_malloc_dbg, context_t& context, bool debugRuntime, size_t size, size_t alignment, size_t offset, int type, char const *file, int line); - void* __aligned_realloc_dbg (_aligned_realloc_dbg_t p_aligned_realloc_dbg, context_t& context, bool debugRuntime, void *mem, size_t size, size_t alignment, int type, char const *file, int line); - void* __aligned_offset_realloc_dbg (_aligned_offset_realloc_dbg_t p_aligned_offset_realloc_dbg, context_t& context, bool debugRuntime, void *mem, size_t size, size_t alignment, size_t offset, int type, char const *file, int line); - void* __aligned_recalloc_dbg (_aligned_recalloc_dbg_t p_aligned_recalloc_dbg, context_t& context, bool debugRuntime, void *mem, size_t num, size_t size, size_t alignment, int type, char const *file, int line); - void* __aligned_offset_recalloc_dbg (_aligned_offset_recalloc_dbg_t p_aligned_offset_recalloc_dbg, context_t& context, bool debugRuntime, void *mem, size_t num, size_t size, size_t alignment, size_t offset, int type, char const *file, int line); - //////////////////////////////////////////////////////////////////////////////// // Public IMalloc methods - for support of COM-based memory leak detection. //////////////////////////////////////////////////////////////////////////////// @@ -343,12 +305,15 @@ class VisualLeakDetector : public IMalloc BOOL enabled (); SIZE_T eraseDuplicates (const BlockMap::Iterator &element, Set &aggregatedLeak); tls_t* getTls (); - VOID mapBlock (HANDLE heap, LPCVOID mem, SIZE_T size, bool crtalloc, DWORD threadId, blockinfo_t* &pblockInfo); + VOID mapBlock (HANDLE heap, LPCVOID mem, SIZE_T size, bool crtalloc, bool ucrt, DWORD threadId, blockinfo_t* &pblockInfo); VOID mapHeap (HANDLE heap); VOID remapBlock (HANDLE heap, LPCVOID mem, LPCVOID newmem, SIZE_T size, - bool crtalloc, DWORD threadId, blockinfo_t* &pblockInfo, const context_t &context); + bool crtalloc, bool ucrt, DWORD threadId, blockinfo_t* &pblockInfo, const context_t &context); VOID reportConfig (); + static bool isDebugCrtAlloc(LPCVOID block, blockinfo_t* info); SIZE_T reportHeapLeaks (HANDLE heap); + static int getCrtBlockUse (LPCVOID block, bool ucrt); + static size_t getCrtBlockSize(LPCVOID block, bool ucrt); SIZE_T getLeaksCount (heapinfo_t* heapinfo, DWORD threadId = (DWORD)-1); SIZE_T reportLeaks(heapinfo_t* heapinfo, bool &firstLeak, Set &aggregatedLeaks, DWORD threadId = (DWORD)-1); VOID markAllLeaksAsReported (heapinfo_t* heapinfo, DWORD threadId = (DWORD)-1);