windows-nt/Source/XPSP1/NT/enduser/speech/common/include/assertwithstack.h
2020-09-26 16:20:57 +08:00

116 lines
4.3 KiB
C

//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#pragma once
#ifdef ASSERT_WITH_STACK
#ifndef _WIN64
#include <windows.h>
#include <imagehlp.h>
#include <crtdbg.h>
//
//--- Constants ---------------------------------------------------------------
//
const UINT cchMaxAssertModuleLen = 12;
const UINT cchMaxAssertSymbolLen = 257;
const UINT cfrMaxAssertStackLevels = 20;
const UINT cchMaxAssertExprLen = 257;
const UINT cchMaxAssertStackLevelStringLen =
(2 * 8) + cchMaxAssertModuleLen + cchMaxAssertSymbolLen + 12;
// 2 addresses of at most 8 char, module, symbol, and the extra chars:
// 0x<address>: <module>! <symbol> + 0x<offset>\n
//
//--- Prototypes --------------------------------------------------------------
//
/****************************************************************************
* MagicDeinit *
*-------------*
* Description:
* Cleans up for the symbol loading code. Should be called before
* exiting in order to free the dynamically loaded imagehlp.dll
****************************************************************************/
void MagicDeinit(void);
/****************************************************************************
* GetStringFromStackLevels *
*--------------------------*
* Description:
* Retrieves a string from the stack frame. If more than one frame, they
* are separated by newlines. Each fram appears in this format:
*
* 0x<address>: <module>! <symbol> + 0x<offset>
****************************************************************************/
void GetStringFromStackLevels(UINT ifrStart, UINT cfrTotal, CHAR *pszString);
/****************************************************************************
* GetAddrFromStackLevel *
*-----------------------*
* Description:
* Retrieves the address of the next instruction to be executed on a
* particular stack frame.
*
* Return:
* The address as a DWORD.
****************************************************************************/
DWORD GetAddrFromStackLevel(UINT ifrStart);
/****************************************************************************
* GetStringFromAddr *
*-------------------*
* Description:
* Builds a string from an address in the format:
*
* 0x<address>: <module>! <symbol> + 0x<offset>
****************************************************************************/
void GetStringFromAddr(DWORD dwAddr, TCHAR *szString);
//
//--- _ASSERTE replacement ----------------------------------------------------
//
/****************************************************************************
* _ASSERTE *
*----------*
* Description:
* A replacement for the CRT runtime's version of _ASSERTE that also
* includes stack information in the assert.
****************************************************************************/
#undef _ASSERTE
#define _ASSERTE(expr) \
do \
{ \
if (!(expr)) \
{ \
char *pszExprWithStack = \
(char*)_alloca( \
cchMaxAssertStackLevelStringLen * \
cfrMaxAssertStackLevels + cchMaxAssertExprLen + 50 + 1); \
strcpy(pszExprWithStack, #expr); \
strcat(pszExprWithStack, "\n\n"); \
GetStringFromStackLevels(0, 10, pszExprWithStack + strlen(pszExprWithStack)); \
strcat(pszExprWithStack, "\n"); \
SYSTEMTIME sysTime; \
GetLocalTime(&sysTime); \
CHAR pszDateTime[50]; \
sprintf(pszDateTime, "\n%d.%d.%d %02d:%02d:%02d", \
sysTime.wMonth,sysTime.wDay,sysTime.wYear, \
sysTime.wHour,sysTime.wMinute,sysTime.wSecond); \
strcat(pszExprWithStack, pszDateTime); \
if (1 == _CrtDbgReport(_CRT_ASSERT, \
__FILE__, \
__LINE__, \
NULL, pszExprWithStack)) \
_CrtDbgBreak(); \
} \
} while (0) \
#endif // _WIN64
#endif // ASSERT_WITH_STACK