132 lines
3.1 KiB
C
132 lines
3.1 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1989 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
assert.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module implements the RtlAssert function that is referenced by the
|
||
|
debugging version of the ASSERT macro defined in NTDEF.H
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Steve Wood (stevewo) 03-Oct-1989
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Jay Krell (a-JayK) November 2000
|
||
|
added RtlAssert2, support for __FUNCTION__ (lost the change to ntrtl.w, will reapply later)
|
||
|
added break Once instead of the usual dumb Break repeatedly
|
||
|
--*/
|
||
|
|
||
|
#include <nt.h>
|
||
|
#include <ntrtl.h>
|
||
|
#include <zwapi.h>
|
||
|
|
||
|
//
|
||
|
// RtlAssert is not called unless the caller is compiled with DBG non-zero
|
||
|
// therefore it does no harm to always have this routine in the kernel.
|
||
|
// This allows checked drivers to be thrown on the system and have their
|
||
|
// asserts be meaningful.
|
||
|
//
|
||
|
|
||
|
#define RTL_ASSERT_ALWAYS_ENABLED 1
|
||
|
|
||
|
#ifdef _X86_
|
||
|
#pragma optimize("y", off) // RtlCaptureContext needs EBP to be correct
|
||
|
#endif
|
||
|
|
||
|
#undef RtlAssert
|
||
|
#undef RtlAssert2
|
||
|
|
||
|
VOID
|
||
|
NTAPI
|
||
|
RtlAssert2(
|
||
|
IN CONST CHAR* FailedAssertion,
|
||
|
IN CONST CHAR* FileName,
|
||
|
IN ULONG LineNumber,
|
||
|
IN CONST CHAR* Message OPTIONAL,
|
||
|
IN CONST CHAR* Function OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
#if DBG || RTL_ASSERT_ALWAYS_ENABLED
|
||
|
char Response[ 2 ];
|
||
|
#ifndef BLDR_KERNEL_RUNTIME
|
||
|
CONTEXT Context;
|
||
|
|
||
|
RtlCaptureContext( &Context );
|
||
|
#endif
|
||
|
|
||
|
while (TRUE) {
|
||
|
DbgPrint( "\n*** Assertion failed: %s%s\n*** %s%s%sSource File: %s, line %ld\n\n",
|
||
|
Message ? Message : "",
|
||
|
FailedAssertion,
|
||
|
Function ? "Function: " : "",
|
||
|
Function ? Function : "",
|
||
|
Function ? ", " : "",
|
||
|
FileName,
|
||
|
LineNumber
|
||
|
);
|
||
|
DbgPrompt( "Break repeatedly, break Once, Ignore, terminate Process, or terminate Thread (boipt)? ",
|
||
|
Response,
|
||
|
sizeof( Response )
|
||
|
);
|
||
|
switch (Response[0]) {
|
||
|
case 'B':
|
||
|
case 'b':
|
||
|
case 'O':
|
||
|
case 'o':
|
||
|
#ifndef BLDR_KERNEL_RUNTIME
|
||
|
DbgPrint( "Execute '.cxr %p' to dump context\n", &Context);
|
||
|
#endif
|
||
|
DbgBreakPoint();
|
||
|
if (Response[0] == 'o' || Response[0] == 'O')
|
||
|
return;
|
||
|
break;
|
||
|
|
||
|
case 'I':
|
||
|
case 'i':
|
||
|
return;
|
||
|
|
||
|
case 'P':
|
||
|
case 'p':
|
||
|
ZwTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
|
||
|
break;
|
||
|
|
||
|
case 'T':
|
||
|
case 't':
|
||
|
ZwTerminateThread( NtCurrentThread(), STATUS_UNSUCCESSFUL );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DbgBreakPoint();
|
||
|
ZwTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Keep this for binary compatibility.
|
||
|
//
|
||
|
|
||
|
VOID
|
||
|
NTAPI
|
||
|
RtlAssert(
|
||
|
IN PVOID FailedAssertion,
|
||
|
IN PVOID FileName,
|
||
|
IN ULONG LineNumber,
|
||
|
IN PCHAR Message OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
#if DBG || RTL_ASSERT_ALWAYS_ENABLED
|
||
|
RtlAssert2(FailedAssertion, FileName, LineNumber, Message, NULL);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifdef _X86_
|
||
|
#pragma optimize("", on)
|
||
|
#endif
|