debug.h

来自「用于查询PC机上的USB端口是否有设备挂接上」· C头文件 代码 · 共 1,471 行 · 第 1/3 页

H
1,471
字号
/*****************************************************************************
 *
 *   (C) Copyright MICROSOFT Corp. 1989-1990
 *
 *****************************************************************************/

#define	NOBUGBUG	1

// XLATOFF

#if DEBLEVEL > DEBLEVELRETAIL

#ifndef Not_VxD

#ifdef WIN31COMPAT

#define Debug_Out(str)	{Out_Debug_String(str "\r\n"); _asm {int 1}}

#define	Trace_Out(str)	{Out_Debug_String(str "\r\n");}

#else // not WIN31COMPAT

#define	Debug_Out(str)	{_Debug_Out_Service(str "\r\n");}

#define	Trace_Out(str)	{_Trace_Out_Service(str "\r\n");}

#define	Debug_Printf	_Debug_Printf_Service

#endif // WIN31COMPAT

#define	Debug_OutC(cond, str)	{if(cond) {Debug_Out(str)}}
#define	Trace_OutC(cond, str)	{if(cond) {Trace_Out(str)}}

#endif // Not_VxD

#define	STATIC
#define	Trap()			{_asm {_emit 0xcc}}
#define	TrapC(cond)		{if(cond) {Trap()}}
#define	TrapFatal()		{_asm { \
				 _asm _emit 0xcc \
				 _asm _emit 0xeb \
				 _asm _emit 0xfd}}
#define	TrapFatalC(cond)	{if(cond) {TrapFatal()}}

#else // DEBLEVEL > DEBLEVELRETAIL

#ifndef Not_VxD

#define	Debug_Out(str)
#define	Trace_Out(str)
#define	Debug_OutC(cond, str)
#define	Trace_OutC(cond, str)
#define	Debug_Printf()

#endif // Not_VxD

#define	STATIC		static
#define	Trap()
#define	TrapC(cond)
#define	TrapFatal()
#define	TrapFatalC(cond)

#endif // DEBLEVEL > DEBLEVELRETAIL

#ifndef Not_VxD

#if DEBLEVEL >= DEBLEVELMAX
#define Trace_Out_DebMax(str)		Trace_Out(str)
#define Debug_Out_DebMax(str)		Debug_Out(str)
#define Trace_OutC_DebMax(cond, str)	Trace_OutC(cond, str)
#define Debug_OutC_DebMax(cond, str)	Debug_OutC(cond, str)
#define	Debug_Printf_DebMax		_Debug_Printf_Service
#define Assert_VM_Handle_DebMax(hvm)	Assert_VM_Handle(hvm)
#else
#define Trace_Out_DebMax(str)
#define Debug_Out_DebMax(str)
#define Trace_OutC_DebMax(cond, str)
#define Debug_OutC_DebMax(cond, str)
#define	Debug_Printf_DebMax()
#define Assert_VM_Handle_DebMax(hvm)
#endif

#ifdef DEBUG
#define	Queue_Out(sz, uleax, ulebx) Queue_Debug_String(sz "\r\n", uleax, ulebx)
#else
#define	Queue_Out(sz, uleax, ulebx)
#endif // DEBUG

#ifdef WIN31COMPAT
#define Assert_VM_Handle(hvm)	(VMM_TRUE)
#else
#define Assert_VM_Handle(hvm)	Debug_OutC(((struct cb_s *)hvm)->CB_Signature != VMCB_ID, "Assert_VM_Handle failed")
#endif

#ifdef WIN31COMPAT
#define Assert_Thread_Handle(ptcb)
#else
#define Assert_Thread_Handle(ptcb)	Debug_OutC(((struct tcb_s *)ptcb)->TCB_Signature != SCHED_OBJ_ID_THREAD, "Assert_Thread_Handle failed")
#endif

#endif // Not_VxD

#define	BUGBUG(d, id, note)

#define	IsDebugOnlyLoaded(pvar)	(((unsigned long)(pvar)) <= MAXSYSTEMLADDR)

#ifdef DEBUG
#define	Assert_FS	VMMCall(Assert_FS_Service)
#else
#define	Assert_FS
#endif

// XLATON

/* ASM
Assert_FS	macro
ifdef DEBUG
	VMMCall	Assert_FS_Service
endif
endm

;***	BUGBUG - Document incomplete code, temporary assumptions, etc
;
;	ENTRY	d    - date
;		id   - your email ID (eg, JeffPar)
;		note - a few words about the problem, assumption, etc,
;		       in brackets (<>)
;
;	NOBUGBUG    Disables BUGBUG messages
;	ERRBUGBUG   Forces compilation error if any BUGBUGs exist

BUGBUG	macro	d, id, note
	ifb <d>
		%out Bad date in BUGBUG
		.err
	endif
	ifb <id>
		%out Bad email id in BUGBUG
		.err
	endif
	ifndef NOBUGBUG
		%out BUGBUG d id: note
	endif
	ifdef ERRBUGBUG
		.err
	endif
endm


;***	IsDebugOnlyLoaded
;
;	ENTRY	lab - label to jump if NOT loaded if not blank
;
;	EXIT:	jumps to label, if given, if debug only segment is NOT loaded
;		ZF is clear if debug-only segment IS loaded
;
;	USES:	flags
;
;	The code we generate is
;
;	    test    [magic_address], magic_operand
;	ifnb <lab>
;	    jz	    lab
;	endif
;
;	where magic_address is the address of magic_operand.  Essentially,
;	we are `test'ing an immediate constant with itself.
;
;	If the debug-only segment is not loaded, the magic_operand
;	will be zero, because _DB0START is placed at exactly
;	MAXSYSTEMLADDR + 1 in the no-debug-only case.
;
;	If the debug-only segment is loaded, the magic_operand will
;	be nonzero because it will be offset of the actual debug-only
;	segment (relative to MAXSYSTEMLADDR + 1).
;
;	Unfortunately, RaymondC's clever version doesn't work with
;	the linker that ships with C9, C10, etc.  There are two problems:
;
;	(1) The linker sorts segments in a group alphabetically instead of
;	    leaving them in the order in which they're defined.  This
;	    used to put _DBOSTART last, so its starting address was *not*
;	    MAXSYSTEMLADDR + 1.  Renaming it to _DB0START fixed this
;	    problem.
;	(2) The linker does not always do the right thing with empty
;	    segments.  In particular, if I defined "var" as a label in
;	    _DB1CODE with no bytes associated with it, its offset wasn't
;	    calculated properly for the "mov" below.

IsDebugOnlyLoaded	macro	lab
	local	var, magic
ifdef BLD_COFF
_DB1CODE segment
var	db	?
_DB1CODE ends
	push	eax			; Save user's register
	mov	eax,OFFSET32 var	; (EAX) = address of dummy variable
	cmp	eax,MAXSYSTEMLADDR	; Does it reside in system space?
ifb <lab>
	setbe	al			;  yes, (AL) = 1; no, (AL) = 0
	or	al,al			;  yes, ZF clear; no, ZF set
endif
	pop	eax			; Restore user's register
ifnb <lab>
	ja	lab			;  no, jump to given label
endif
else
_DB0START segment
var	label	byte	
_DB0START ends
	db	0F7h, 05h		; test memory absolute with immediate
	dd	OFFSET32 magic		; magic_address
magic	dd	OFFSET32 var - (MAXSYSTEMLADDR + 1) ; magic_operand
ifnb <lab>
	jz	lab
endif
endif
	endm


;**	DPublic - Make a public symbol for debugging
;
;	A lot of debuggers only work with public symbols.  This macro
;	allows us to declare them public in debug mode but doesn't
;	litter the distributed .OBJ files with symbols which
;		1) waste space, and
;		2) facilitate reverse engineering of DOS

DPublic MACRO	arg
if DEBLEVEL GT DEBLEVELRETAIL
	public	arg
endif
        ENDM


;******************************************************************************
;
;   Assumes_Fall_Through
;
;   DESCRIPTION:
;	Used for debugging purposes only.  It will generate an error if
;	the IP <> the specified label.
;
;   PARAMETERS:
;	Label_Name = Name of label to fall-through to
;
;------------------------------------------------------------------------------

Assumes_Fall_Through MACRO L
ifndef MASM6
IF2
 IFDEF profileall
  IF (?prolog_&L - $) GT 3
  %OUT ERROR:  Fall through to &L invalid
  .ERR
  ENDIF
 ELSE
  IF (L - $) GT 3
  %OUT ERROR:  Fall through to &L invalid
  .ERR
  ENDIF
 ENDIF
ENDIF
else
 IFDEF profileall
.errnz ((?prolog_&L - $) GT 3), <ERROR: Fall through to &L invalid>
 ELSE
.errnz ((L - $) GT 3), <ERROR: Fall through to &L invalid>
 ENDIF
endif    ; not MASM6

     ENDM


ifndef Not_VxD

;******************************************************************************
;
;   Assert_VM_Handle
;
;   PARAMETERS:
;	Handle_Register = Register that contains a VM handle
;	MinDebugLevel   = Validate only if debug level is this level or higher
;			  (default = DEBLEVELNORMAL)
;	fUsesFlags      = the symbol "USES_FLAGS" if the macro is permitted
;			  to damage flags
;
;   ASSUMES:
;	Debug_Test_Valid_Handle does not destroy any registers or flags
;	unless USES_FLAGS is set, in which case flags are modified
;
;   EXIT:
;	NOTHING MODIFIED (not even flags)
;	unless USES_FLAGS is set, in which case flags are modified
;
;------------------------------------------------------------------------------
;
; Optimized for the case R = ebx, since that is by far the most common case.
;
; If DEBLEVELRETAIL: Do nothing
; If DEBLEVELNORMAL: Expand in-line for fast validation
; If DEBLEVELMAX:    Call into VMM for full validation
;

??avh_parse_one_arg macro arg
    ifidni <arg>, <USES_FLAGS>
	??_fUsesFlagsPushfd equ <>	    ; Don't need to preserve flags
	??_fUsesFlagsPopfd equ <>
    elseifnb <arg>
	??_debLevel = arg
    endif
endm

??avh_parse_args macro DL, fUSES_FLAGS
	??_fUsesFlagsPushfd equ <pushfd>    ; Preserve flags by default
	??_fUsesFlagsPopfd equ <popfd>
	??_debLevel = DEBLEVELNORMAL	    ; Default deblevel
	??avh_parse_one_arg <DL>
	??avh_parse_one_arg <fUSES_FLAGS>
endm

Assert_VM_Handle MACRO R, DL, fUSES_FLAGS
	LOCAL l1

IF DEBLEVEL GT DEBLEVELRETAIL

	??avh_parse_args <DL>, <fUSES_FLAGS>

IF DEBLEVEL GE ??_debLevel

IFNDEF WIN31COMPAT
IF DEBLEVEL LT DEBLEVELMAX
	??_fUsesFlagsPushfd
	cmp	[R].CB_Signature, VMCB_ID
	je	SHORT l1
ENDIF
ENDIF

IFDIFI <ebx>,<R>	
	push	ebx
	mov	ebx, R
ENDIF
	VMMCall	Debug_Test_Valid_Handle
IFDIFI <ebx>, <R>
	pop	ebx
ENDIF

IFNDEF WIN31COMPAT
IF DEBLEVEL LT DEBLEVELMAX
l1:
	??_fUsesFlagsPopfd
ENDIF
ENDIF

ENDIF

ENDIF
	ENDM

;******************************************************************************
;
;   Assert_Thread_Handle
;
;   PARAMETERS:
;       Handle_Register = Register that contains a thread handle
;	MinDebugLevel   = Validate only if debug level is this level or higher
;			  (default = DEBLEVELNORMAL)
;	fUsesFlags      = the symbol "USES_FLAGS" if the macro is permitted
;			  to damage flags
;
;   ASSUMES:
;       Debug_Test_Valid_Thread_Handle does not destroy any registers or flags
;	unless USES_FLAGS is set, in which case flags are modified
;
;   EXIT:
;	NOTHING MODIFIED (not even flags)
;	unless USES_FLAGS is set, in which case flags are modified
;
;------------------------------------------------------------------------------
;
; Optimized for the case R = edi, since that is by far the most common case.
;
; If DEBLEVELRETAIL: Do nothing
; If DEBLEVELNORMAL: Expand in-line for fast validation
; If DEBLEVELMAX:    Call into VMM for full validation

Assert_Thread_Handle MACRO R, DL, fUSES_FLAGS
	LOCAL l1

IF DEBLEVEL GT DEBLEVELRETAIL

	??avh_parse_args <DL>, <fUSES_FLAGS>

IF DEBLEVEL GE ??_debLevel

IF DEBLEVEL LT DEBLEVELMAX
	??_fUsesFlagsPushfd
	cmp	dword ptr [R.TCB_Signature], SCHED_OBJ_ID_THREAD
	je	SHORT l1
ENDIF
			
IFDIFI <edi>,<R>
        push    edi
        mov     edi, R
ENDIF
        VMMCall Debug_Test_Valid_Thread_Handle
IFDIFI <edi>,<R>
        pop     edi
ENDIF

IF DEBLEVEL LT DEBLEVELMAX
l1:
	??_fUsesFlagsPopfd
ENDIF

ENDIF

ENDIF
	ENDM

;******************************************************************************
;
;   Assert_Cur_Thread_Handle (Register)
;
;   DESCRIPTION: Verifies that the register contains the current thread handle
;
;   ENTRY:
;
;   EXIT:
;
;   USES:
;
;==============================================================================
;
; Optimized for the case R = edi, since that is by far the most common case.

Assert_Cur_Thread_Handle MACRO R, DL
	LOCAL myDebLevel
	LOCAL	OK

IF DEBLEVEL GT DEBLEVELRETAIL

IFB <DL>
	myDebLevel EQU DEBLEVELNORMAL
ELSE
	myDebLevel EQU <DL>
ENDIF

IF DEBLEVEL GE myDebLevel

IFDIFI <edi>,<R>
        push    edi
        mov     edi, R
ENDIF
        VMMCall Debug_Test_Cur_Thread
IFDIFI <edi>,<R>
        pop     edi
ENDIF

ENDIF

ENDIF
	ENDM

;******************************************************************************
;
;   Debug_Printf
;
;   ENTRY:	fmt - format string
;		args - printf arguments enclosed with <>
;		dl - optional DEBLEVEL
;
;   USES: 	NONE
;
;------------------------------------------------------------------------------

Debug_Printf	macro	fmt, args, dl
	local	fmtlab, myDebLevel

ife ?_DBOCODE
    ??_fDoit = VMM_TRUE
else
    ??_fDoit = FALSE
endif

if DEBLEVEL GT DEBLEVELRETAIL

ifb <dl>
	myDebLevel EQU <DEBLEVELNORMAL>
else
	myDebLevel EQU <dl>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?