⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memtrk.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (dwFlags&PRINT_TRACE)
    {
        DWORD Index, temp;
        LPWSTR lpsz;
        LPMODULE lpm;

        for (Cnt=0; Cnt < NUM_TRACK_STACK_FRAMES; Cnt++)
        {
#ifdef WINCEPROFILE
			PROFentry *pProfEntry = NULL;
			ULONG ulAddr = pn->Frames[Cnt] & ((1<<VA_SECTION) - 1);
#endif
			
			if (!(temp = pn->Frames[Cnt] & ~((1<<VA_SECTION) - 1)))
				break;
            for (Index=0; (Index< MAX_PROCESSES) && (ProcArray[Index].dwVMBase != temp); Index++)
            	;

            if (Index>= MAX_PROCESSES)
            {
                lpsz=L"Bad Frame";
                temp=pn->Frames[Cnt];
            }
            else if (lpm=MEMTR_ModuleFromAddress(pn->Frames[Cnt]))
            {
                //This is a DLL
                lpsz=lpm->lpszModName;
                temp=ZeroPtr(pn->Frames[Cnt])-ZeroPtr(lpm->BasePtr);
#ifdef WINCEPROFILE
				pProfEntry = GetFixedProfEntry(ulAddr);
#endif
            }
            else
            {
                lpsz=MEMTR_GetWin32ExeName((PPROCESS)&ProcArray[Index]);
                temp=(DWORD)ZeroPtr(pn->Frames[Cnt])-(DWORD)ZeroPtr(ProcArray[Index].BasePtr);
#ifdef WINCEPROFILE
				pProfEntry = GetEXEProfEntry(Index);
#endif
            }

#ifdef WINCEPROFILE
			{
				ULONG ulFuncAddr;
				LPSTR szSymbol;

				if(pProfEntry && (szSymbol = GetSymbol(pProfEntry, ulAddr, &ulFuncAddr))) {
					RETAILMSG(1, (L"%12.12s!%a+0x%04lx\r\n", lpsz, szSymbol, ulAddr - ulFuncAddr));
				} else {
					RETAILMSG(1, (L"%12.12s!0x%8.8lx\r\n", lpsz, temp));
				}
			}
#else
            if (Cnt)
                RETAILMSG(1, (L", "));
            else    
                RETAILMSG(1, (L"    "));

			if (Cnt && (Cnt%3==2)) 
				RETAILMSG(1, (L"\r\n"));

            RETAILMSG(1, (L"%12.12s!0x%8.8lx", lpsz, temp));
#endif
        }

		RETAILMSG(1,(L"\r\n\r\n"));
    }

	SETCURKEY(ulOldKey);
}
#pragma optimize ("", on)

#define SKIP_FRAMES 2

BOOL MEMTR_GetStackFrames(DWORD lpFrames[])
{
	CONTEXT CurrentContext;
    CONTEXT ContextRecord1;
    ULONG ControlPc;
    ULONG EstablisherFrame;
    PRUNTIME_FUNCTION FunctionEntry;
    BOOLEAN InFunction;
    ULONG HighLimit;
    ULONG LowLimit;
    ULONG NestedFrame;
    ULONG NextPc;
    ULONG PrevSp;
    ULONG Cnt;
	PCALLSTACK pcstk;
	PPROCESS pprcSave;
	ACCESSKEY akySave;

    RtlCaptureContext(&CurrentContext);
	pprcSave = pCurProc;
	akySave = pCurThread->aky;
    NKGetStackLimits(pCurThread, &LowLimit, &HighLimit);
    memcpy(&ContextRecord1, &CurrentContext, sizeof(CONTEXT));
    ControlPc = CONTEXT_TO_PROGRAM_COUNTER(&ContextRecord1);
    NestedFrame = 0;
	pcstk = pCurThread->pcstkTop;
	Cnt = 0;
//	RETAILMSG(1,(L"Frames requested\r\n"));
    do {
	    PrevSp = ContextRecord1.STACKPTR;
        FunctionEntry = LookupFunctionEntry(pCurProc, ControlPc);
        // RETAILMSG(1,(L"Frame %d: %8.8lx\r\n",Cnt,MapPtrProc(ControlPc,pCurProc)));
		if (Cnt >= SKIP_FRAMES)
	    	lpFrames[Cnt-SKIP_FRAMES] = (DWORD)MapPtrProc(ControlPc,pCurProc);
		Cnt++;
        if (FunctionEntry != NULL) {
            NextPc = RtlVirtualUnwind(ControlPc,
                                      FunctionEntry,
                                      &ContextRecord1,
                                      &InFunction,
                                      &EstablisherFrame);
            if ((EstablisherFrame < LowLimit) || (EstablisherFrame > HighLimit) ||
            		((EstablisherFrame & STK_ALIGN) != 0))
                break;
            else if ((!InFunction || !FunctionEntry->ExceptionHandler) && (NextPc != ControlPc))
                PrevSp = 0;	// don't terminate loop because sp didn't change.
        } else {
            NextPc = ContextRecord1.RETADDR - INST_SIZE;
            PrevSp = 0;	// don't terminate loop because sp didn't change.
            if (NextPc == ControlPc)
                break;
        }
        ControlPc = NextPc;
        if (pcstk && (ControlPc == SYSCALL_RETURN || ControlPc+INST_SIZE == SYSCALL_RETURN
                || ControlPc == DIRECT_RETURN || ControlPc+INST_SIZE == DIRECT_RETURN)) {
        	PPROCESS pProc = pcstk->pprcLast;
        	ContextRecord1.RETADDR = (ULONG)pcstk->retAddr;
	        if ((ulong)pProc < 0x10000)
	            SetContextMode(&ContextRecord1, (ULONG)pProc);
	        else
                UpdateASID(pCurThread, pProc, pcstk->akyLast ? pcstk->akyLast : pCurThread->aky);
        	ControlPc = ContextRecord1.RETADDR - INST_SIZE;
        	pcstk = pcstk->pcstkNext;
        }
        else if (pcstk && (DWORD)pcstk < ContextRecord1.STACKPTR && !pcstk->retAddr)
        {
            PPROCESS pProc = pcstk->pprcLast;
            ContextRecord1.RETADDR = (DWORD)ZeroPtr(ControlPc);
            // RETAILMSG(1,(L"*** CallBack4 ControlPc %8.8l ZeroPtr %08x\r\n",ControlPc,ContextRecord1.RETADDR));
            if ((ulong)pProc < 0x10000)
                SetContextMode(&ContextRecord1, (ULONG)pProc);
            else
                UpdateASID(pCurThread, pProc, pcstk->akyLast ? pcstk->akyLast : pCurThread->aky);
            ControlPc = ContextRecord1.RETADDR - INST_SIZE;
            pcstk=pcstk->pcstkNext;
        }
    } while ((ContextRecord1.STACKPTR < HighLimit) && (ContextRecord1.STACKPTR > PrevSp) && (Cnt < NUM_TRACK_STACK_FRAMES + SKIP_FRAMES));
	UpdateASID(pCurThread, pprcSave, akySave);
	return TRUE;
}

extern PROCESS *kdProcArray;
LPMODULE MEMTR_ModuleFromAddress(DWORD dwAdd)
{
    DWORD fa; //Fixedup address
    DWORD ModZa;  //Module's zero based address
    LPMODULE pMod;

    //Make the given address zero based
    fa=ZeroPtr(dwAdd);

    //Walk module list to find this address
    pMod=pModList;							 
    while (pMod) {
		ModZa = (DWORD)pMod->BasePtr-kdProcArray[0].dwVMBase;
		if (fa >= ModZa && fa < ModZa+pMod->e32.e32_vsize) {
		    return pMod;
		}		    
		pMod=pMod->pMod;
    }

    return NULL;
}

static LPWSTR lpszUnknown=L"UNKNOWN";

LPWSTR MEMTR_GetWin32ExeName(PPROCESS pProc)
{
    if (pProc->lpszProcName)
		return pProc->lpszProcName;
	return lpszUnknown;
}

#endif

/*
@func   BOOL | PrintTrackedItem | Prints tracked items
@parm   DWORD | dwFlags | Flags controlling what gets printed. Can be a combination of:
        @flag PRINT_RECENT | Only prints resources allocated or freed since the last checkpoint
        @flag PRINT_SETCHECKPOINT | Sets a checkpoint for all resources dumped in this call
        @flag PRINT_DETAILS | Prints details for the resource items
        @flag PRINT_TRACE | Prints a stack trace for resource items
        @flag PRINT_FILTERTYPE | Only prints resources of this type
        @flag PRINT_FILTERPROCID | Only prints resources for this process id
        @flag PRINT_FILTERHANDLE | Only prints resources with this handle. Typically used while
            specifying the PRINT_FILTERTYPE flag also, since both are required for the handle to
            be unique.  The high word is reserved for application defined values.
@parm   DWORD | dwType | TypeID to filter for if PRINT_FILTERTYPE is specified
@parm   DWORD | dwProcID | ProcID to filter for if PRINT_FILTERPROCID is specified
@parm   HANDLE | handle | Handle to filter for if PRINT_FILTERHANDLE is specified
@comm   For the incremental flag to be useful you must make sure to checkpoint at the appropriate
        points. Note that only resources which meet the filter requirements are checkpointed - 
        in other words if you call this function with the checkpoint flag set and a filter set
        on type 4, then only resource items of that type will be checkpointed. To keep things 
        simple you should probably not use any filters when you are checkpointing. A typical mode
        of usage would be to checkpoint, do some operation, and then do an incremental dump to 
        see if the last operation caused any leaks in the system. Once you feel there is a leak,
        you can use the PRINT_DETAILS flag to see what specific items might have been leaked, and
        then print stack traces for them by using the PRINT_FILTERHANDLE and PRINT_TRACE flags.
@xref   <f RegisterTrackedItem> <f AddTrackedItem> <f DeleteTrackedItem> <f FilterTrackedItem> <f TrackerCallBack>
*/
BOOL SC_PrintTrackedItem(DWORD dwFlags, DWORD dwType, DWORD dwProcID, HANDLE handle)
{
#ifdef MEMTRACKING
  	pTrack_Node pnCur, pnFree;
    DWORD dwCurType;
    DWORD dwSize, dwCount;
  	  	
	EnterCriticalSection(&Trackcs);
	if (!pTOC->ulTrackingLen || !pTOC->ulTrackingStart)
    {
    	ERRORMSG(1, (L"No resource tracking memory!!\r\n"));
        goto errret;
    }
    if (!uiTablesize && !PerformCallBack4(&cbi,0)){
        ERRORMSG(1, (L"MEMTR: Out of resource tracking memory!\r\n"));
        SetLastError(ERROR_NOT_ENOUGH_SERVER_MEMORY);
        goto errret;
    }        
	DEBUGCHK(table);

    // Go through all nodes and print as required
 	RETAILMSG(dwFlags&PRINT_DETAILS,(L"LEGEND:- Process:Handle(AllocTime):Size::dwCustom1:dwCustom2\r\n"));
    for (dwCurType=0; rgRegTypes[dwCurType].dwFlags&REGTYPE_INUSE; dwCurType++) {
	    if ((dwFlags&PRINT_FILTERTYPE) && (dwCurType!=dwType)) continue;
	    if (rgRegTypes[dwCurType].dwFlags&REGTYPE_MASKED) continue;
	    RETAILMSG(1, (L"Resource Name: %s(%d)\r\n",
					  rgRegTypes[dwCurType].szName, dwCurType));
	    RETAILMSG(1, (L" Allocated:"));
	    RETAILMSG(dwFlags&PRINT_DETAILS, (L"\r\n"));
	    dwCount = dwSize = 0;
    	for (pnCur = pnFirst; pnCur; pnCur = pnCur->pnNext) {
    	    // do all the filtering
    	    if (pnCur->dwType != dwCurType) continue;
    	    if ((dwFlags&PRINT_FILTERHANDLE) && (pnCur->handle!=handle)) continue;
    	    if ((dwFlags&PRINT_FILTERPROCID) && (pnCur->dwProcID!=dwProcID)) continue;
    	    if ((dwFlags&PRINT_RECENT) && (pnCur->dwFlags&ITEM_SHOWN)) continue;
            if (!(pnCur->dwFlags&ITEM_DELETED)) {
        	    // print the item
        	    if ((dwFlags&PRINT_DETAILS) || (dwFlags&PRINT_TRACE)) {
            		MEMTR_printnode(dwFlags, pnCur);
                }            		
        		dwSize += pnCur->dwSize;
        		dwCount++;
    		}
    		if (dwFlags&PRINT_SETCHECKPOINT) {
        		pnCur->dwFlags |= ITEM_SHOWN;
            }        		
    	}
	    RETAILMSG(1, (L"  Total size: %6.6lu, Num items:%u\r\n", dwSize, dwCount));
	    RETAILMSG(1, (L" Freed    :"));
	    RETAILMSG(dwFlags&PRINT_DETAILS, (L"\r\n"));
	    dwCount = dwSize = 0;
   	    pnFree = NULL;
    	for (pnCur = pnFirst; pnCur; pnCur=pnCur->pnNext) {
    	    // free the last node if necessary
    	    if ((dwFlags&PRINT_SETCHECKPOINT) && pnFree) {
                DEBUGMSG(ZONE_MEMTRACKER, (L"X"));
    	        MEMTR_deletenode(pnFree);
        	    pnFree = NULL;
            }        	    
    	    
    	    // do all the filtering
    	    if (pnCur->dwType != dwCurType) continue;
    	    if ((dwFlags&PRINT_FILTERHANDLE) && (pnCur->handle!=handle)) continue;
    	    if ((dwFlags&PRINT_FILTERPROCID) && (pnCur->dwProcID!=dwProcID)) continue;
    	    if (pnCur->dwFlags&ITEM_DELETED) {
        	    // print the item
        	    if ((dwFlags&PRINT_DETAILS) || (dwFlags&PRINT_TRACE)) {
            		MEMTR_printnode(dwFlags, pnCur);
                }            		
        		dwSize += pnCur->dwSize;
        		dwCount++;
                pnFree = pnCur;
    		} 
    	}
	    RETAILMSG(1, (L"  Total size: %6.6lu, Num items %u\r\n", dwSize, dwCount));
    }

	LeaveCriticalSection(&Trackcs);
    return TRUE;

errret:
	LeaveCriticalSection(&Trackcs);
#endif
	return FALSE;	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -