- Fix WARN macros
- Keep a list of the PROCESSINFO of all the running processes
- Count how many handles a process owns per type in PROCESSINFO
- Improve the debug output when we run out of user handles to show all handle counts per process 

svn path=/trunk/; revision=57623
This commit is contained in:
Giannis Adamopoulos 2012-10-27 16:39:18 +00:00
parent 53d8444030
commit 80ae4e6e8c
7 changed files with 102 additions and 52 deletions

View file

@ -56,7 +56,8 @@ typedef enum _USER_OBJECT_TYPE
otHidData,
otDeviceInfo,
otTouchInput,
otGestureInfo
otGestureInfo,
USER_HANDLE_TYPE_COUNT
} USER_OBJECT_TYPE;
typedef enum _USERTHREADINFOCLASS

View file

@ -26,6 +26,7 @@ PSERVERINFO gpsi = NULL; // Global User Server Information.
SHORT gusLanguageID;
PPROCESSINFO ppiScrnSaver;
PPROCESSINFO gppiList = NULL;
extern ULONG_PTR Win32kSSDT[];
extern UCHAR Win32kSSPT[];
@ -55,7 +56,7 @@ APIENTRY
Win32kProcessCallback(struct _EPROCESS *Process,
BOOLEAN Create)
{
PPROCESSINFO ppiCurrent;
PPROCESSINFO ppiCurrent, *pppi;
DECLARE_RETURN(NTSTATUS);
ASSERT(Process->Peb);
@ -160,6 +161,10 @@ Win32kProcessCallback(struct _EPROCESS *Process,
ASSERT(ppiCurrent->pPoolDcAttr);
ASSERT(ppiCurrent->pPoolBrushAttr);
ASSERT(ppiCurrent->pPoolRgnAttr);
/* Add the process to the global list */
ppiCurrent->ppiNext = gppiList;
gppiList = ppiCurrent;
}
else
{
@ -212,11 +217,25 @@ Win32kProcessCallback(struct _EPROCESS *Process,
if (gppiInputProvider == ppiCurrent) gppiInputProvider = NULL;
pppi = &gppiList;
while (*pppi != NULL && *pppi != ppiCurrent)
pppi = &(*pppi)->ppiNext;
ASSERT(*pppi == ppiCurrent);
*pppi = ppiCurrent->ppiNext;
TRACE_CH(UserProcess,"Freeing ppi 0x%p\n", ppiCurrent);
/* Ftee the PROCESSINFO */
PsSetProcessWin32Process(Process, NULL);
ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO);
#if DBG
if (DBG_IS_CHANNEL_ENABLED(ppiCurrent, DbgChUserObj, WARN_LEVEL))
{
DbgUserDumpHandleTable();
}
#endif
}
RETURN( STATUS_SUCCESS);

View file

@ -12,6 +12,7 @@
extern BOOL gbInitialized;
extern PSERVERINFO gpsi;
extern PTHREADINFO gptiCurrent;
extern PPROCESSINFO gppiList;
extern PPROCESSINFO ppiScrnSaver;
extern PPROCESSINFO gppiInputProvider;

View file

@ -12,6 +12,66 @@ DBG_DEFAULT_CHANNEL(UserObj);
//int usedHandles=0;
PUSER_HANDLE_TABLE gHandleTable = NULL;
#if DBG
void DbgUserDumpHandleTable()
{
int HandleCounts[USER_HANDLE_TYPE_COUNT];
PPROCESSINFO ppiList;
int i;
PWCHAR TypeNames[] = {L"Free",L"Window",L"Menu", L"CursorIcon", L"SMWP", L"Hook", L"ClipBoardData", L"CallProc",
L"Accel", L"DDEaccess", L"DDEconv", L"DDExact", L"Monitor", L"KBDlayout", L"KBDfile",
L"Event", L"Timer", L"InputContext", L"HidData", L"DeviceInfo", L"TouchInput",L"GestureInfo"};
ERR("Total handles count: %d\n", gpsi->cHandleEntries);
memset(HandleCounts, 0, sizeof(HandleCounts));
/* First of all count the number of handles per tpe */
ppiList = gppiList;
while (ppiList)
{
ERR("Process %s (%d) handles count: %d\n\t", ppiList->peProcess->ImageFileName, ppiList->peProcess->UniqueProcessId, ppiList->UserHandleCount);
for (i = 1 ;i < USER_HANDLE_TYPE_COUNT; i++)
{
HandleCounts[i] += ppiList->DbgHandleCount[i];
DbgPrint("%S: %d, ", TypeNames[i], ppiList->DbgHandleCount[i]);
if (i % 6 == 0)
DbgPrint("\n\t");
}
DbgPrint("\n");
ppiList = ppiList->ppiNext;
}
/* Print total type counts */
ERR("Total handles of the running processes: \n\t");
for (i = 1 ;i < USER_HANDLE_TYPE_COUNT; i++)
{
DbgPrint("%S: %d, ", TypeNames[i], HandleCounts[i]);
if (i % 6 == 0)
DbgPrint("\n\t");
}
DbgPrint("\n");
/* Now count the handle counts that are allocated from the handle table */
memset(HandleCounts, 0, sizeof(HandleCounts));
for (i = 0; i < gHandleTable->nb_handles; i++)
HandleCounts[gHandleTable->handles[i].type]++;
ERR("Total handles count allocated: \n\t");
for (i = 1 ;i < USER_HANDLE_TYPE_COUNT; i++)
{
DbgPrint("%S: %d, ", TypeNames[i], HandleCounts[i]);
if (i % 6 == 0)
DbgPrint("\n\t");
}
DbgPrint("\n");
}
#endif
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle )
{
@ -51,55 +111,12 @@ __inline static PUSER_HANDLE_ENTRY alloc_user_entry(PUSER_HANDLE_TABLE ht)
if (ht->nb_handles >= ht->allocated_handles) /* Need to grow the array */
{
/**/
int i, iFree = 0, iWindow = 0, iMenu = 0, iCursorIcon = 0,
iHook = 0, iCallProc = 0, iAccel = 0, iMonitor = 0, iTimer = 0, iEvent = 0, iSMWP = 0;
/**/
ERR("Out of user handles! Used -> %i, NM_Handle -> %d\n", gpsi->cHandleEntries, ht->nb_handles);
//#if 0
for(i = 0; i < ht->nb_handles; i++)
{
switch (ht->handles[i].type)
{
case otFree: // Should be zero.
iFree++;
break;
case otWindow:
iWindow++;
break;
case otMenu:
iMenu++;
break;
case otCursorIcon:
iCursorIcon++;
break;
case otHook:
iHook++;
break;
case otCallProc:
iCallProc++;
break;
case otAccel:
iAccel++;
break;
case otMonitor:
iMonitor++;
break;
case otTimer:
iTimer++;
break;
case otEvent:
iEvent++;
break;
case otSMWP:
iSMWP++;
default:
break;
}
}
ERR("Handle Count by Type:\n Free = %d Window = %d Menu = %d CursorIcon = %d Hook = %d\n CallProc = %d Accel = %d Monitor = %d Timer = %d Event = %d SMWP = %d\n",
iFree, iWindow, iMenu, iCursorIcon, iHook, iCallProc, iAccel, iMonitor, iTimer, iEvent, iSMWP );
//#endif
ERR("Out of user handles! Used -> %i, NM_Handle -> %d\n", gpsi->cHandleEntries, ht->nb_handles);
#if DBG
DbgUserDumpHandleTable();
#endif
return NULL;
#if 0
PUSER_HANDLE_ENTRY new_handles;
@ -138,6 +155,11 @@ __inline static void *free_user_entry(PUSER_HANDLE_TABLE ht, PUSER_HANDLE_ENTRY
{
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
void *ret;
#if DBG
ppi->DbgHandleCount[entry->type]--;
#endif
ret = entry->ptr;
entry->ptr = ht->freelist;
entry->type = 0;
@ -339,6 +361,10 @@ UserCreateObject( PUSER_HANDLE_TABLE ht,
return NULL;
}
#if DBG
ppi->DbgHandleCount[type]++;
#endif
RtlZeroMemory(Object, size);
switch (type)

View file

@ -39,6 +39,7 @@ PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, USER_OBJECT_TYPE type
PVOID UserGetObjectNoErr(PUSER_HANDLE_TABLE, HANDLE, USER_OBJECT_TYPE);
BOOL FASTCALL UserCreateHandleTable(VOID);
BOOL FASTCALL UserObjectInDestroy(HANDLE);
void DbgUserDumpHandleTable();
static __inline VOID
UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)

View file

@ -195,6 +195,7 @@ typedef struct _PROCESSINFO
PTHREADINFO ptiList;
PTHREADINFO ptiMainThread;
struct _DESKTOP* rpdeskStartup;
PPROCESSINFO ppiNext;
PCLS pclsPrivateList;
PCLS pclsPublicList;
INT cThreads;
@ -224,6 +225,7 @@ typedef struct _PROCESSINFO
#if DBG
BYTE DbgChannelLevel[DbgChCount];
DWORD DbgHandleCount[USER_HANDLE_TYPE_COUNT];
#endif
} PROCESSINFO;

View file

@ -125,7 +125,7 @@
#define DBG_ENABLE_CHANNEL(ppi,ch,level) ((ppi)->DbgChannelLevel[ch] |= level)
#define DBG_DISABLE_CHANNEL(ppi,ch,level) ((ppi)->DbgChannelLevel[ch] &= ~level)
#define DBG_IS_CHANNEL_ENABLED(ppi,ch,level) ((ppi)->DbgChannelLevel[ch] & level)
#define DBG_IS_CHANNEL_ENABLED(ppi,ch,level) (((ppi)->DbgChannelLevel[ch] & level) == level)
#define DBG_PRINT(ppi,ch,level,fmt, ...) do { \
if((level == ERR_LEVEL) || (ppi && DBG_IS_CHANNEL_ENABLED(ppi,ch,level))) \