* 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:
wj32
2010-02-06 23:04:10 +00:00
parent dc6639b91c
commit 08999f8beb
4 changed files with 114 additions and 12 deletions
+89 -9
View File
@@ -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
+10
View File
@@ -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
+4 -3
View File
@@ -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++;
+11
View File
@@ -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. */