296 lines
9.0 KiB
C
296 lines
9.0 KiB
C
/*++
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
udbg.c
|
|
|
|
Abstract:
|
|
Usermode test for debugger
|
|
|
|
Author:
|
|
Mark Lucovsky (markl) 19-Jan-1990
|
|
--*/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <ntdbg.h>
|
|
|
|
HANDLE DebugPort;
|
|
|
|
|
|
NTSTATUS ThreadThatExits (IN PVOID ThreadParameter)
|
|
{
|
|
NtTerminateThread(NtCurrentThread(),(NTSTATUS) ThreadParameter );
|
|
}
|
|
|
|
|
|
ULONG foo(PULONG l)
|
|
{
|
|
//ULONG x;
|
|
//x = *l;
|
|
//return x + 1;
|
|
|
|
return *l;
|
|
}
|
|
|
|
|
|
NTSTATUS ThreadThatExcepts (IN PVOID ThreadParameter)
|
|
{
|
|
foo((PULONG)0x00000001);
|
|
NtTerminateThread(NtCurrentThread(),(NTSTATUS) ThreadParameter );
|
|
}
|
|
|
|
|
|
NTSTATUS ThreadThatSpins (IN PVOID ThreadParameter)
|
|
{
|
|
for(;;);
|
|
NtTerminateThread(NtCurrentThread(),STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
UdbgTest1()
|
|
{
|
|
NTSTATUS st;
|
|
HANDLE ExitThread, SpinThread, DebugProcess;
|
|
CLIENT_ID ExitClientId, SpinClientId;
|
|
DBGKM_APIMSG m;
|
|
PDBGKM_CREATE_THREAD CreateThreadArgs;
|
|
PDBGKM_CREATE_PROCESS CreateProcessArgs;
|
|
PDBGKM_EXIT_THREAD ExitThreadArgs;
|
|
PDBGKM_EXIT_PROCESS ExitProcessArgs;
|
|
ULONG Psp;
|
|
|
|
DbgPrint("UdbgTest1: (1)...\n");
|
|
|
|
// Verify that a process can be created with a debug port.
|
|
st = NtCreateProcess(&DebugProcess, PROCESS_ALL_ACCESS, NULL, NtCurrentProcess(), FALSE, NULL, DebugPort, NULL);
|
|
ASSERT(NT_SUCCESS(st));
|
|
st = RtlCreateUserThread(DebugProcess,NULL,TRUE,0L,0L,0L,ThreadThatExits,(PVOID) STATUS_ABANDONED,&ExitThread,&ExitClientId);
|
|
ASSERT(NT_SUCCESS(st));
|
|
st = RtlCreateUserThread(DebugProcess,NULL,TRUE,0L,0L,0L,ThreadThatSpins,NULL,&SpinThread,&SpinClientId);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
DbgPrint("UdbgTest1: (2)...\n");
|
|
|
|
// Verify that CreateProcess Messages Arrive, and that they are correct
|
|
st = NtResumeThread(SpinThread,NULL);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = NtReplyWaitReceivePort(DebugPort,NULL,NULL,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
ASSERT(m.ApiNumber == DbgKmCreateProcessApi);
|
|
|
|
CreateThreadArgs = &m.u.CreateProcess.InitialThread;
|
|
CreateProcessArgs = &m.u.CreateProcess;
|
|
ASSERT( CreateThreadArgs->SubSystemKey == 0 && CreateThreadArgs->StartAddress == (PVOID)ThreadThatSpins );
|
|
ASSERT( CreateProcessArgs->SubSystemKey == 0);
|
|
|
|
DbgPrint("UdbgTest1: (3)...\n");
|
|
|
|
// Verify that other threads in the process are properly suspended
|
|
st = NtSuspendThread(ExitThread,&Psp);
|
|
ASSERT(NT_SUCCESS(st) && Psp == 2);
|
|
|
|
st = NtResumeThread(ExitThread,&Psp);
|
|
ASSERT(NT_SUCCESS(st) && Psp == 3);
|
|
|
|
st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
DbgPrint("UdbgTest1: (4)...\n");
|
|
|
|
// Verify that CreateThread Messages Arrive, and that they are correct
|
|
st = NtResumeThread(ExitThread,&Psp);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = NtReplyWaitReceivePort(DebugPort,NULL,NULL,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
ASSERT(m.ApiNumber == DbgKmCreateThreadApi);
|
|
|
|
CreateThreadArgs = &m.u.CreateThread;
|
|
ASSERT( CreateThreadArgs->SubSystemKey == 0 && CreateThreadArgs->StartAddress == (PVOID)ThreadThatExits );
|
|
|
|
st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
DbgPrint("UdbgTest1: (5)...\n");
|
|
|
|
// Verify that ExitThread Messages Arrive, and that they are correct
|
|
st = NtReplyWaitReceivePort(DebugPort,NULL,NULL,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
ASSERT(m.ApiNumber == DbgKmExitThreadApi);
|
|
|
|
ExitThreadArgs = &m.u.ExitThread;
|
|
ASSERT( ExitThreadArgs->ExitStatus == STATUS_ABANDONED );
|
|
|
|
st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = NtWaitForSingleObject(ExitThread,FALSE,NULL);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
DbgPrint("UdbgTest1: (6)...\n");
|
|
|
|
// Verify that ExitThread Messages Arrive, and that they are correct
|
|
st = NtTerminateProcess(DebugProcess,STATUS_REPARSE);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = NtReplyWaitReceivePort(DebugPort,NULL,NULL,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
ASSERT(m.ApiNumber == DbgKmExitThreadApi);
|
|
|
|
ExitThreadArgs = &m.u.ExitThread;
|
|
ASSERT( ExitThreadArgs->ExitStatus == STATUS_REPARSE );
|
|
|
|
st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
DbgPrint("UdbgTest1: (7)...\n");
|
|
|
|
// Verify that ExitProcess Messages Arrive, and that they are correct
|
|
st = NtReplyWaitReceivePort(DebugPort,NULL,NULL,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
ASSERT(m.ApiNumber == DbgKmExitProcessApi);
|
|
|
|
ExitProcessArgs = &m.u.ExitProcess;
|
|
ASSERT( ExitProcessArgs->ExitStatus == STATUS_REPARSE );
|
|
|
|
st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = NtWaitForSingleObject(ExitThread,FALSE,NULL);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = NtWaitForSingleObject(DebugProcess,FALSE,NULL);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
NtClose(ExitThread);
|
|
NtClose(SpinThread);
|
|
NtClose(DebugProcess);
|
|
|
|
DbgPrint("UdbgTest1: END OF TEST ***\n");
|
|
}
|
|
|
|
|
|
UdbgTest2()
|
|
{
|
|
NTSTATUS st;
|
|
HANDLE ExceptionThread, DebugProcess;
|
|
DBGKM_APIMSG m;
|
|
PDBGKM_CREATE_THREAD CreateThreadArgs;
|
|
PDBGKM_CREATE_PROCESS CreateProcessArgs;
|
|
PDBGKM_EXIT_THREAD ExitThreadArgs;
|
|
PDBGKM_EXIT_PROCESS ExitProcessArgs;
|
|
PDBGKM_EXCEPTION ExceptionArgs;
|
|
ULONG Psp;
|
|
|
|
DbgPrint("UdbgTest2: (1)...\n");
|
|
|
|
// Verify that a process can be created with a debug port.
|
|
st = NtCreateProcess(&DebugProcess,PROCESS_ALL_ACCESS,NULL,NtCurrentProcess(),FALSE,NULL,DebugPort,NULL);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = RtlCreateUserThread(DebugProcess,NULL,TRUE,0L,0L,0L,ThreadThatExcepts,(PVOID) STATUS_ABANDONED,&ExceptionThread,NULL);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
DbgPrint("UdbgTest2: (2)...\n");
|
|
|
|
// Verify that CreateThread Messages Arrive, and that they are correct
|
|
st = NtResumeThread(ExceptionThread,NULL);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = NtReplyWaitReceivePort(DebugPort,NULL,NULL,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
ASSERT(m.ApiNumber == DbgKmCreateProcessApi);
|
|
|
|
CreateThreadArgs = &m.u.CreateProcess.InitialThread;
|
|
CreateProcessArgs = &m.u.CreateProcess;
|
|
ASSERT( CreateThreadArgs->SubSystemKey == 0 && CreateThreadArgs->StartAddress == (PVOID)ThreadThatExcepts );
|
|
ASSERT( CreateProcessArgs->SubSystemKey == 0);
|
|
|
|
st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
DbgPrint("UdbgTest2: (3)...\n");
|
|
|
|
// Verify that First Chance Exception Messages Arrive, and that they are correct
|
|
st = NtReplyWaitReceivePort(DebugPort,NULL,NULL,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
ASSERT(m.ApiNumber == DbgKmExceptionApi);
|
|
|
|
ExceptionArgs = &m.u.Exception;
|
|
ASSERT( ExceptionArgs->FirstChance == TRUE );
|
|
|
|
m.ReturnedStatus = DBG_EXCEPTION_NOT_HANDLED;
|
|
|
|
st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
DbgPrint("UdbgTest2: (4)...\n");
|
|
|
|
// Verify that First Chance Exception Messages Arrive, and that they are correct
|
|
st = NtReplyWaitReceivePort(DebugPort,NULL,NULL,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
ASSERT(m.ApiNumber == DbgKmExceptionApi);
|
|
|
|
ExceptionArgs = &m.u.Exception;
|
|
ASSERT( ExceptionArgs->FirstChance == FALSE );
|
|
|
|
m.ReturnedStatus = DBG_EXCEPTION_HANDLED;
|
|
|
|
skip4:
|
|
st = NtTerminateProcess(DebugProcess,STATUS_REPARSE);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = NtReplyWaitReceivePort(DebugPort,NULL,NULL,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
ASSERT(m.ApiNumber == DbgKmExitThreadApi);
|
|
|
|
ExitThreadArgs = &m.u.ExitThread;
|
|
ASSERT( ExitThreadArgs->ExitStatus == STATUS_REPARSE );
|
|
|
|
st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
DbgPrint("UdbgTest2: (5)...\n");
|
|
|
|
// Verify that ExitProcess Messages Arrive, and that they are correct
|
|
st = NtReplyWaitReceivePort(DebugPort,NULL,NULL,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
ASSERT(m.ApiNumber == DbgKmExitProcessApi);
|
|
|
|
ExitProcessArgs = &m.u.ExitProcess;
|
|
ASSERT( ExitProcessArgs->ExitStatus == STATUS_REPARSE );
|
|
|
|
st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = NtWaitForSingleObject(ExceptionThread,FALSE,NULL);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
st = NtWaitForSingleObject(DebugProcess,FALSE,NULL);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
NtClose(ExceptionThread);
|
|
NtClose(DebugProcess);
|
|
|
|
DbgPrint("UdbgTest2: END OF TEST ***\n");
|
|
}
|
|
|
|
|
|
main()
|
|
{
|
|
NTSTATUS st;
|
|
OBJECT_ATTRIBUTES Obja;
|
|
|
|
InitializeObjectAttributes(&Obja, NULL, 0, NULL, NULL);
|
|
st = NtCreatePort(&DebugPort, &Obja, 0L, 256, 256 * 16);
|
|
ASSERT(NT_SUCCESS(st));
|
|
|
|
UdbgTest2();
|
|
UdbgTest1();
|
|
} |