You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
228 lines
5.3 KiB
228 lines
5.3 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
process.c
|
|
|
|
Abstract:
|
|
|
|
This module maintains state about each process/thread created by the application
|
|
pfmon program.
|
|
|
|
Author:
|
|
|
|
Mark Lucovsky (markl) 26-Jan-1995
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "pfmonp.h"
|
|
|
|
BOOL
|
|
AddProcess(
|
|
LPDEBUG_EVENT DebugEvent,
|
|
PPROCESS_INFO *ReturnedProcess
|
|
)
|
|
{
|
|
PPROCESS_INFO Process;
|
|
|
|
Process = LocalAlloc(LMEM_ZEROINIT, sizeof( *Process ) );
|
|
if (Process == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
Process->Id = DebugEvent->dwProcessId;
|
|
Process->Handle = DebugEvent->u.CreateProcessInfo.hProcess;
|
|
InitializeListHead( &Process->ThreadListHead );
|
|
InsertTailList( &ProcessListHead, &Process->Entry );
|
|
*ReturnedProcess = Process;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
DeleteProcess(
|
|
PPROCESS_INFO Process
|
|
)
|
|
{
|
|
PLIST_ENTRY Next, Head;
|
|
PTHREAD_INFO Thread;
|
|
PMODULE_INFO Module;
|
|
CHAR Line[256];
|
|
|
|
RemoveEntryList( &Process->Entry );
|
|
|
|
Head = &Process->ThreadListHead;
|
|
Next = Head->Flink;
|
|
while (Next != Head) {
|
|
Thread = CONTAINING_RECORD( Next, THREAD_INFO, Entry );
|
|
Next = Next->Flink;
|
|
DeleteThread( Process, Thread );
|
|
}
|
|
|
|
LocalFree( Process );
|
|
fprintf(stdout,"\n");
|
|
|
|
Next = ModuleListHead.Flink;
|
|
while ( Next != &ModuleListHead ) {
|
|
Module = CONTAINING_RECORD(Next,MODULE_INFO,Entry);
|
|
|
|
|
|
sprintf(Line,"%16s Caused %6d faults had %6d Soft %6d Hard faulted VA's\n",
|
|
Module->ModuleName,
|
|
Module->NumberCausedFaults,
|
|
Module->NumberFaultedSoftVas,
|
|
Module->NumberFaultedHardVas
|
|
);
|
|
if ( !fLogOnly ) {
|
|
fprintf(stdout,"%s",Line);
|
|
}
|
|
if ( LogFile ) {
|
|
fprintf(LogFile,"%s",Line);
|
|
}
|
|
|
|
Next = Next->Flink;
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
AddThread(
|
|
LPDEBUG_EVENT DebugEvent,
|
|
PPROCESS_INFO Process,
|
|
PTHREAD_INFO *ReturnedThread
|
|
)
|
|
{
|
|
PTHREAD_INFO Thread;
|
|
|
|
Thread = LocalAlloc(LMEM_ZEROINIT, sizeof( *Thread ) );
|
|
if (Thread == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
Thread->Id = DebugEvent->dwThreadId;
|
|
if (DebugEvent->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) {
|
|
Thread->Handle = DebugEvent->u.CreateProcessInfo.hThread;
|
|
Thread->StartAddress = DebugEvent->u.CreateProcessInfo.lpStartAddress;
|
|
}
|
|
else {
|
|
Thread->Handle = DebugEvent->u.CreateThread.hThread;
|
|
Thread->StartAddress = DebugEvent->u.CreateThread.lpStartAddress;
|
|
}
|
|
InsertTailList( &Process->ThreadListHead, &Thread->Entry );
|
|
*ReturnedThread = Thread;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
DeleteThread(
|
|
PPROCESS_INFO Process,
|
|
PTHREAD_INFO Thread
|
|
)
|
|
{
|
|
|
|
RemoveEntryList( &Thread->Entry );
|
|
|
|
LocalFree( Thread );
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
PPROCESS_INFO
|
|
FindProcessById(
|
|
ULONG Id
|
|
)
|
|
{
|
|
PLIST_ENTRY Next, Head;
|
|
PPROCESS_INFO Process;
|
|
|
|
Head = &ProcessListHead;
|
|
Next = Head->Flink;
|
|
while (Next != Head) {
|
|
Process = CONTAINING_RECORD( Next, PROCESS_INFO, Entry );
|
|
if (Process->Id == Id) {
|
|
return Process;
|
|
}
|
|
|
|
Next = Next->Flink;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
BOOL
|
|
FindProcessAndThreadForEvent(
|
|
LPDEBUG_EVENT DebugEvent,
|
|
PPROCESS_INFO *ReturnedProcess,
|
|
PTHREAD_INFO *ReturnedThread
|
|
)
|
|
{
|
|
PLIST_ENTRY Next, Head;
|
|
PPROCESS_INFO Process;
|
|
PTHREAD_INFO Thread;
|
|
|
|
Head = &ProcessListHead;
|
|
Next = Head->Flink;
|
|
Process = NULL;
|
|
Thread = NULL;
|
|
while (Next != Head) {
|
|
Process = CONTAINING_RECORD( Next, PROCESS_INFO, Entry );
|
|
if (Process->Id == DebugEvent->dwProcessId) {
|
|
Head = &Process->ThreadListHead;
|
|
Next = Head->Flink;
|
|
while (Next != Head) {
|
|
Thread = CONTAINING_RECORD( Next, THREAD_INFO, Entry );
|
|
if (Thread->Id == DebugEvent->dwThreadId) {
|
|
break;
|
|
}
|
|
|
|
Thread = NULL;
|
|
Next = Next->Flink;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
Process = NULL;
|
|
Next = Next->Flink;
|
|
}
|
|
|
|
*ReturnedProcess = Process;
|
|
*ReturnedThread = Thread;
|
|
|
|
if (DebugEvent->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) {
|
|
if (Process != NULL) {
|
|
DeclareError( PFMON_DUPLICATE_PROCESS_ID, 0, DebugEvent->dwProcessId );
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
if (DebugEvent->dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT) {
|
|
if (Thread != NULL) {
|
|
DeclareError( PFMON_DUPLICATE_THREAD_ID, 0, DebugEvent->dwThreadId, DebugEvent->dwProcessId );
|
|
return FALSE;
|
|
}
|
|
if (Process == NULL) {
|
|
DeclareError( PFMON_MISSING_PROCESS_ID, 0, DebugEvent->dwProcessId );
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
if (Process == NULL) {
|
|
DeclareError( PFMON_MISSING_PROCESS_ID, 0, DebugEvent->dwProcessId );
|
|
return FALSE;
|
|
}
|
|
else
|
|
if (Thread == NULL) {
|
|
DeclareError( PFMON_MISSING_THREAD_ID, 0, DebugEvent->dwThreadId, DebugEvent->dwProcessId );
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|