- Add tracing in process/thread.c as well.

- Add a new tracing class/macro for reference counts and add it in kill/process/thread.c.
- Remove tracing TODO from kernel fun.

svn path=/trunk/; revision=23254
This commit is contained in:
Alex Ionescu 2006-07-23 19:45:16 +00:00
parent 6cf55b644f
commit 881a60f895
6 changed files with 93 additions and 19 deletions

View file

@ -27,7 +27,6 @@
// Ps:
// - Figure out why processes don't die.
// - Generate process cookie for user-more thread.
// - Add tracing.
//
// Ob:
// - Possible bug in deferred deletion under Cc Rewrite branch.

View file

@ -23,6 +23,7 @@
#define PS_STATE_DEBUG 0x40
#define PS_QUOTA_DEBUG 0x80
#define PS_KILL_DEBUG 0x100
#define PS_REF_DEBUG 0x200
//
// Debug/Tracing support
@ -46,8 +47,13 @@
DbgPrint(__VA_ARGS__); \
}
#endif
#define PSREFTRACE(x) \
PSTRACE(PS_REF_DEBUG, \
"Pointer Count: %lx\n", \
OBJECT_TO_OBJECT_HEADER(x)->PointerCount);
#else
#define PSTRACE(x, ...) DPRINT(__VA_ARGS__);
#define PSREFTRACE(x)
#endif
//

View file

@ -85,6 +85,7 @@ PspTerminateProcess(IN PEPROCESS Process,
PAGED_CODE();
PSTRACE(PS_KILL_DEBUG,
"Process: %p ExitStatus: %p\n", Process, ExitStatus);
PSREFTRACE(Process);
/* Check if this is a Critical Process */
if (Process->BreakOnTermination)
@ -103,7 +104,9 @@ PspTerminateProcess(IN PEPROCESS Process,
while (Thread)
{
/* Kill it */
PSREFTRACE(Thread);
PspTerminateThreadByPointer(Thread, ExitStatus, FALSE);
PSREFTRACE(Thread);
Thread = PsGetNextProcessThread(Process, Thread);
}
@ -111,6 +114,7 @@ PspTerminateProcess(IN PEPROCESS Process,
if (Process->ObjectTable) ObClearProcessHandleTable(Process);
/* Return success*/
PSREFTRACE(Process);
return STATUS_SUCCESS;
}
@ -181,6 +185,7 @@ PspReapRoutine(IN PVOID Context)
/* Dereference this thread */
ObDereferenceObject(Thread);
PSREFTRACE(Thread);
} while ((NextEntry != NULL) && (NextEntry != (PVOID)1));
/* Remove magic value, keep looping if it got changed */
@ -195,6 +200,7 @@ PspDeleteProcess(IN PVOID ObjectBody)
KAPC_STATE ApcState;
PAGED_CODE();
PSTRACE(PS_KILL_DEBUG, "ObjectBody: %p\n", ObjectBody);
PSREFTRACE(Process);
/* Check if it has an Active Process Link */
if (Process->ActiveProcessLinks.Flink)
@ -316,6 +322,7 @@ PspDeleteProcess(IN PVOID ObjectBody)
/* Destroy the Quota Block */
PspDestroyQuotaBlock(Process);
PSREFTRACE(Process);
}
VOID
@ -326,6 +333,7 @@ PspDeleteThread(IN PVOID ObjectBody)
PEPROCESS Process = Thread->ThreadsProcess;
PAGED_CODE();
PSTRACE(PS_KILL_DEBUG, "ObjectBody: %p\n", ObjectBody);
PSREFTRACE(Thread);
ASSERT(Thread->Tcb.Win32Thread == NULL);
/* Check if we have a stack */
@ -351,6 +359,7 @@ PspDeleteThread(IN PVOID ObjectBody)
PspDeleteThreadSecurity(Thread);
/* Make sure the thread was inserted, before continuing */
PSREFTRACE(Thread);
if (!Process) return;
/* Check if the thread list is valid */
@ -370,6 +379,8 @@ PspDeleteThread(IN PVOID ObjectBody)
/* Dereference the Process */
ObDereferenceObject(Process);
PSREFTRACE(Thread);
PSREFTRACE(Process);
}
/*
@ -401,6 +412,8 @@ PspExitThread(IN NTSTATUS ExitStatus)
ASSERT((Thread) == PsGetCurrentThread());
/* Can't terminate a thread if it attached another process */
PSREFTRACE(Thread);
PSREFTRACE(CurrentProcess);
if (KeIsAttachedProcess())
{
/* Bugcheck */
@ -624,6 +637,7 @@ TryAgain2:
PsW32ThreadCalloutExit);
/* If we are the last thread and have a W32 Process */
PSREFTRACE(Thread);
if ((Last) && (CurrentProcess->Win32Process))
{
/* Run it down too */
@ -687,6 +701,8 @@ TryAgain2:
ASSERT(Thread->Tcb.CombinedApcDisable == 0);
/* Check if this is the final thread or not */
PSREFTRACE(Thread);
PSREFTRACE(CurrentProcess);
if (Last)
{
/* Set the process exit time */
@ -711,6 +727,7 @@ TryAgain2:
/* Kill the process in the Object Manager */
ObKillProcess(CurrentProcess);
PSREFTRACE(CurrentProcess);
/* Check if we have a section object */
if (CurrentProcess->SectionObject)
@ -788,6 +805,8 @@ TryAgain2:
if (Last) KeSetProcess(&CurrentProcess->Pcb, 0, FALSE);
/* Terminate the Thread from the Scheduler */
PSREFTRACE(Thread);
PSREFTRACE(CurrentProcess);
KeTerminateThread(0);
}
@ -868,6 +887,7 @@ PspTerminateThreadByPointer(IN PETHREAD Thread,
ULONG Flags;
PAGED_CODE();
PSTRACE(PS_KILL_DEBUG, "Thread: %p ExitStatus: %p\n", Thread, ExitStatus);
PSREFTRACE(Thread);
/* Check if this is a Critical Thread, and Bugcheck */
if (Thread->BreakOnTermination)
@ -932,6 +952,7 @@ PspTerminateThreadByPointer(IN PETHREAD Thread,
ExFreePool(Apc);
/* Return Status */
PSREFTRACE(Thread);
return Status;
}
@ -944,6 +965,7 @@ PspExitProcess(IN BOOLEAN LastThread,
PAGED_CODE();
PSTRACE(PS_KILL_DEBUG,
"LastThread: %p Process: %p\n", LastThread, Process);
PSREFTRACE(Process);
/* Set Process Exit flag */
InterlockedOr((PLONG)&Process->Flags, PSF_PROCESS_EXITING_BIT);
@ -975,6 +997,7 @@ PspExitProcess(IN BOOLEAN LastThread,
}
/* Check if we are the last thread */
PSREFTRACE(Process);
if (LastThread)
{
/* Check if we have to set the Timer Resolution */

View file

@ -97,6 +97,8 @@ PsGetNextProcessThread(IN PEPROCESS Process,
PETHREAD FoundThread = NULL;
PLIST_ENTRY ListHead, Entry;
PAGED_CODE();
PSTRACE(PS_PROCESS_DEBUG,
"Process: %p Thread: %p\n", Process, Thread);
/* Lock the process */
KeEnterCriticalRegion();
@ -147,6 +149,7 @@ PsGetNextProcess(IN PEPROCESS OldProcess)
PLIST_ENTRY Entry, ListHead;
PEPROCESS FoundProcess = NULL;
PAGED_CODE();
PSTRACE(PS_PROCESS_DEBUG, "Process: %p\n", OldProcess);
/* Acquire the Active Process Lock */
KeAcquireGuardedMutex(&PspActiveProcessMutex);
@ -195,6 +198,7 @@ PspComputeQuantumAndPriority(IN PEPROCESS Process,
ULONG i;
UCHAR LocalQuantum, MemoryPriority;
PAGED_CODE();
PSTRACE(PS_PROCESS_DEBUG, "Process: %p Mode: %lx\n", Process, Mode);
/* Check if this is a foreground process */
if (Mode == PsProcessPriorityForeground)
@ -256,6 +260,8 @@ PsChangeQuantumTable(IN BOOLEAN Immediate,
UCHAR Quantum;
PCHAR QuantumTable;
PAGED_CODE();
PSTRACE(PS_PROCESS_DEBUG,
"%lx PrioritySeparation: %lx\n", Immediate, PrioritySeparation);
/* Write the current priority separation */
PsPrioritySeparation = PspPrioritySeparationFromMask(PrioritySeparation);
@ -362,12 +368,12 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
PDBGK_DEBUG_OBJECT DebugObject;
PSECTION_OBJECT SectionObject;
NTSTATUS Status, AccessStatus;
KPROCESSOR_MODE PreviousMode;
PHYSICAL_ADDRESS DirectoryTableBase;
PHYSICAL_ADDRESS DirectoryTableBase = {{0}};
KAFFINITY Affinity;
HANDLE_TABLE_ENTRY CidEntry;
PETHREAD CurrentThread;
PEPROCESS CurrentProcess;
PETHREAD CurrentThread = PsGetCurrentThread();
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PEPROCESS CurrentProcess = PsGetCurrentProcess();
ULONG MinWs, MaxWs;
ACCESS_STATE LocalAccessState;
PACCESS_STATE AccessState = &LocalAccessState;
@ -377,14 +383,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
PSECURITY_DESCRIPTOR SecurityDescriptor;
SECURITY_SUBJECT_CONTEXT SubjectContext;
PAGED_CODE();
DirectoryTableBase.QuadPart = 0;
/* Get the current thread, process and cpu ring mode */
CurrentThread = PsGetCurrentThread();
ASSERT(&CurrentThread->Tcb == KeGetCurrentThread());
PreviousMode = ExGetPreviousMode();
ASSERT((CurrentThread) == PsGetCurrentThread());
CurrentProcess = (PEPROCESS)CurrentThread->Tcb.ApcState.Process;
PSTRACE(PS_PROCESS_DEBUG,
"ProcessHandle: %p Parent: %p\n", ProcessHandle, Parent);
/* Validate flags */
if (Flags & ~PS_ALL_FLAGS) return STATUS_INVALID_PARAMETER;
@ -400,6 +400,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
(PVOID*)&Parent,
NULL);
if (!NT_SUCCESS(Status)) return Status;
PSREFTRACE(ParentProcess);
/* If this process should be in a job but the parent isn't */
if ((InJob) && (!Parent->Job))
@ -418,7 +419,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
Parent = NULL;
#ifdef CONFIG_SMP
/*
* FIXME: Only the boot cpu is initialized in the early boot phase.
* FIXME: Only the boot cpu is initialized in the early boot phase.
*/
Affinity = 0xffffffff;
#else
@ -443,6 +444,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
if (!NT_SUCCESS(Status)) goto Cleanup;
/* Clean up the Object */
PSREFTRACE(Process);
RtlZeroMemory(Process, sizeof(EPROCESS));
/* Initialize pushlock and rundown protection */
@ -590,7 +592,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
Process->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
/* Create the Process' Address Space */
Status = MmCreateProcessAddressSpace(Process, (PROS_SECTION_OBJECT)SectionObject);
Status = MmCreateProcessAddressSpace(Process,
(PROS_SECTION_OBJECT)SectionObject);
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
/* Check for parent again */
@ -690,6 +693,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
if (AccessState) SeDeleteAccessState(AccessState);
/* Cleanup on failure */
PSREFTRACE(Process);
if (!NT_SUCCESS(Status)) goto Cleanup;
/* Compute Quantum and Priority */
@ -762,6 +766,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
KeQuerySystemTime(&Process->CreateTime);
/* Protect against bad user-mode pointer */
PSREFTRACE(Process);
_SEH_TRY
{
/* Save the process handle */
@ -787,10 +792,12 @@ Cleanup:
if (Parent) ObDereferenceObject(Parent);
/* Return status to caller */
PSREFTRACE(Process);
if (Parent) PSREFTRACE(Parent);
return Status;
}
/* PUBLIC FUNCTIONS *****************************************************************/
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
@ -825,6 +832,7 @@ PsLookupProcessByProcessId(IN HANDLE ProcessId,
PEPROCESS FoundProcess;
NTSTATUS Status = STATUS_INVALID_PARAMETER;
PAGED_CODE();
PSTRACE(PS_PROCESS_DEBUG, "ProcessId: %p\n", ProcessId);
KeEnterCriticalRegion();
/* Get the CID Handle Entry */
@ -867,6 +875,7 @@ PsLookupProcessThreadByCid(IN PCLIENT_ID Cid,
PETHREAD FoundThread;
NTSTATUS Status = STATUS_INVALID_CID;
PAGED_CODE();
PSTRACE(PS_PROCESS_DEBUG, "Cid: %p\n", Cid);
KeEnterCriticalRegion();
/* Get the CID Handle Entry */
@ -1158,6 +1167,7 @@ PsSetProcessPriorityByClass(IN PEPROCESS Process,
{
UCHAR Quantum;
ULONG Priority;
PSTRACE(PS_PROCESS_DEBUG, "Process: %p Type: %lx\n", Process, Type);
/* Compute quantum and priority */
Priority = PspComputeQuantumAndPriority(Process, Type, &Quantum);
@ -1173,7 +1183,7 @@ NTSTATUS
NTAPI
NtCreateProcessEx(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess,
IN ULONG Flags,
IN HANDLE SectionHandle OPTIONAL,
@ -1184,6 +1194,8 @@ NtCreateProcessEx(OUT PHANDLE ProcessHandle,
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
PSTRACE(PS_PROCESS_DEBUG,
"ParentProcess: %p Flags: %lx\n", ParentProcess, Flags);
/* Check if we came from user mode */
if(PreviousMode != KernelMode)
@ -1241,6 +1253,8 @@ NtCreateProcess(OUT PHANDLE ProcessHandle,
IN HANDLE ExceptionPort OPTIONAL)
{
ULONG Flags = 0;
PSTRACE(PS_PROCESS_DEBUG,
"Parent: %p Attributes: %p\n", ParentProcess, ObjectAttributes);
/* Set new-style flags */
if ((ULONG)SectionHandle & 1) Flags = PS_REQUEST_BREAKAWAY;
@ -1280,6 +1294,8 @@ NtOpenProcess(OUT PHANDLE ProcessHandle,
ACCESS_STATE AccessState;
AUX_DATA AuxData;
PAGED_CODE();
PSTRACE(PS_PROCESS_DEBUG,
"ClientId: %p Attributes: %p\n", ClientId, ObjectAttributes);
/* Check if we were called from user mode */
if (PreviousMode != KernelMode)
@ -1409,6 +1425,8 @@ NtOpenProcess(OUT PHANDLE ProcessHandle,
/* Dereference the Process */
ObDereferenceObject(Process);
PSREFTRACE(Process);
PSREFTRACE(Thread);
}
else
{

View file

@ -17,7 +17,7 @@
#include "internal/ps_i.h"
/* Debugging Level */
ULONG PspTraceLevel = 0; //PS_KILL_DEBUG | PS_SECURITY_DEBUG;
ULONG PspTraceLevel = 0; //PS_KILL_DEBUG | PS_REF_DEBUG;
/* PRIVATE FUNCTIONS *********************************************************/

View file

@ -30,6 +30,8 @@ PspUserThreadStartup(IN PKSTART_ROUTINE StartRoutine,
PTEB Teb;
BOOLEAN DeadThread = FALSE;
PAGED_CODE();
PSTRACE(PS_THREAD_DEBUG,
"StartRoutine: %p StartContext: %p\n", StartRoutine, StartContext);
/* Go to Passive Level */
KeLowerIrql(PASSIVE_LEVEL);
@ -50,6 +52,7 @@ PspUserThreadStartup(IN PKSTART_ROUTINE StartRoutine,
}
/* Check if this is a system thread, or if we're hiding */
PSREFTRACE(Thread);
if (!(Thread->SystemThread) && !(Thread->HideFromDebugger))
{
/* We're not, so notify the debugger */
@ -108,12 +111,15 @@ PspSystemThreadStartup(IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext)
{
PETHREAD Thread;
PSTRACE(PS_THREAD_DEBUG,
"StartRoutine: %p StartContext: %p\n", StartRoutine, StartContext);
/* Unlock the dispatcher Database */
KeLowerIrql(PASSIVE_LEVEL);
Thread = PsGetCurrentThread();
/* Make sure the thread isn't gone */
PSREFTRACE(Thread);
if (!(Thread->Terminated) && !(Thread->DeadThread))
{
/* Call it the Start Routine */
@ -128,7 +134,7 @@ NTSTATUS
NTAPI
PspCreateThread(OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle,
IN PEPROCESS TargetProcess,
OUT PCLIENT_ID ClientId,
@ -153,6 +159,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
PSECURITY_DESCRIPTOR SecurityDescriptor;
SECURITY_SUBJECT_CONTEXT SubjectContext;
PAGED_CODE();
PSTRACE(PS_THREAD_DEBUG,
"ThreadContext: %p TargetProcess: %p ProcessHandle: %p\n",
ThreadContext, TargetProcess, ProcessHandle);
/* If we were called from PsCreateSystemThread, then we're kernel mode */
if (StartRoutine) PreviousMode = KernelMode;
@ -167,6 +176,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
PreviousMode,
(PVOID*)&Process,
NULL);
PSREFTRACE(Process);
}
else
{
@ -175,6 +185,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
{
/* Reference the Process by Pointer */
ObReferenceObject(TargetProcess);
PSREFTRACE(TargetProcess);
Process = TargetProcess;
Status = STATUS_SUCCESS;
}
@ -191,6 +202,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
/* Also make sure that User-Mode isn't trying to create a system thread */
if ((PreviousMode != KernelMode) && (Process == PsInitialSystemProcess))
{
/* Fail */
ObDereferenceObject(Process);
return STATUS_INVALID_HANDLE;
}
@ -213,6 +225,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
}
/* Zero the Object entirely */
PSREFTRACE(Thread);
RtlZeroMemory(Thread, sizeof(ETHREAD));
/* Initialize rundown protection */
@ -294,6 +307,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
}
/* Check if we failed */
PSREFTRACE(Thread);
if (!NT_SUCCESS(Status))
{
/* Delete the TEB if we had done */
@ -389,6 +403,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
&hThread);
/* Delete the access state if we had one */
PSREFTRACE(Thread);
if (AccessState) SeDeleteAccessState(AccessState);
/* Check for success */
@ -440,6 +455,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
ASSERT(!(Thread->CreateTime.HighPart & 0xF0000000));
/* Make sure the thread isn't dead */
PSREFTRACE(Thread);
if (!Thread->DeadThread)
{
/* Get the thread's SD */
@ -505,6 +521,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
}
/* Dispatch thread */
PSREFTRACE(Thread);
OldIrql = KeAcquireDispatcherDatabaseLock ();
KiReadyThread(&Thread->Tcb);
KeReleaseDispatcherDatabaseLock(OldIrql);
@ -513,6 +530,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
ObDereferenceObject(Thread);
/* Return */
PSREFTRACE(Thread);
return Status;
/* Most annoying failure case ever, where we undo almost all manually */
@ -521,6 +539,7 @@ Quickie:
ExReleasePushLockExclusive(&Process->ProcessLock);
/* Uninitailize it */
PSREFTRACE(Thread);
KeUninitThread(&Thread->Tcb);
/* If we had a TEB, delete it */
@ -531,6 +550,7 @@ Quickie:
/* Dereference the thread and return failure */
ObDereferenceObject(Thread);
PSREFTRACE(Thread);
return STATUS_PROCESS_IS_TERMINATING;
}
@ -552,6 +572,9 @@ PsCreateSystemThread(OUT PHANDLE ThreadHandle,
PEPROCESS TargetProcess = NULL;
HANDLE Handle = ProcessHandle;
PAGED_CODE();
PSTRACE(PS_THREAD_DEBUG,
"ProcessHandle: %p StartRoutine: %p StartContext: %p\n",
ProcessHandle, StartRoutine, StartContext);
/* Check if we have a handle. If not, use the System Process */
if (!ProcessHandle)
@ -586,6 +609,7 @@ PsLookupThreadByThreadId(IN HANDLE ThreadId,
PETHREAD FoundThread;
NTSTATUS Status = STATUS_INVALID_PARAMETER;
PAGED_CODE();
PSTRACE(PS_THREAD_DEBUG, "ThreadId: %p\n", ThreadId);
KeEnterCriticalRegion();
/* Get the CID Handle Entry */
@ -811,6 +835,8 @@ NtCreateThread(OUT PHANDLE ThreadHandle,
INITIAL_TEB SafeInitialTeb;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
PSTRACE(PS_THREAD_DEBUG,
"ProcessHandle: %p Context: %p\n", ProcessHandle, ThreadContext);
/* Check if this was from user-mode */
if(KeGetPreviousMode() != KernelMode)
@ -887,6 +913,8 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
ACCESS_STATE AccessState;
AUX_DATA AuxData;
PAGED_CODE();
PSTRACE(PS_THREAD_DEBUG,
"ClientId: %p ObjectAttributes: %p\n", ClientId, ObjectAttributes);
/* Check if we were called from user mode */
if (PreviousMode != KernelMode)