windows-nt/Source/XPSP1/NT/ds/security/common/debug/debuglib/assert.c
2020-09-26 16:20:57 +08:00

226 lines
6.2 KiB
C

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: assert.c
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 4-03-95 RichardW Created
//
//----------------------------------------------------------------------------
#include "debuglib.h"
typedef ULONG (NTAPI * DBGPROMPT)(PCH, PCH, ULONG);
#define DSYSASSERT_FAILED 0x00000001
#define DSYSASSERT_ERROR 0x00000002
#define DSYSASSERT_WARN 0x00000004
DWORD __AssertInfoLevel = DSYSASSERT_FAILED;
DebugModule __AssertModule = {NULL, &__AssertInfoLevel, 0, 7,
NULL, 0, 0, "Assert",
{"FAILED", "Error", "Warning", "",
"", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "" }
};
DebugModule * __pAssertModule = &__AssertModule;
VOID
__AssertDebugOut(
ULONG Mask,
CHAR * Format,
... )
{
va_list ArgList;
va_start(ArgList, Format);
_DebugOut( __pAssertModule, Mask, Format, ArgList);
}
BOOL
DbgpStartDebuggerOnMyself(BOOL UseKernelDebugger)
{
WCHAR cch[80];
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
SECURITY_ATTRIBUTES sa;
HANDLE hEvent;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = &DbgpPartySd;
sa.bInheritHandle = TRUE;
hEvent = CreateEvent(&sa, TRUE, FALSE, NULL);
swprintf(cch, TEXT("ntsd %s -p %ld -e %ld -g"), (UseKernelDebugger ? "-d" : ""),
GetCurrentProcessId(), hEvent);
ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
StartupInfo.cb = sizeof(STARTUPINFO);
if (!UseKernelDebugger)
{
StartupInfo.lpDesktop = TEXT("WinSta0\\Default");
}
if (CreateProcess( NULL,
cch,
NULL,
NULL,
TRUE,
HIGH_PRIORITY_CLASS,
NULL,
NULL,
&StartupInfo,
&ProcessInformation) )
{
CloseHandle(ProcessInformation.hProcess);
CloseHandle(ProcessInformation.hThread);
WaitForSingleObject(hEvent, 60000);
CloseHandle(hEvent);
return(TRUE);
}
else
{
__AssertDebugOut( DSYSASSERT_ERROR, "Could not start debugger '%ws', %d\n", cch, GetLastError());
return(FALSE);
}
}
VOID
_DsysAssertEx(
PVOID FailedAssertion,
PVOID FileName,
ULONG LineNumber,
PCHAR Message,
ULONG ContinueCode
)
{
CHAR Response[2];
HMODULE hNtDll;
DBGPROMPT DbgPromptFn;
if (DbgpHeader)
{
__pAssertModule->pHeader = DbgpHeader;
if (DbgpHeader->fDebug & DEBUG_DISABLE_ASRT)
{
__AssertDebugOut( DSYSASSERT_WARN, "Assertion at %s:%d disabled\n",
FileName, LineNumber);
return;
}
}
if (Message)
__AssertDebugOut( DSYSASSERT_FAILED, "%s: %s (%s:%d)\n",
Message, FailedAssertion, FileName, LineNumber);
else
__AssertDebugOut( DSYSASSERT_FAILED, "%s (%s:%d)\n",
FailedAssertion, FileName, LineNumber);
switch (ContinueCode)
{
case DSYSDBG_ASSERT_BREAK:
__AssertDebugOut( DSYSASSERT_FAILED, "\tBreakpoint\n");
DebugBreak();
break;
case DSYSDBG_ASSERT_CONTINUE:
__AssertDebugOut( DSYSASSERT_WARN, "\tContinuing\n");
return;
case DSYSDBG_ASSERT_SUSPEND:
__AssertDebugOut( DSYSASSERT_WARN, "\tSuspending Thread %d\n", GetCurrentThreadId());
SuspendThread(GetCurrentThread());
return;
case DSYSDBG_ASSERT_KILL:
__AssertDebugOut( DSYSASSERT_WARN, "\tKill Thread (exit %x)\n", NtCurrentTeb()->LastStatusValue);
TerminateThread(GetCurrentThread(), NtCurrentTeb()->LastStatusValue);
return;
case DSYSDBG_ASSERT_DEBUGGER:
if (IsDebuggerPresent())
{
DebugBreak();
}
else
{
if (DbgpHeader)
{
if ((DbgpHeader->fDebug & DEBUG_PROMPTS) == 0)
{
DbgpStartDebuggerOnMyself(DbgpHeader->fDebug & DEBUG_USE_KDEBUG);
DebugBreak();
break;
}
}
hNtDll = LoadLibrary(TEXT("ntdll.dll"));
if (hNtDll)
{
DbgPromptFn = (DBGPROMPT) GetProcAddress(hNtDll, "DbgPrompt");
}
else
{
DbgPromptFn = NULL;
}
while (TRUE)
{
if (DbgPromptFn)
{
DbgPromptFn( "Start Debugger, Break, Ignore (dbi)?",
Response, sizeof(Response));
switch (Response[0])
{
case 'i':
case 'I':
return;
case 'd':
case 'D':
DbgpStartDebuggerOnMyself(DbgpHeader ? (DbgpHeader->fDebug & DEBUG_USE_KDEBUG) : TRUE );
case 'b':
case 'B':
DebugBreak();
return;
}
}
else
{
DbgpStartDebuggerOnMyself(TRUE);
DebugBreak();
return;
}
}
}
break;
default:
__AssertDebugOut( DSYSASSERT_ERROR, "Unknown continue code for assert: %d\n",
ContinueCode);
return;
}
}