📄 mdbghook.cpp
字号:
/***
*dbgrpt.c - Debug CRT Reporting Functions
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*
*******************************************************************************/
#ifdef _DEBUG
#include <internal.h>
#include <crtdbg.h>
#include <mtdll.h>
#include <malloc.h>
#pragma warning(disable:4439) // C4439: function with a managed parameter must have a __clrcall calling convention
volatile _CRT_REPORT_HOOK_M __declspec(appdomain) __pfnReportHookManaged = (_CRT_REPORT_HOOK_M) _encoded_null();
static int __cdecl _CrtReportHook_managed_thunk(int i, char *pCh, int *pInt)
{
// Avoid thread-sync issues
_CRT_REPORT_HOOK_M pfnReportHookManaged = (_CRT_REPORT_HOOK_M) DecodePointer(__pfnReportHookManaged);
if (pfnReportHookManaged != NULL)
{
return (*pfnReportHookManaged)(i, pCh, pInt);
}
else
{
return 0;
}
}
static void __clrcall _CrtReportHook_managed_cleanup(void)
{
_CRT_REPORT_HOOK pfnReportHook=_CrtGetReportHook();
_CRT_REPORT_HOOK_M enull = (_CRT_REPORT_HOOK_M) _encoded_null();
if(pfnReportHook==_CrtReportHook_managed_thunk && __pfnReportHookManaged!=enull)
{
_CrtSetReportHook((_CRT_REPORT_HOOK)NULL);
}
__pfnReportHookManaged=enull;
}
/***
*_CRT_REPORT_HOOK_M _CrtSetReportHook() - set client report hook
*
*Purpose:
* set client report hook
*
*Entry:
* _CRT_REPORT_HOOK_M pfnNewHook - new report hook
*
*Exit:
* return previous hook
*
*Exceptions:
*
*******************************************************************************/
_MRTIMP _CRT_REPORT_HOOK_M __cdecl _CrtSetReportHook(
_CRT_REPORT_HOOK_M pfnNewHook
)
{
if(_atexit_m_appdomain(_CrtReportHook_managed_cleanup)!=0)
{
return NULL;
}
_CRT_REPORT_HOOK_M pfnOldHook = (_CRT_REPORT_HOOK_M) DecodePointer(__pfnReportHookManaged);
if (pfnNewHook)
{
__pfnReportHookManaged = (_CRT_REPORT_HOOK_M) EncodePointer(pfnNewHook);
_CrtSetReportHook((_CRT_REPORT_HOOK)_CrtReportHook_managed_thunk);
}
else
{
_CRT_REPORT_HOOK_M enull = (_CRT_REPORT_HOOK_M) _encoded_null();
__pfnReportHookManaged = enull;
_CrtSetReportHook((_CRT_REPORT_HOOK)NULL);
}
return pfnOldHook;
}
_MRTIMP _CRT_REPORT_HOOK __cdecl _CrtSetReportHook(
int pfnNewHook
)
{
_VALIDATE_RETURN(pfnNewHook == 0, EINVAL, NULL);
return _CrtSetReportHook((_CRT_REPORT_HOOK)NULL);
}
/***
static int __cdecl _CrtAllocHook_managed_thunk
(
int allocType,
void *userData,
size_t size,
int blockType,
long requestNumber,
const unsigned char *filename,
int lineNumber
)
*
*Purpose:
* thunk m-> client alloc hook
*
*Exceptions:
*
*******************************************************************************/
volatile _CRT_ALLOC_HOOK_M __declspec(appdomain) __pfnAllocHookManaged = (_CRT_ALLOC_HOOK_M) _encoded_null();
static int __cdecl _CrtAllocHook_managed_thunk
(
int allocType,
void *userData,
size_t size,
int blockType,
long requestNumber,
const unsigned char *filename,
int lineNumber
)
{
// Avoid thread-sync issues
_CRT_ALLOC_HOOK_M pfnAllocHookManaged= (_CRT_ALLOC_HOOK_M) DecodePointer(__pfnAllocHookManaged);
if (pfnAllocHookManaged != NULL)
{
return (*pfnAllocHookManaged)(allocType, userData, size, blockType, requestNumber, filename, lineNumber);
}
else
{
// we want to return 1 (TRUE) here
// because if we return 0 (FALSE) it will call _CrtDbgReport()
return 1;
}
}
static void __clrcall _CrtAllocHook_managed_cleanup(void)
{
_CRT_ALLOC_HOOK pfnAllocHook=_CrtGetAllocHook();
_CRT_ALLOC_HOOK_M enull = (_CRT_ALLOC_HOOK_M) _encoded_null();
if(pfnAllocHook==_CrtAllocHook_managed_thunk && __pfnAllocHookManaged!=enull)
{
_CrtSetAllocHook((_CRT_ALLOC_HOOK)NULL);
}
__pfnAllocHookManaged=enull;
}
/***
*_CRT_ALLOC_HOOK_M _CrtSetAllocHook() - set client report hook
*
*Purpose:
* set client alloc hook
*
*Entry:
* _CRT_ALLOC_HOOK_M pfnNewHook - new alloc hook
*
*Exit:
* return previous hook
*
*Exceptions:
*
*******************************************************************************/
_MRTIMP _CRT_ALLOC_HOOK_M __cdecl _CrtSetAllocHook
(
_CRT_ALLOC_HOOK_M pfnNewHook
)
{
if(_atexit_m_appdomain(_CrtAllocHook_managed_cleanup)!=0)
{
return NULL;
}
_CRT_ALLOC_HOOK_M pfnOldHook = (_CRT_ALLOC_HOOK_M) DecodePointer(__pfnAllocHookManaged);
if (pfnNewHook)
{
__pfnAllocHookManaged = (_CRT_ALLOC_HOOK_M) EncodePointer(pfnNewHook);
_CrtSetAllocHook((_CRT_ALLOC_HOOK)_CrtAllocHook_managed_thunk);
}
else
{
_CRT_ALLOC_HOOK_M enull = (_CRT_ALLOC_HOOK_M) _encoded_null();
__pfnAllocHookManaged = enull;
_CrtSetAllocHook((_CRT_ALLOC_HOOK)NULL);
}
return pfnOldHook;
}
_MRTIMP _CRT_ALLOC_HOOK __cdecl _CrtSetAllocHook
(
int pfnNewHook
)
{
_VALIDATE_RETURN(pfnNewHook == 0, EINVAL, NULL);
return _CrtSetAllocHook((_CRT_ALLOC_HOOK)NULL);
}
/***
static void __cdecl _CrtDumpClient_managed_thunk
(
void *userPortion,
size_t blockSize
)
*
*Purpose:
* thunk m-> client dump hook
*
*Exceptions:
*
*******************************************************************************/
volatile _CRT_DUMP_CLIENT_M __declspec(appdomain) __pfnDumpClientManaged = (_CRT_DUMP_CLIENT_M) _encoded_null();
static void __cdecl _CrtDumpClient_managed_thunk
(
void *userPortion,
size_t blockSize
)
{
// Avoid thread-sync issues
_CRT_DUMP_CLIENT_M pfnDumpClientManaged = (_CRT_DUMP_CLIENT_M) DecodePointer(__pfnDumpClientManaged);
if (pfnDumpClientManaged != NULL)
{
(*pfnDumpClientManaged)(userPortion, blockSize);
}
}
static void __clrcall _CrtDumpClient_managed_cleanup(void)
{
_CRT_DUMP_CLIENT pfnDumpClient=_CrtGetDumpClient();
_CRT_DUMP_CLIENT_M enull = (_CRT_DUMP_CLIENT_M) _encoded_null();
if(pfnDumpClient==_CrtDumpClient_managed_thunk && __pfnDumpClientManaged!=enull)
{
_CrtSetDumpClient((_CRT_DUMP_CLIENT)NULL);
}
__pfnDumpClientManaged=enull;
}
/***
*_CRT_DUMP_CLIENT_M _CrtSetDumpClient() - set client dump hook
*
*Purpose:
* set client dump hook
*
*Entry:
* _CRT_DUMP_CLIENT_M pfnNewHook - new dump hook
*
*Exit:
* return previous hook
*
*Exceptions:
*
*******************************************************************************/
_MRTIMP _CRT_DUMP_CLIENT_M __cdecl _CrtSetDumpClient
(
_CRT_DUMP_CLIENT_M pfnNewHook
)
{
if(_atexit_m_appdomain(_CrtDumpClient_managed_cleanup)!=0)
{
return NULL;
}
_CRT_DUMP_CLIENT_M pfnOldHook = (_CRT_DUMP_CLIENT_M) DecodePointer(__pfnDumpClientManaged);
if (pfnNewHook)
{
__pfnDumpClientManaged = (_CRT_DUMP_CLIENT_M) EncodePointer(pfnNewHook);
_CrtSetDumpClient((_CRT_DUMP_CLIENT)_CrtDumpClient_managed_thunk);
}
else
{
_CRT_DUMP_CLIENT_M enull = (_CRT_DUMP_CLIENT_M) _encoded_null();
__pfnDumpClientManaged = enull;
_CrtSetDumpClient((_CRT_DUMP_CLIENT)NULL);
}
return pfnOldHook;
}
_MRTIMP _CRT_DUMP_CLIENT __cdecl _CrtSetDumpClient
(
int pfnNewHook
)
{
_VALIDATE_RETURN(pfnNewHook == 0, EINVAL, NULL);
return _CrtSetDumpClient((_CRT_DUMP_CLIENT)NULL);
}
/*
* The implementation here is not ideal. The problem is when to free the list.
* If we free it before process shutdown, any problem after that could not be
* reported.
*/
/***
* CCrtReportHook2DB Class for keeping track of all the report hooks.
*******************************************************************************/
/*
FUTURE: I did a trivial templatisation of this code to support W hooks. Cleanup to bind into a single template class would be nice.
*/
template<typename HookType>
static int __cdecl _CrtSetReportHook2_thunk
(
int mode,
HookType pfnNewHook
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -