diff --git a/2.x/trunk/ProcessHacker/dbgcon.c b/2.x/trunk/ProcessHacker/dbgcon.c index 5512f66e9..f96855e43 100644 --- a/2.x/trunk/ProcessHacker/dbgcon.c +++ b/2.x/trunk/ProcessHacker/dbgcon.c @@ -8,6 +8,8 @@ NTSTATUS PhpDebugConsoleThreadStart( static HANDLE DebugConsoleThreadHandle; static PPH_HASHTABLE ObjectListSnapshot = NULL; +static PPH_LIST NewObjectList = NULL; +static PH_MUTEX NewObjectListLock; VOID PhShowDebugConsole() { @@ -74,6 +76,38 @@ static VOID PhpPrintObjectInfo( wprintf(L"\n"); } +static VOID PhpDebugCreateObjectHook( + __in PVOID Object, + __in SIZE_T Size, + __in ULONG Flags, + __in PPH_OBJECT_TYPE ObjectType + ) +{ + PhAcquireMutex(&NewObjectListLock); + + if (NewObjectList) + { + PhReferenceObject(Object); + PhAddListItem(NewObjectList, Object); + } + + PhReleaseMutex(&NewObjectListLock); +} + +static VOID PhpDeleteNewObjectList() +{ + if (NewObjectList) + { + ULONG i; + + for (i = 0; i < NewObjectList->Count; i++) + PhDereferenceObject(NewObjectList->Items[i]); + + PhDereferenceObject(NewObjectList); + NewObjectList = NULL; + } +} + NTSTATUS PhpDebugConsoleThreadStart( __in PVOID Parameter ) @@ -90,6 +124,9 @@ NTSTATUS PhpDebugConsoleThreadStart( PhEnumGenericModules(NtCurrentProcessId(), NtCurrentProcess(), 0, PhpLoadCurrentProcessSymbolsCallback, symbolProvider); + PhInitializeMutex(&NewObjectListLock); + PhCreateObjectHook = PhpDebugCreateObjectHook; + while (TRUE) { static PWSTR delims = L" \t"; @@ -122,6 +159,9 @@ NTSTATUS PhpDebugConsoleThreadStart( L"objtrace object-address\n" L"objmksnap\n" L"objcmpsnap\n" + L"objmknew\n" + L"objdelnew\n" + L"objviewnew\n" ); } else if (WSTR_IEQUAL(command, L"objects")) @@ -146,17 +186,13 @@ NTSTATUS PhpDebugConsoleThreadStart( objectHeader = CONTAINING_RECORD(currentEntry, PH_OBJECT_HEADER, ObjectListEntry); - // Prevent the object from being destroyed. + // Make sure the object isn't being destroyed. if (!PhReferenceObjectSafe(PhObjectHeaderToObject(objectHeader))) { currentEntry = currentEntry->Flink; continue; } - // Release the lock because the following operations may - // require creating objects. - PhReleaseFastLockShared(&PhObjectListLock); - totalNumberOfObjects++; totalNumberOfBytes += objectHeader->Size; @@ -174,10 +210,6 @@ NTSTATUS PhpDebugConsoleThreadStart( PhpPrintObjectInfo(objectHeader); } - PhAcquireFastLockShared(&PhObjectListLock); - - // This ordering is *very* important. We can't allow the object - // to be destroyed outside of the lock. currentEntry = currentEntry->Flink; PhDereferenceObjectDeferDelete(PhObjectHeaderToObject(objectHeader)); } @@ -332,6 +364,54 @@ NTSTATUS PhpDebugConsoleThreadStart( PhDereferenceObject(newObjects); #else wprintf(commandDebugOnly); +#endif + } + else if (WSTR_IEQUAL(command, L"objmknew")) + { +#ifdef DEBUG + PhAcquireMutex(&NewObjectListLock); + PhpDeleteNewObjectList(); + PhReleaseMutex(&NewObjectListLock); + + // Creation needs to be done outside of the lock, + // otherwise a deadlock will occur. + NewObjectList = PhCreateList(100); +#else + wprintf(commandDebugOnly); +#endif + } + else if (WSTR_IEQUAL(command, L"objdelnew")) + { +#ifdef DEBUG + PhAcquireMutex(&NewObjectListLock); + PhpDeleteNewObjectList(); + PhReleaseMutex(&NewObjectListLock); +#else + wprintf(commandDebugOnly); +#endif + } + else if (WSTR_IEQUAL(command, L"objviewnew")) + { +#ifdef DEBUG + ULONG i; + + PhAcquireMutex(&NewObjectListLock); + + if (!NewObjectList) + { + wprintf(L"Object creation hooking not active.\n"); + PhReleaseMutex(&NewObjectListLock); + goto EndCommand; + } + + for (i = 0; i < NewObjectList->Count; i++) + { + PhpPrintObjectInfo(PhObjectToObjectHeader(NewObjectList->Items[i])); + } + + PhReleaseMutex(&NewObjectListLock); +#else + wprintf(commandDebugOnly); #endif } else diff --git a/2.x/trunk/ProcessHacker/include/ref.h b/2.x/trunk/ProcessHacker/include/ref.h index 1884dd9e9..d40a012f0 100644 --- a/2.x/trunk/ProcessHacker/include/ref.h +++ b/2.x/trunk/ProcessHacker/include/ref.h @@ -55,6 +55,15 @@ typedef struct _PH_AUTO_POOL *PPH_AUTO_POOL; struct _PH_FAST_LOCK; typedef struct _PH_FAST_LOCK PH_FAST_LOCK, *PPH_FAST_LOCK; +#ifdef DEBUG +typedef VOID (NTAPI *PPH_CREATE_OBJECT_HOOK)( + __in PVOID Object, + __in SIZE_T Size, + __in ULONG Flags, + __in PPH_OBJECT_TYPE ObjectType + ); +#endif + #ifndef REF_PRIVATE extern PPH_OBJECT_TYPE PhObjectTypeObject; extern PPH_OBJECT_TYPE PhAllocType; @@ -62,6 +71,7 @@ extern PPH_OBJECT_TYPE PhAllocType; #ifdef DEBUG extern LIST_ENTRY PhObjectListHead; extern PH_FAST_LOCK PhObjectListLock; +extern PPH_CREATE_OBJECT_HOOK PhCreateObjectHook; #endif #endif diff --git a/2.x/trunk/ProcessHacker/procprv.c b/2.x/trunk/ProcessHacker/procprv.c index 91f34e88d..6953f7c5b 100644 --- a/2.x/trunk/ProcessHacker/procprv.c +++ b/2.x/trunk/ProcessHacker/procprv.c @@ -749,6 +749,7 @@ VOID PhProcessProviderUpdate( ) { static ULONG runCount = 0; + static PPH_LIST pids = NULL; // Note about locking: // Since this is the only function that is allowed to @@ -758,7 +759,6 @@ VOID PhProcessProviderUpdate( PVOID processes; PSYSTEM_PROCESS_INFORMATION process; - PPH_LIST pids; ULONG64 sysTotalTime; @@ -782,7 +782,8 @@ VOID PhProcessProviderUpdate( // Create a PID list. - pids = PhCreateList(40); + if (!pids) + pids = PhCreateList(40); process = PH_FIRST_PROCESS(processes); @@ -1014,7 +1015,7 @@ VOID PhProcessProviderUpdate( } } - PhDereferenceObject(pids); + PhClearList(pids); PhFree(processes); runCount++; diff --git a/2.x/trunk/ProcessHacker/ref.c b/2.x/trunk/ProcessHacker/ref.c index 49204794d..a36d62b89 100644 --- a/2.x/trunk/ProcessHacker/ref.c +++ b/2.x/trunk/ProcessHacker/ref.c @@ -40,6 +40,7 @@ static ULONG PhpAutoPoolTlsIndex; #ifdef DEBUG LIST_ENTRY PhObjectListHead; PH_FAST_LOCK PhObjectListLock; +PPH_CREATE_OBJECT_HOOK PhCreateObjectHook = NULL; #endif /** @@ -161,6 +162,16 @@ NTSTATUS PhCreateObject( PhAcquireFastLockExclusive(&PhObjectListLock); InsertHeadList(&PhObjectListHead, &objectHeader->ObjectListEntry); PhReleaseFastLockExclusive(&PhObjectListLock); + + if (PhCreateObjectHook) + { + PhCreateObjectHook( + PhObjectHeaderToObject(objectHeader), + ObjectSize, + Flags, + ObjectType + ); + } #endif /* Pass a pointer to the object body back to the caller. */