📄 hxassert.cpp
字号:
#if defined(_WIN32) || defined(_WINDOWS)
// active popup window for the current thread
HWND hWndParent = GetActiveWindow();
#if !defined(WIN32_PLATFORM_PSPC)
if (hWndParent != NULL)
{
hWndParent = GetLastActivePopup(hWndParent);
}
#endif /* !defined(WIN32_PLATFORM_PSPC) */
// display the assert
#if !defined(WIN32_PLATFORM_PSPC)
// we remove WM_QUIT because if it is in the queue then the message box
// won't display
MSG msg;
BOOL bQuit = ::PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
int nCode = ::MessageBox
(
hWndParent,
z_szAssertMessage,
"Assertion Failed!",
MB_TASKMODAL|
MB_ICONHAND|MB_ABORTRETRYIGNORE|MB_DEFBUTTON3
#if defined(_WIN32)
|MB_SETFOREGROUND
#endif
);
if (bQuit)
PostQuitMessage(msg.wParam);
#else /* !defined(WIN32_PLATFORM_PSPC) */
int nCode = ::MessageBox
(
hWndParent,
OS_STRING(z_szAssertMessage),
OS_STRING("Assertion Failed!"),
MB_ICONHAND|MB_ABORTRETRYIGNORE
);
#endif /* !defined(WIN32_PLATFORM_PSPC) */
#elif defined (_MACINTOSH)
int nCode = HXCRT_ASSERT(z_szAssertMessage);
#elif defined (_UNIX)
const char *debugopts;
int debuglevel = 0;
int nCode = IDIGNORE;
#if defined(_MAC_UNIX)
debuglevel = 2; // default to something less extreme on Mac
#endif
if (debugopts = getenv("HX_DEBUGLEVEL"))
{
debuglevel = atoi(debugopts);
}
switch(debuglevel)
{
case 1: /* debugger */
{
fprintf(stderr, "HX_ASSERT failed: %s\n", z_szAssertMessage );
nCode = IDRETRY;
break;
}
case 2: /* terminate */
{
fprintf(stderr, "HX_ASSERT failed: %s\n", z_szAssertMessage );
nCode = IDIGNORE;
break;
}
case 3: /* silent */
{
nCode = IDIGNORE;
break;
}
case 4: /* interactive */
{
setvbuf(stdin, NULL, _IONBF, 0);
fprintf(stderr, "HX_ASSERT failed: %s\n((d)ebug (i)gnore (a)bort)? ", z_szAssertMessage );
char input = '\n';
while (input == '\n')
read(0, &input, 1);
switch (input)
{
case 'i': /* ignore */
nCode = IDIGNORE;
break;
case 'a': /* abort */
abort();
break;
case 'd':
default: /* debug */
nCode = IDRETRY;
break;
}
break;
}
case 0: /* terminate */
default:
{
fprintf(stderr, "HX_ASSERT failed: %s\n", z_szAssertMessage );
abort();
}
}
#endif
#if defined(_SYMBIAN)
int nCode = IDRETRY;
TRAPD(err, nCode = QueryAssertActionL(z_szAssertMessage));
#endif //_SYMBIAN
#if defined(_OPENWAVE)
int nCode = IDIGNORE;
// XXXSAB Fill this in!!!
# ifdef _OPENWAVE_SIMULATOR
//What to do on the emulator.
# else
//What to do on the device.
# endif
#endif
//
// END: Platform specific portion of HXAssert(). The rest of
// this function is cross-platform.
//
/////////////////////////////////////////////////////////////////
// cleanup
z_nMultiAssertCount--;
if (nCode == IDIGNORE)
{
return FALSE; // ignore
}
if (nCode == IDRETRY)
{
return TRUE;
}
HXAbort(); // should not return (but otherwise HXDebugBreak)
return TRUE;
};
/////////////////////////////////////////////////////////////////////////////
//
// HXAssertValidPointer: Helper function used by HX_ASSERT_VALID_PTR()
//
void STDMETHODCALLTYPE HXAssertValidPointer(const void* pVoid, const char* pszFileName, int nLine)
{
if (pVoid == NULL)
{
if (HXAssertFailedLine("HX_ASSERT_VALID_PTR fails on NULL pointer",pszFileName,nLine))
{
HXDebugBreak();
}
return; // quick escape
}
if (!HXIsValidAddress(pVoid))
{
if (HXAssertFailedLine("HX_ASSERT_VALID_PTR fails with illegal pointer.",pszFileName,nLine))
{
HXDebugBreak();
}
return; // quick escape
}
};
/////////////////////////////////////////////////////////////////////////////
//
// HXIsValidAddress: Helper function used by HXAssertValidPointer()
//
#ifdef _WIN16
// see comment in hxassert.h for problem with STDMETHODCALLTYPE in win16
BOOL far _cdecl HXIsValidAddress(const void* lp, ULONG32 nBytes, BOOL bReadWrite)
#else
BOOL STDMETHODCALLTYPE HXIsValidAddress(const void* lp, ULONG32 nBytes, BOOL bReadWrite)
#endif
{
/////////////////////////////////////////////////////////////////
//
// BEGIN: Platform specific portion of HXIsValidAddress(), namely,
// we need to to check if a pointer is a valid pointer.
//
#if defined(_WIN32) || defined(_WINDOWS)
// simple version using Win APIs for pointer validation.
return (
(lp != NULL)
&&
!IsBadReadPtr(lp, (UINT)nBytes)
&&
(!bReadWrite || !IsBadWritePtr((LPVOID)lp, (UINT)nBytes))
);
#else
# ifdef __MWERKS__
return TRUE;
# endif
# ifdef _UNIX
return lp != NULL;
# endif
# ifdef _SYMBIAN
return lp != NULL;
# endif
# ifdef _OPENWAVE
return lp != NULL;
# endif
#endif
//
// END: Platform specific portion of HXIsValidAddress(). The rest
// of this function is cross-platform.
//
/////////////////////////////////////////////////////////////////
}
#ifdef _WIN16
// see comment in hxassert.h for problem with STDMETHODCALLTYPE in win16
BOOL far _cdecl HXIsValidString(const char* psz, int nLength)
#else
BOOL STDMETHODCALLTYPE HXIsValidString(const char* psz, int nLength)
#endif
{
if (psz == NULL)
{
return FALSE;
}
/////////////////////////////////////////////////////////////////
//
// BEGIN: Platform specific portion of HXIsValidString(), namely,
// we need to to check if a pointer is a valid string pointer.
//
#if defined(_WIN32) || defined(_WINDOWS)
#if defined(_WIN32) && !defined(WIN32_PLATFORM_PSPC)
// simple version using Win APIs for pointer validation.
BOOL bIsBad = IsBadStringPtr(psz, nLength);
#else
// Win APIs function is buggy under 16bits, damn, let's assume its OK?
BOOL bIsBad = FALSE;
#endif
return (!bIsBad);
#else
BOOL bIsBad = FALSE;
#endif
//
// END: Platform specific portion of HXIsValidString(). The rest
// of this function is cross-platform.
//
/////////////////////////////////////////////////////////////////
return TRUE;
}
#if defined(_SYMBIAN) && !defined (__WINS__)
#include <e32std.h>
void HXDebugBreak()
{
User::Invariant();
}
#elif defined(_OPENWAVE) && !defined(_OPENWAVE_SIMULATOR)
void HXDebugBreak()
{
#error Figure out if HXDebugBreak() makes sense on target device...
}
#elif defined(_UNIX)
void HXDebugBreak()
{
static int debuggerpid = 0;
pid_t pid = getpid();
const char *pname = getenv("PROCESS_NAME");
const char *pDebuggerProcess = getenv("HX_DEBUGGER");
if (debuggerpid)
{
kill(pid, SIGSTOP);
return;
}
// This allows the user to override the debug command. The command
// called will be given process name and pid arguments
if (pDebuggerProcess)
{
char pCmdTemplate[1024], pCmd[1024]; /* Flawfinder: ignore */
SafeSprintf(pCmdTemplate, 1024, "%s %%s %%d", pDebuggerProcess);
SafeSprintf(pCmd, 1024, pCmdTemplate, pname? pname : "/dev/null", pid);
system(pCmd);
sleep(3);
return;
}
if (debuggerpid = fork()) {
sleep(3);
}
else
{
setsid();
int kid;
if (!(kid = fork()))
{
char buf[1024]; /* Flawfinder: ignore */
sprintf(buf, "%d", pid); /* Flawfinder: ignore */
if (!pname)
{
fprintf(stderr, "Need to set PROCESS_NAME to enable jit debugging\n");
fflush(0);
_exit(0);
}
if (-1 == (execlp("xterm", "xterm", "-e", "gdb", "-nw", "-nx", pname, buf, NULL)))
{
fprintf(stderr, "failed to start debugger (%s)\n", strerror(errno));
abort();
}
}
else
{
int dummy;
waitpid(kid, &dummy, 0);
fflush(0);
_exit(0);
}
}
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -