diff -r 516af714ebb4 -r f2950aff7424 perfsrv/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapWalk.cpp --- a/perfsrv/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapWalk.cpp Fri Sep 17 08:38:31 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,538 +0,0 @@ -/* -* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - -#include "MemSpyDriverLogChanHeapWalk.h" - -// System includes -#include -#include -#include -#include - -// Shared includes -#include "MemSpyDriverOpCodes.h" -#include "MemSpyDriverObjectsInternal.h" - -// User includes -#include "MemSpyDriverHeap.h" -#include "MemSpyDriverUtils.h" -#include "MemSpyDriverDevice.h" -#include "MemSpyDriverOSAdaption.h" -#include "MemSpyDriverSuspensionManager.h" - - - -DMemSpyDriverLogChanHeapWalk::DMemSpyDriverLogChanHeapWalk( DMemSpyDriverDevice& aDevice, DThread& aThread ) -: DMemSpyDriverLogChanHeapBase( aDevice, aThread ), iWalkHeap( aDevice.OSAdaption() ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::DMemSpyDriverLogChanHeapWalk() - this: 0x%08x", this )); - } - - -DMemSpyDriverLogChanHeapWalk::~DMemSpyDriverLogChanHeapWalk() - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::~DMemSpyDriverLogChanHeapWalk() - START - this: 0x%08x", this )); - - NKern::ThreadEnterCS(); - - WalkHeapClose(); - - NKern::ThreadLeaveCS(); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::~DMemSpyDriverLogChanHeapWalk() - END - this: 0x%08x", this )); - } - - - - - - - -TInt DMemSpyDriverLogChanHeapWalk::Request( TInt aFunction, TAny* a1, TAny* a2 ) - { - TInt r = DMemSpyDriverLogChanBase::Request( aFunction, a1, a2 ); - if ( r == KErrNone ) - { - switch( aFunction ) - { - case EMemSpyDriverOpCodeWalkHeapInit: - r = WalkHeapInit( (TMemSpyDriverInternalWalkHeapParamsInit*) a1 ); - break; - case EMemSpyDriverOpCodeWalkHeapGetCellInfo: - r = WalkHeapGetCellInfo( (TAny*) a1, (TMemSpyDriverInternalWalkHeapParamsCell*) a2 ); - break; - case EMemSpyDriverOpCodeWalkHeapReadCellData: - r = WalkHeapReadCellData( (TMemSpyDriverInternalWalkHeapCellDataReadParams*) a1 ); - break; - case EMemSpyDriverOpCodeWalkHeapNextCell: - r = WalkHeapNextCell( (TUint) a1, (TMemSpyDriverInternalWalkHeapParamsCell*) a2 ); - break; - case EMemSpyDriverOpCodeWalkHeapClose: - r = WalkHeapClose(); - break; - - default: - r = KErrNotSupported; - break; - } - } - // - return r; - } - - -TBool DMemSpyDriverLogChanHeapWalk::IsHandler( TInt aFunction ) const - { - return ( aFunction > EMemSpyDriverOpCodeWalkHeapBase && aFunction < EMemSpyDriverOpCodeWalkHeapEnd ); - } - - - - - - - - - - - - - - - - - - - - - - -TInt DMemSpyDriverLogChanHeapWalk::WalkHeapInit( TMemSpyDriverInternalWalkHeapParamsInit* aParams ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit() - START")); - __ASSERT_ALWAYS( !iHeapWalkInitialised && iWalkHeap.Helper() == NULL, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkPending ) ); - - TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &iHeapWalkInitialParameters, sizeof(TMemSpyDriverInternalWalkHeapParamsInit) ); - if ( r == KErrNone ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, iHeapWalkInitialParameters.iDebugAllocator)); - - r = OpenTempObject( iHeapWalkInitialParameters.iTid, EThread ); - if ( r == KErrNone ) - { - // Find the chunk with the correct handle - DThread* thread = (DThread*) TempObject(); - if ( SuspensionManager().IsSuspended( *thread ) ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - thread: %O", thread)); - - // Open client's heap - r = iWalkHeap.OpenUserHeap(*thread, iHeapWalkInitialParameters.iDebugAllocator); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - opening client heap returned: %d", r) ); - - if ( r == KErrNone ) - { - // Indicates that we've initiated a walk - so we can tell whether to close - // the chunk later on. - iHeapWalkInitialised = ETrue; - iWalkHeapCellIndex = 0; - - // Walk the client's heap - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - calling heap walker constructor...")); - RMemSpyDriverHeapWalker heapWalker(iWalkHeap); - - TMemSpyDriverLogChanHeapWalkObserver observer( *this ); - heapWalker.SetObserver( &observer ); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - starting traversal...")); - r = heapWalker.Traverse(); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - finished traversal - err: %d", r)); - } - - // If the initialise process didn't complete successfully, then we must be sure - // to release the associated heap chunk - if ( r < KErrNone ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - error scenario - releasing kernel heap chunk copy" )); - iWalkHeap.Close(); - } - } - else - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - parent process not suspended => KErrAccessDenied")); - r = KErrAccessDenied; - } - - CloseTempObject(); - } - else - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - thread not found")); - } - } - else - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - params read error: %d", r)); - } - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit() - END - ret: %d", r)); - return r; - } - - -TInt DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell( TUint aTid, TMemSpyDriverInternalWalkHeapParamsCell* aParams ) - { - const TInt walkedHeapCellCount = iWalkHeapCells.Count(); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell() - START - current cell count: %d", walkedHeapCellCount)); - __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); - - // Open the original thread - TInt r = OpenTempObject( aTid, EThread ); - if ( r == KErrNone ) - { - // Get the thread handle and that we have suspended the process' threads - DThread* thread = (DThread*) TempObject(); - if ( SuspensionManager().IsSuspended( *thread ) ) - { - NKern::ThreadEnterCS(); - - if ( walkedHeapCellCount > 0 && iWalkHeapCellIndex >= 0 && iWalkHeapCellIndex < walkedHeapCellCount ) - { - // Write back head cell to user-space - TMemSpyDriverInternalWalkHeapParamsCell cell( iWalkHeapCells[ iWalkHeapCellIndex++ ] ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell - returning... cellType: %1d, addr: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", cell.iCellType, cell.iCellAddress, cell.iLength, cell.iNestingLevel, cell.iAllocNumber )); - - r = Kern::ThreadRawWrite( &ClientThread(), aParams, &cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) ); - if ( r != KErrNone ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell - params read error: %d", r)); - } - } - else - { - r = KErrEof; - } - - NKern::ThreadLeaveCS(); - } - else - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell - parent process not suspended => KErrAccessDenied")); - r = KErrAccessDenied; - } - - CloseTempObject(); - } - else - { - Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell - thread not found"); - } - // - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell() - END - ret: %d", r)); - return r; - } - - -TInt DMemSpyDriverLogChanHeapWalk::WalkHeapClose() - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose() - START")); - // - if ( iHeapWalkInitialised ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose - heap walk was still open...")); - NKern::ThreadEnterCS(); - - iWalkHeap.Close(); - - // Discard handled cells - iWalkHeapCells.Reset(); - - iHeapWalkInitialised = EFalse; - - NKern::ThreadLeaveCS(); - } - // - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose() - END")); - return KErrNone; - } - - -TInt DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData(TMemSpyDriverInternalWalkHeapCellDataReadParams* aParams) - { - __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); - // - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable)); - // - TMemSpyDriverInternalWalkHeapCellDataReadParams params; - TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalWalkHeapCellDataReadParams) ); - if ( r != KErrNone ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END - params read error: %d", r)); - return r; - } - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cell: 0x%08x, readLen: %8d, writeAddr: 0x%08x", params.iCellAddress, params.iReadLen, params.iDes)); - - // Open the original thread - r = OpenTempObject( iHeapWalkInitialParameters.iTid, EThread ); - if ( r == KErrNone ) - { - // Get the thread handle - DThread* thread = (DThread*) TempObject(); - - // Check the threads in the process are suspended - if ( SuspensionManager().IsSuspended( *thread ) ) - { - // Check we can find the cell in the cell list... - const TMemSpyDriverInternalWalkHeapParamsCell* cell = CellInfoForSpecificAddress( params.iCellAddress ); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cell: 0x%08x for address: 0x%08x", cell, params.iCellAddress )); - - if ( cell ) - { - const TInt cellLen = cell->iLength; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellLen: %d", cellLen )); - - if ( params.iReadLen <= cellLen ) - { - - // Get user side descriptor length info - TInt destLen = 0; - TInt destMax = 0; - TUint8* destPtr = NULL; - - r = Kern::ThreadGetDesInfo( &ClientThread(), params.iDes, destLen, destMax, destPtr, ETrue ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", params.iDes, destPtr, destLen, destMax, r )); - - // Work out the start offset for the data... - if ( r == KErrNone && destMax >= params.iReadLen ) - { - const TAny* srcPos = ((TUint8*) cell->iCellAddress); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - srcPos: 0x%08x", srcPos )); - - // Read some data - r = Kern::ThreadRawRead( thread, srcPos, destPtr, params.iReadLen ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - read from thread returned: %d", r)); - - if ( r == KErrNone ) - { - // Client will update descriptor length in this situation. - r = params.iReadLen; - } - } - else - { - if ( r != KErrBadDescriptor ) - { - r = KErrArgument; - Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - user-descriptor isnt big enough for requested data" ); - } - else - { - Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - bad or non-writable user-side descriptor" ); - } - } - } - else - { - r = KErrArgument; - Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - read length is bigger than cell length"); - } - } - else - { - r = KErrArgument; - Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - no cell at user supplied address!"); - } - } - else - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - parent process not suspended => KErrAccessDenied")); - r = KErrAccessDenied; - } - - CloseTempObject(); - } - else - { - Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - thread not found"); - } - // - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END result=%d", r)); - return r; - } - - -TInt DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo( TAny* aCellAddress, TMemSpyDriverInternalWalkHeapParamsCell* aParams ) - { - __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); - // - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable)); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - cell: 0x%08x", aCellAddress)); - - // Open the original thread - TInt r = OpenTempObject( iHeapWalkInitialParameters.iTid, EThread ); - if (r != KErrNone) - { - Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END - thread not found"); - return r; - } - - // Get the thread handle - DThread* thread = (DThread*) TempObject(); - - // Check the threads in the process are suspended - if ( !SuspensionManager().IsSuspended( *thread ) ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - END - parent process not suspended => KErrAccessDenied")); - CloseTempObject(); - return KErrAccessDenied; - } - - // Check we can find the cell in the cell list... - const TMemSpyDriverInternalWalkHeapParamsCell* cell = CellInfoForSpecificAddress( aCellAddress ); - if ( cell == NULL ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - no exact match for address: 0x%08x...", aCellAddress)); - - // If the cell still wasn't found, then let's look for any heap cell that contains - // the client-specified address (i.e. find the heap cell that contains the specified - // address). - if ( cell == NULL ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - still couldnt find cell by exact address. Searching for the cell that contains the specified address...")); - cell = CellInfoForAddressWithinCellRange( aCellAddress ); - } - } - - if ( cell ) - { - // Have enough info to write back to client now - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - returning... cellType: %1d, addr: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", cell->iCellType, cell->iCellAddress, cell->iLength, cell->iNestingLevel, cell->iAllocNumber )); - r = Kern::ThreadRawWrite( &ClientThread(), aParams, cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) ); - } - else - { - r = KErrArgument; - Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - no cell at user supplied address!"); - } - - CloseTempObject(); - // - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END result=%d", r)); - return r; - } - - - - - - - - - - - - - - - - - - - - - - - - - - - -const TMemSpyDriverInternalWalkHeapParamsCell* DMemSpyDriverLogChanHeapWalk::CellInfoForAddressWithinCellRange( TAny* aAddress ) const - { - const TMemSpyDriverInternalWalkHeapParamsCell* ret = NULL; - // - const TInt count = iWalkHeapCells.Count(); - for(TInt i=0; i= item.iCellAddress && aAddress < cellExtent ) - { - ret = &item; - } - } - // - return ret; - } - - -const TMemSpyDriverInternalWalkHeapParamsCell* DMemSpyDriverLogChanHeapWalk::CellInfoForSpecificAddress( TAny* aAddress ) const - { - const TMemSpyDriverInternalWalkHeapParamsCell* ret = NULL; - // - const TInt count = iWalkHeapCells.Count(); - for(TInt i=0; i