mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
* added new-object detection
* re-use PID list instead of creating a new one on each update git-svn-id: svn://svn.code.sf.net/p/processhacker/code@2801 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user