- Forgot to actually initialize Dbgk during system initialization, so any API would crash.

- Fix some stupid bugs in NtCreateDebugObject.
- Add tracing framework and add tracing to all of debug.c.
- Dbgk *almost* works: http://www.tinykrnl.org/dbgworking.png. Here I attach to services.exe and the kernel is sending notifications for all threads and DLLs loaded.

svn path=/trunk/; revision=24981
This commit is contained in:
Alex Ionescu 2006-11-30 04:16:35 +00:00
parent 2a4049fdfc
commit d83fcae7d1
4 changed files with 118 additions and 14 deletions

View file

@ -14,6 +14,7 @@
POBJECT_TYPE DbgkDebugObjectType;
FAST_MUTEX DbgkpProcessDebugPortMutex;
ULONG DbgkpTraceLevel = -1;
GENERIC_MAPPING DbgkDebugObjectMapping =
{
@ -47,6 +48,10 @@ DbgkpQueueMessage(IN PEPROCESS Process,
NTSTATUS Status;
BOOLEAN NewEvent;
PAGED_CODE();
DBGKTRACE(DBGK_MESSAGE_DEBUG,
"Process: %p Thread: %p Message: %p Flags: %lx\n",
Process, Thread, Message, Flags);
DBGKTRACE(DBGK_MESSAGE_DEBUG, "MessageType: %lx\n", Message->ApiNumber);
/* Check if we have to allocate a debug event */
NewEvent = (Flags & 2) ? TRUE : FALSE;
@ -191,6 +196,7 @@ DbgkpQueueMessage(IN PEPROCESS Process,
}
/* Return status */
DBGKTRACE(DBGK_MESSAGE_DEBUG, "Status: %lx\n", Status);
return Status;
}
@ -240,6 +246,7 @@ DbgkpSendApiMessage(IN OUT PDBGKM_MSG ApiMsg,
{
NTSTATUS Status;
PAGED_CODE();
DBGKTRACE(DBGK_MESSAGE_DEBUG, "ApiMsg: %p Flags: %lx\n", ApiMsg, Flags);
/* Suspend process if required */
if (Flags) DbgkpSuspendProcess();
@ -272,6 +279,7 @@ DbgkCopyProcessDebugPort(IN PEPROCESS Process,
{
PDEBUG_OBJECT DebugObject;
PAGED_CODE();
DBGKTRACE(DBGK_PROCESS_DEBUG, "Process: %p Parent: %p\n", Process, Parent);
/* Clear this process's port */
Process->DebugPort = NULL;
@ -318,6 +326,8 @@ DbgkForwardException(IN PEXCEPTION_RECORD ExceptionRecord,
PVOID Port;
BOOLEAN UseLpc = FALSE;
PAGED_CODE();
DBGKTRACE(DBGK_EXCEPTION_DEBUG,
"ExceptionRecord: %p Port: %p\n", ExceptionRecord, DebugPort);
/* Setup the API Message */
ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
@ -379,6 +389,7 @@ DbgkpFreeDebugEvent(IN PDEBUG_EVENT DebugEvent)
{
PHANDLE Handle = NULL;
PAGED_CODE();
DBGKTRACE(DBGK_OBJECT_DEBUG, "DebugEvent: %p\n", DebugEvent);
/* Check if this event had a file handle */
switch (DebugEvent->ApiMsg.ApiNumber)
@ -414,6 +425,7 @@ DbgkpWakeTarget(IN PDEBUG_EVENT DebugEvent)
{
PETHREAD Thread = DebugEvent->Thread;
PAGED_CODE();
DBGKTRACE(DBGK_OBJECT_DEBUG, "DebugEvent: %p\n", DebugEvent);
/* Check if we have to wake the thread */
if (DebugEvent->Flags & 20) PsResumeThread(Thread, NULL);
@ -457,6 +469,8 @@ DbgkpPostFakeModuleMessages(IN PEPROCESS Process,
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
PAGED_CODE();
DBGKTRACE(DBGK_PROCESS_DEBUG, "Process: %p Thread: %p DebugObject: %p\n",
Process, Thread, DebugObject);
/* Quit if there's no PEB */
if (!Peb) return STATUS_SUCCESS;
@ -493,6 +507,10 @@ DbgkpPostFakeModuleMessages(IN PEPROCESS Process,
LoadDll->DebugInfoSize = NtHeader->FileHeader.NumberOfSymbols;
}
/* Trace */
DBGKTRACE(DBGK_PROCESS_DEBUG, "Name: %wZ. Base: %p\n",
&LdrEntry->FullDllName, LdrEntry->DllBase);
/* Get the name of the DLL */
Status = MmGetFileNameForAddress(NtHeader, &ModuleName);
if (NT_SUCCESS(Status))
@ -561,6 +579,8 @@ DbgkpPostFakeThreadMessages(IN PEPROCESS Process,
BOOLEAN First;
PIMAGE_NT_HEADERS NtHeader;
PAGED_CODE();
DBGKTRACE(DBGK_THREAD_DEBUG, "Process: %p StartThread: %p Object: %p\n",
Process, StartThread, DebugObject);
/* Check if we have a start thread */
if (StartThread)
@ -669,6 +689,12 @@ DbgkpPostFakeThreadMessages(IN PEPROCESS Process,
CreateThread->StartAddress = ThisThread->StartAddress;
}
/* Trace */
DBGKTRACE(DBGK_THREAD_DEBUG, "Thread: %p. First: %lx, OldThread: %p\n",
ThisThread, First, OldThread);
DBGKTRACE(DBGK_THREAD_DEBUG, "Start Address: %p\n",
ThisThread->StartAddress);
/* Queue the message */
Status = DbgkpQueueMessage(Process,
ThisThread,
@ -726,6 +752,8 @@ DbgkpPostFakeProcessCreateMessages(IN PEPROCESS Process,
PETHREAD ReturnThread = NULL;
NTSTATUS Status;
PAGED_CODE();
DBGKTRACE(DBGK_PROCESS_DEBUG, "Process: %p DebugObject: %p\n",
Process, DebugObject);
/* Attach to the process */
KeStackAttachProcess(&Process->Pcb, &ApcState);
@ -883,6 +911,7 @@ DbgkpMarkProcessPeb(IN PEPROCESS Process)
{
KAPC_STATE ApcState;
PAGED_CODE();
DBGKTRACE(DBGK_PROCESS_DEBUG, "Process: %p\n", Process);
/* Acquire process rundown */
if (!ExAcquireRundownProtection(&Process->RundownProtect)) return;
@ -920,6 +949,8 @@ DbgkpOpenHandles(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
HANDLE Handle;
PHANDLE DupHandle;
PAGED_CODE();
DBGKTRACE(DBGK_OBJECT_DEBUG, "Process: %p Thread: %p\n",
Process, Thread);
/* Check which state this is */
switch (WaitStateChange->NewState)
@ -1035,6 +1066,8 @@ DbgkpCloseObject(IN PEPROCESS OwnerProcess OPTIONAL,
BOOLEAN DebugPortCleared = FALSE;
PLIST_ENTRY DebugEventList;
PDEBUG_EVENT DebugEvent;
DBGKTRACE(DBGK_OBJECT_DEBUG, "OwnerProcess: %p DebugObject: %p\n",
OwnerProcess, DebugObject);
/* If this isn't the last handle, do nothing */
if (HandleCount > 1) return;
@ -1122,6 +1155,8 @@ DbgkpSetProcessDebugObject(IN PEPROCESS Process,
PETHREAD ThisThread, FirstThread;
PLIST_ENTRY NextEntry;
PAGED_CODE();
DBGKTRACE(DBGK_PROCESS_DEBUG, "Process: %p DebugObject: %p\n",
Process, DebugObject);
/* Initialize the temporary list */
InitializeListHead(&TempList);
@ -1228,6 +1263,8 @@ ThreadScan:
NextEntry = DebugObject->EventList.Flink;
while (NextEntry != &DebugObject->EventList)
{
DPRINT1("Next Entry: %p\n", NextEntry);
DPRINT1("List: %p\n", &DebugObject->EventList);
/* FIXME: TODO */
KEBUGCHECK(0);
}
@ -1260,6 +1297,8 @@ DbgkClearProcessDebugObject(IN PEPROCESS Process,
IN PDEBUG_OBJECT SourceDebugObject)
{
/* FIXME: TODO */
DBGKTRACE(DBGK_PROCESS_DEBUG, "Process: %p DebugObject: %p\n",
Process, SourceDebugObject);
return STATUS_UNSUCCESSFUL;
}
@ -1330,7 +1369,7 @@ NtCreateDebugObject(OUT PHANDLE DebugHandle,
ObjectAttributes,
PreviousMode,
NULL,
sizeof(PDEBUG_OBJECT),
sizeof(DEBUG_OBJECT),
0,
0,
(PVOID*)&DebugObject);
@ -1343,7 +1382,9 @@ NtCreateDebugObject(OUT PHANDLE DebugHandle,
InitializeListHead(&DebugObject->EventList);
/* Initialize the Debug Object's Wait Event */
KeInitializeEvent(&DebugObject->EventsPresent, NotificationEvent, 0);
KeInitializeEvent(&DebugObject->EventsPresent,
NotificationEvent,
FALSE);
/* Set the Flags */
DebugObject->KillProcessOnExit = KillProcessOnExit;
@ -1355,9 +1396,6 @@ NtCreateDebugObject(OUT PHANDLE DebugHandle,
0,
NULL,
&hDebug);
ObDereferenceObject(DebugObject);
/* Check for success and return handle */
if (NT_SUCCESS(Status))
{
_SEH_TRY
@ -1372,6 +1410,8 @@ NtCreateDebugObject(OUT PHANDLE DebugHandle,
}
/* Return Status */
DBGKTRACE(DBGK_OBJECT_DEBUG, "Handle: %p DebugObject: %p\n",
hDebug, DebugObject);
return Status;
}
@ -1389,6 +1429,8 @@ NtDebugContinue(IN HANDLE DebugHandle,
BOOLEAN NeedsWake = FALSE;
CLIENT_ID ClientId;
PAGED_CODE();
DBGKTRACE(DBGK_OBJECT_DEBUG, "Handle: %p Status: %p\n",
DebugHandle, ContinueStatus);
/* Check if we were called from user mode*/
if (PreviousMode != KernelMode)
@ -1513,6 +1555,9 @@ NtDebugActiveProcess(IN HANDLE ProcessHandle,
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
PETHREAD LastThread;
NTSTATUS Status;
PAGED_CODE();
DBGKTRACE(DBGK_PROCESS_DEBUG, "Process: %p Handle: %p\n",
ProcessHandle, DebugHandle);
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
@ -1576,6 +1621,9 @@ NtRemoveProcessDebug(IN HANDLE ProcessHandle,
PDEBUG_OBJECT DebugObject;
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
NTSTATUS Status;
PAGED_CODE();
DBGKTRACE(DBGK_PROCESS_DEBUG, "Process: %p Handle: %p\n",
ProcessHandle, DebugHandle);
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
@ -1705,6 +1753,8 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle,
NTSTATUS Status = STATUS_SUCCESS;
PDEBUG_EVENT DebugEvent, DebugEvent2;
PLIST_ENTRY ListHead, NextEntry;
PAGED_CODE();
DBGKTRACE(DBGK_OBJECT_DEBUG, "Handle: %p\n", DebugHandle);
/* Clear the initial wait state change structure */
RtlZeroMemory(&WaitStateChange, sizeof(WaitStateChange));

View file

@ -792,6 +792,9 @@ ExpInitializeExecutive(IN ULONG Cpu,
/* Initialize the Process Manager */
if (!PsInitSystem()) KEBUGCHECK(PROCESS_INITIALIZATION_FAILED);
/* Initialize the User-Mode Debugging Subsystem */
DbgkInitialize();
/* Calculate the tick count multiplier */
ExpTickCountMultiplier = ExComputeTickCountMultiplier(KeMaximumIncrement);
SharedUserData->TickCountMultiplier = ExpTickCountMultiplier;

View file

@ -1,5 +1,57 @@
#ifndef __NTOSKRNL_INCLUDE_INTERNAL_DBGK_H
#define __NTOSKRNL_INCLUDE_INTERNAL_DBGK_H
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/include/dbgk.h
* PURPOSE: Internal header for the User-Mode Debugging Backend
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
//
// Define this if you want debugging support
//
#define _DBGK_DEBUG_ 0x01
//
// These define the Debug Masks Supported
//
#define DBGK_THREAD_DEBUG 0x01
#define DBGK_PROCESS_DEBUG 0x02
#define DBGK_OBJECT_DEBUG 0x04
#define DBGK_MESSAGE_DEBUG 0x08
#define DBGK_EXCEPTION_DEBUG 0x10
//
// Debug/Tracing support
//
#if _DBGK_DEBUG_
#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
#define DBGKTRACE(x, ...) \
{ \
DbgPrintEx("%s [%.16s] - ", \
__FUNCTION__, \
PsGetCurrentProcess()->ImageFileName); \
DbgPrintEx(__VA_ARGS__); \
}
#else
#define DBGKTRACE(x, ...) \
if (x & DbgkpTraceLevel) \
{ \
DbgPrint("%s [%.16s] - ", \
__FUNCTION__, \
PsGetCurrentProcess()->ImageFileName); \
DbgPrint(__VA_ARGS__); \
}
#endif
#else
#define DBGKTRACE(x, ...) DPRINT(__VA_ARGS__);
#endif
VOID
INIT_FUNCTION
NTAPI
DbgkInitialize(
VOID
);
VOID
NTAPI
@ -82,6 +134,5 @@ DbgkClearProcessDebugObject(
);
extern POBJECT_TYPE DbgkDebugObjectType;
#endif
/* EOF */

View file

@ -1,10 +1,10 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/include/ps.h
* PURPOSE: Internal header for the Process Manager
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/include/ps.h
* PURPOSE: Internal header for the Process Manager
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
//
// Define this if you want debugging support