memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapBase.cpp
changeset 0 a03f92240627
child 18 3406c99bc375
equal deleted inserted replaced
-1:000000000000 0:a03f92240627
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "MemSpyDriverLogChanHeapBase.h"
       
    19 
       
    20 // System includes
       
    21 #include <u32hal.h>
       
    22 #include <e32rom.h>
       
    23 #include <memspy/driver/memspydriverobjectsshared.h>
       
    24 
       
    25 // Shared includes
       
    26 #include "MemSpyDriverOpCodes.h"
       
    27 #include "MemSpyDriverObjectsInternal.h"
       
    28 
       
    29 // User includes
       
    30 #include "MemSpyDriverHeap.h"
       
    31 #include "MemSpyDriverUtils.h"
       
    32 #include "MemSpyDriverDevice.h"
       
    33 #include "MemSpyDriverOSAdaption.h"
       
    34 
       
    35 // Constants
       
    36 const TInt KMemSpyDriverLogChanHeapBaseXferBufferSize = 1024 * 16;
       
    37 
       
    38 
       
    39 
       
    40 
       
    41 DMemSpyDriverLogChanHeapBase::DMemSpyDriverLogChanHeapBase( DMemSpyDriverDevice& aDevice, DThread& aThread )
       
    42 :	DMemSpyDriverLogChanBase( aDevice, aThread )
       
    43     {
       
    44 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::DMemSpyDriverLogChanHeapBase() - this: 0x%08x", this ));
       
    45     }
       
    46 
       
    47 
       
    48 DMemSpyDriverLogChanHeapBase::~DMemSpyDriverLogChanHeapBase()
       
    49 	{
       
    50 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::~DMemSpyDriverLogChanHeapBase() - START - this: 0x%08x", this ));
       
    51 
       
    52     ReleaseFreeCells();
       
    53 
       
    54 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::~DMemSpyDriverLogChanHeapBase() - END - this: 0x%08x", this ));
       
    55 	}
       
    56 
       
    57 
       
    58 TInt DMemSpyDriverLogChanHeapBase::Construct()
       
    59 	{
       
    60 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::Construct() - START - this: 0x%08x", this ));
       
    61     
       
    62     const TInt ret = BaseConstruct( KMemSpyDriverLogChanHeapBaseXferBufferSize );
       
    63 
       
    64 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::Construct() - END - this: 0x%08x, err: %d", this, ret ));
       
    65     return ret;
       
    66 	}
       
    67 
       
    68 
       
    69 
       
    70 
       
    71 
       
    72 
       
    73 
       
    74 
       
    75 
       
    76 
       
    77 
       
    78 TInt DMemSpyDriverLogChanHeapBase::Request( TInt aFunction, TAny* a1, TAny* a2 )
       
    79 	{
       
    80 	const TInt r = DMemSpyDriverLogChanBase::Request( aFunction, a1, a2 );
       
    81     return r;
       
    82 	}
       
    83 
       
    84 
       
    85 
       
    86 
       
    87 
       
    88 
       
    89 
       
    90 
       
    91 
       
    92 
       
    93 
       
    94 
       
    95 
       
    96 DMemSpyDriverLogChanHeapBase::TDrmMatchType DMemSpyDriverLogChanHeapBase::IsDrmThread( DThread& aThread )
       
    97     {
       
    98     TDrmMatchType ret = EMatchTypeNone;
       
    99     //
       
   100     const TUid procUid = aThread.iOwningProcess->iUids.iUid[ 2 ];
       
   101     TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::IsDrmThread() - START - aThread: %O, process uid: 0x%08x", &aThread, procUid.iUid ));
       
   102 
       
   103     // Some more rudimentary checks based upon process name and
       
   104     // known uids.
       
   105     TFullName fullName;
       
   106     aThread.FullName( fullName );
       
   107 
       
   108     // Exclude threads containing "DRM"
       
   109     _LIT( KDrmThreadMatchText, "*DRM*" );
       
   110     const TInt matchPos = fullName.MatchF( KDrmThreadMatchText );
       
   111     if ( matchPos >= 0 )
       
   112         {
       
   113         TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::IsDrmThread() - found \'DRM\' at pos: %d (%S)", matchPos, &fullName ));
       
   114         ret = EMatchTypeName;
       
   115         }
       
   116     else
       
   117         {
       
   118         // Some known DRM related process UIDs
       
   119         switch( procUid.iUid )
       
   120             {
       
   121         case 0x10005A22: // DRMEncryptor.exe
       
   122         case 0x01105901: // DRMEncryptor.exe
       
   123         case 0x101F85C7: // DRMRightsManager.exe
       
   124         case 0x10205CA8: // DcfRepSrv.exe
       
   125         case 0x101F51F2: // RightsServer.exe
       
   126         case 0x101F6DC5: // DRMHelperServer.exe
       
   127         case 0x10282F1B: // wmdrmserver.exe
       
   128             ret = EMatchTypeUid;
       
   129             break;
       
   130         default:
       
   131             ret = EMatchTypeNone;
       
   132             break;
       
   133             }
       
   134         }
       
   135 
       
   136     TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::IsDrmThread() - END - procUid: 0x%08x, matchType: %d", procUid.iUid, ret ));
       
   137     return ret;
       
   138     }
       
   139 
       
   140 
       
   141 
       
   142 
       
   143 
       
   144 
       
   145 
       
   146 
       
   147 
       
   148 
       
   149 
       
   150 
       
   151 
       
   152 
       
   153 
       
   154 
       
   155 
       
   156 
       
   157 
       
   158 
       
   159 
       
   160 
       
   161 
       
   162 
       
   163 
       
   164 
       
   165 
       
   166 
       
   167 
       
   168 
       
   169 
       
   170 
       
   171 
       
   172 
       
   173 
       
   174 
       
   175 
       
   176 TInt DMemSpyDriverLogChanHeapBase::OpenUserHeap( DThread& aClientThread, TUint aExpectedHeapVTable, RMemSpyDriverRHeapUser& aHeap, DChunk*& aUserHeapChunk, TDes8* aClientHeapChunkName )
       
   177     {
       
   178     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap() - START - aHeap.ChunkIsInitialised: %d, aExpectedHeapVTable: 0x%08x, aClientThread: %O", aHeap.ChunkIsInitialised(), aExpectedHeapVTable, &aClientThread ));
       
   179     __ASSERT_ALWAYS( aHeap.ChunkIsInitialised() == EFalse, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapChunkAlreadyCloned ) );
       
   180 
       
   181     TInt r = KErrNotFound;
       
   182     aUserHeapChunk = NULL;
       
   183     
       
   184     NKern::ThreadEnterCS();
       
   185 
       
   186     const TBool allocatorIsReallyRHeap = GetUserHeapHandle( aClientThread, aHeap, aExpectedHeapVTable );
       
   187 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - allocatorIsReallyRHeap: %d", allocatorIsReallyRHeap));
       
   188 
       
   189     if  ( allocatorIsReallyRHeap )
       
   190         {
       
   191         RAllocator* allocator = OSAdaption().DThread().GetAllocator( aClientThread );
       
   192 
       
   193         // Open client's heap chunk in order to read it's dimensions
       
   194         const TInt clientsHeapChunkHandle = aHeap.iChunkHandle;
       
   195 	    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clientsHeapChunkHandle: 0x%08x, allocatorAddress: 0x%08x", clientsHeapChunkHandle, allocator));
       
   196 
       
   197  	    NKern::LockSystem();
       
   198         DChunk* clientsHeapChunk = (DChunk*) Kern::ObjectFromHandle( &aClientThread, clientsHeapChunkHandle, EChunk );
       
   199         NKern::UnlockSystem();
       
   200 	    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clientsHeapChunk: 0x%08x", clientsHeapChunk ));
       
   201        
       
   202         if  ( clientsHeapChunk != NULL )
       
   203             {
       
   204             // Get the chunk name (if the caller asked for it)
       
   205             if  ( aClientHeapChunkName )
       
   206                 {
       
   207                 clientsHeapChunk->FullName( *aClientHeapChunkName );
       
   208                 }
       
   209                 
       
   210             // Update the heap chunk pointer. We do this now because this
       
   211             // should point to the _real_ user-side heap chunk, rather than
       
   212             // the copy of the chunk that we are about to make.
       
   213             aUserHeapChunk = clientsHeapChunk;
       
   214 
       
   215             // Set up ourselves to duplicate their heap chunk
       
   216             const TInt clientsHeapChunkSize = OSAdaption().DChunk().GetSize( *clientsHeapChunk );
       
   217 	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - chunkBase: 0x%08x, size: %8d, maxLen: %8d, chunk: %O", clientsHeapChunk->iBase, clientsHeapChunkSize, clientsHeapChunk->iMaxSize, clientsHeapChunk ));
       
   218 
       
   219             // Make a new chunk that is the same size, owned by this thread.
       
   220             TChunkCreateInfo info;
       
   221             info.iType         = TChunkCreateInfo::ESharedKernelSingle;
       
   222             info.iMaxSize      = clientsHeapChunkSize;
       
   223             info.iOwnsMemory   = ETrue; // Use memory from system's free pool
       
   224             info.iDestroyedDfc = NULL;
       
   225         #ifdef __EPOC32__
       
   226             info.iMapAttr      = (TInt)EMapAttrFullyBlocking; // Full caching
       
   227         #endif
       
   228 
       
   229             // Holds a copy of the client's heap chunk
       
   230             DChunk* heapCopyChunk;
       
   231             TLinAddr heapCopyChunkAddress;
       
   232             TUint32 heapCopyChunkMappingAttributes;
       
   233             r = Kern::ChunkCreate( info, heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes );
       
   234 	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - creating chunk returned: %d", r));
       
   235             //
       
   236             if  ( r == KErrNone )
       
   237                 {
       
   238 	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - copy chunk base: 0x%08x, heapCopyChunkAddress: 0x%08x", heapCopyChunk->iBase, heapCopyChunkAddress));
       
   239                 
       
   240                 // Commit memory for entire buffer
       
   241                 TUint32 physicalAddress = 0;
       
   242                 r = Kern::ChunkCommitContiguous( heapCopyChunk, 0, clientsHeapChunkSize, physicalAddress );
       
   243 	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - commiting chunk returned: %d", r));
       
   244 
       
   245                 if  ( r != KErrNone)
       
   246                     {
       
   247                     // On error, thow away the chunk we have created
       
   248                     Kern::ChunkClose( heapCopyChunk );
       
   249                     heapCopyChunk = NULL;
       
   250                     }
       
   251                 else
       
   252                     {
       
   253     	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - heapCopyChunk->iSize: 0x%08x, heapCopyChunk->iBase: 0x%08x, heapCopyChunkAddress: 0x%08x, physicalAddress: 0x%08x", heapCopyChunk->iSize, heapCopyChunk->iBase, heapCopyChunkAddress, physicalAddress));
       
   254     
       
   255                     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - trying to copy %d bytes from clients allocator address of 0x%08x", clientsHeapChunkSize, allocator ));
       
   256                     r = Kern::ThreadRawRead( &aClientThread, allocator, (TAny*) heapCopyChunkAddress, clientsHeapChunkSize );
       
   257 
       
   258                     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - read result of clients heap data is: %d", r));
       
   259                     if  ( r == KErrNone )
       
   260                         {
       
   261                         // Transfer ownership of the copy heap chunk to the heap object. This also calculates the delta
       
   262                         // beween the heap addresses in the client's address space and the kernel address space.
       
   263                         aHeap.AssociateWithKernelChunk( heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes );
       
   264                         }
       
   265                     }
       
   266                 }
       
   267             }
       
   268         else
       
   269             {
       
   270 	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - could not open clients heap chunk by its handle" ) );
       
   271             r = KErrNotFound;
       
   272             }
       
   273         }
       
   274     else
       
   275         {
       
   276 	    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clients heap is not an RHeap (allocated vTable mismatch)" ) );
       
   277         r = KErrNotSupported;
       
   278         }
       
   279 
       
   280     NKern::ThreadLeaveCS();
       
   281 
       
   282     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - r: %d", r ));
       
   283     return r;
       
   284     }
       
   285 
       
   286 
       
   287 
       
   288 
       
   289 
       
   290 
       
   291 
       
   292 
       
   293 
       
   294 
       
   295 
       
   296 
       
   297 
       
   298 
       
   299 
       
   300 
       
   301 
       
   302 
       
   303 
       
   304 
       
   305 
       
   306 
       
   307 
       
   308 TBool DMemSpyDriverLogChanHeapBase::GetUserHeapHandle( DThread& aThread, RMemSpyDriverRHeapUser& aHeap, TUint aExpectedVTable )
       
   309     {
       
   310     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle() - START - aExpectedVTable: 0x%08x", aExpectedVTable) );
       
   311 
       
   312     RAllocator* allocator = OSAdaption().DThread().GetAllocator( aThread );
       
   313 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - allocator addr: 0x%08x", allocator) );
       
   314     TUint* pAllocator = (TUint*) allocator;
       
   315     // 
       
   316     TBool vTableOkay = EFalse;
       
   317     TUint vtable = 0;
       
   318 
       
   319     // Read a bit more data than is available for debugging purposes
       
   320     TBuf8<32> vtableBuf;
       
   321     TInt r = Kern::ThreadRawRead( &aThread, pAllocator, (TUint8*) vtableBuf.Ptr(), vtableBuf.MaxLength() );
       
   322     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - read result of vtable data from requested thread is: %d", r));
       
   323     if  ( r == KErrNone )
       
   324         {
       
   325         TRACE( MemSpyDriverUtils::DataDump("allocator vtable data - %lS", vtableBuf.Ptr(), vtableBuf.MaxLength(), vtableBuf.MaxLength() ) );
       
   326         vtableBuf.SetLength( vtableBuf.MaxLength() );
       
   327         
       
   328         vtable = vtableBuf[0] +
       
   329                 (vtableBuf[1] << 8) + 
       
   330                 (vtableBuf[2] << 16) + 
       
   331                 (vtableBuf[3] << 24);
       
   332         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - client VTable is: 0x%08x", vtable) );
       
   333 
       
   334         // Check the v-table to work out if it really is an RHeap
       
   335         vTableOkay = ( vtable == aExpectedVTable );
       
   336         if  ( vTableOkay )
       
   337             {
       
   338             TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - vtables okay") );
       
   339             r = aHeap.ReadFromUserAllocator( aThread );
       
   340             TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - after userget, error: %d", r));
       
   341         
       
   342             }
       
   343         else
       
   344             {
       
   345             TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - vtables dont match! - aExpectedVTable: 0x%08x, allocator addr: 0x%08x, client VTable is: 0x%08x, aThread: %O", aExpectedVTable, allocator, vtable, &aThread ) );
       
   346             }
       
   347         }
       
   348     else
       
   349         {
       
   350         TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - error during client vTable reading: %d, aThread: %O", r, &aThread ) );
       
   351         }
       
   352     //
       
   353     return (vTableOkay && (r == KErrNone));
       
   354     }
       
   355 
       
   356 
       
   357 
       
   358 
       
   359 
       
   360 
       
   361 
       
   362 
       
   363 
       
   364 
       
   365 
       
   366 
       
   367 
       
   368 
       
   369 void DMemSpyDriverLogChanHeapBase::PrintHeapInfo( const TMemSpyHeapInfo& aInfo )
       
   370     {
       
   371     const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
       
   372     const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData();
       
   373     const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics();
       
   374     const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
       
   375 
       
   376     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   377     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator                                      -" ) );
       
   378     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   379     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iAccessCount:       %d", rHeapObjectData.iAccessCount ) );
       
   380     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iHandleCount:       %d", rHeapObjectData.iHandleCount ) );
       
   381     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iHandles:           0x%08x", rHeapObjectData.iHandles ) );
       
   382     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iFlags:             0x%08x", rHeapObjectData.iFlags ) );
       
   383     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iCellCount:         %d", rHeapObjectData.iCellCount ) );
       
   384     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iTotalAllocSize:    %d", rHeapObjectData.iTotalAllocSize ) );
       
   385     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) );
       
   386 
       
   387     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   388     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap                                           -" ) );
       
   389     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   390     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iMinLength:              %d", rHeapObjectData.iMinLength ) );
       
   391     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iMaxLength:              %d", rHeapObjectData.iMaxLength ) );
       
   392     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iOffset:                 %d", rHeapObjectData.iOffset ) );
       
   393     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iGrowBy:                 %d", rHeapObjectData.iGrowBy ) );
       
   394     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iChunkHandle:            0x%08x", rHeapObjectData.iChunkHandle ) );
       
   395     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iBase:                   0x%08x", rHeapObjectData.iBase ) );
       
   396     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iTop:                    0x%08x", rHeapObjectData.iTop ) );
       
   397     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iAlign:                  %d", rHeapObjectData.iAlign ) );
       
   398     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iMinCell:                %d", rHeapObjectData.iAlign ) );
       
   399     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iPageSize:               %d", rHeapObjectData.iAlign ) );
       
   400     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iFree.next:              0x%08x", rHeapObjectData.iFree.next ) );
       
   401     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iFree.len:               %d", rHeapObjectData.iFree.len ) );
       
   402     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iNestingLevel:           %d", rHeapObjectData.iNestingLevel ) );
       
   403     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iAllocCount:             %d", rHeapObjectData.iAllocCount ) );
       
   404     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iFailType:               %d", rHeapObjectData.iFailType ) );
       
   405     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iFailRate:               %d", rHeapObjectData.iFailRate ) );
       
   406     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iFailed:                 %d", rHeapObjectData.iFailed ) );
       
   407     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iFailAllocCount:         %d", rHeapObjectData.iFailAllocCount ) );
       
   408     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iRand:                   %d", rHeapObjectData.iRand ) );
       
   409     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iTestData:               0x%08x", rHeapObjectData.iTestData ) );
       
   410     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) );
       
   411 
       
   412     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   413     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Free)                                    -" ) );
       
   414     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   415     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell count:                     %d", rHeapStats.StatsFree().TypeCount() ) );
       
   416     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell size:                      %d", rHeapStats.StatsFree().TypeSize() ) );
       
   417     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest:                   0x%08x", rHeapStats.StatsFree().LargestCellAddress() ) );
       
   418     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest size:              %d", rHeapStats.StatsFree().LargestCellSize() ) );
       
   419     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - slack:                          0x%08x", rHeapStats.StatsFree().SlackSpaceCellAddress() ) );
       
   420     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - slack size:                     %d", rHeapStats.StatsFree().SlackSpaceCellSize() ) );
       
   421     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - checksum:                       0x%08x", rHeapStats.StatsFree().Checksum() ) );
       
   422     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) );
       
   423 
       
   424     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   425     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Alloc)                                   -" ) );
       
   426     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   427     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell count:                     %d", rHeapStats.StatsAllocated().TypeCount() ) );
       
   428     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell size:                      %d", rHeapStats.StatsAllocated().TypeSize() ) );
       
   429     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest:                   0x%08x", rHeapStats.StatsAllocated().LargestCellAddress() ) );
       
   430     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest size:              %d", rHeapStats.StatsAllocated().LargestCellSize() ) );
       
   431     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) );
       
   432 
       
   433     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   434     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Common)                                  -" ) );
       
   435     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   436     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - total cell count:               %d", rHeapStats.StatsCommon().TotalCellCount() ) );
       
   437     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) );
       
   438 
       
   439     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   440     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Misc. Info                                      -" ) );
       
   441     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   442     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk size:                     %d", rHeapMetaData.ChunkSize() ) );
       
   443     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk handle:                   0x%08x", rHeapMetaData.ChunkHandle() ) );
       
   444     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk base address:             0x%08x", rHeapMetaData.ChunkBaseAddress() ) );
       
   445     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - debug allocator:                %d", rHeapMetaData.IsDebugAllocator() ) );
       
   446     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - shared heap:                    %d", rHeapMetaData.IsSharedHeap() ) );
       
   447     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - user thread:                    %d", rHeapMetaData.IsUserThread() ) );
       
   448     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (free):        %d", rHeapMetaData.HeaderSizeFree() ) );
       
   449     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (alloc):       %d", rHeapMetaData.HeaderSizeAllocated() ) );
       
   450     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap vTable:                    0x%08x", rHeapMetaData.VTable() ) );
       
   451     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap object size:               %d", rHeapMetaData.ClassSize() ) );
       
   452     }
       
   453 
       
   454 
       
   455 
       
   456 
       
   457 
       
   458 
       
   459 
       
   460 
       
   461 
       
   462 
       
   463 TBool DMemSpyDriverLogChanHeapBase::IsDebugKernel()
       
   464     {
       
   465     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - START") );
       
   466     
       
   467     TInt r = KErrNone;
       
   468     TBool debugKernel = EFalse;
       
   469 
       
   470     NKern::ThreadEnterCS();
       
   471     RMemSpyDriverRHeapKernelInPlace rHeap;
       
   472     r = OpenKernelHeap( rHeap );
       
   473     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - open kernel heap returned: %d", r) );
       
   474 
       
   475     if  ( r == KErrNone )
       
   476         {
       
   477         debugKernel = IsDebugKernel( rHeap );
       
   478 
       
   479         // Tidy up
       
   480         rHeap.DisassociateWithKernelChunk();
       
   481         }
       
   482 
       
   483     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - debugKernel: %d", debugKernel) );
       
   484     NKern::ThreadLeaveCS();
       
   485 
       
   486  	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - END - ret: %d", r) );
       
   487     return debugKernel;
       
   488     }
       
   489 
       
   490 
       
   491 TBool DMemSpyDriverLogChanHeapBase::IsDebugKernel( RMemSpyDriverRHeapKernelInPlace& aHeap )
       
   492     {
       
   493     TBool debugKernel = EFalse;
       
   494     //
       
   495  	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - START") );
       
   496     NKern::ThreadEnterCS();
       
   497 
       
   498     // Request that the kernel fail the next heap allocation
       
   499     aHeap.FailNext();
       
   500 
       
   501     // Allocate a new cell, and in debug builds of the kernel, this should be NULL
       
   502     TInt* cell = new TInt();
       
   503     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - cell: 0x%08x", cell) );
       
   504     debugKernel = ( cell == NULL );
       
   505     delete cell;
       
   506 
       
   507     NKern::ThreadLeaveCS();
       
   508  	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - END - debugKernel: %d", debugKernel) );
       
   509     //
       
   510     return debugKernel;
       
   511     }
       
   512 
       
   513 
       
   514 TInt DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel( RMemSpyDriverRHeapBase& aHeap, TBool aIsDebugAllocator, const TDesC8& aChunkName, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer )
       
   515     {
       
   516     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel() - START - aTransferBuffer: 0x%08x", aTransferBuffer ) );
       
   517 
       
   518     TInt r = KErrNone;
       
   519     NKern::ThreadEnterCS();
       
   520 
       
   521     // This object holds all of the info we will accumulate for the client.
       
   522     TMemSpyHeapInfo masterHeapInfo;
       
   523     masterHeapInfo.SetType( TMemSpyHeapInfo::ETypeRHeap );
       
   524     masterHeapInfo.SetTid( 2 );
       
   525     masterHeapInfo.SetPid( 1 );
       
   526 
       
   527     // This is the RHeap-specific object that contains all RHeap info
       
   528     TMemSpyHeapInfoRHeap& rHeapInfo = masterHeapInfo.AsRHeap();
       
   529 
       
   530     // This is the object data for the RHeap instance
       
   531     TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData();
       
   532     aHeap.CopyObjectDataTo( rHeapObjectData );
       
   533 
       
   534     // When walking the kernel heap we must keep track of the free cells
       
   535     // without allocating any more memory (on the kernel heap...)
       
   536     //
       
   537     // Therefore, we start a stream immediately, which is actually already
       
   538     // pre-allocated.
       
   539     //
       
   540     // Start stream and pad with zero count, which we'll repopulate later on
       
   541     // once we know the final score.
       
   542     RMemSpyMemStreamWriter stream;
       
   543     TInt32* pCount = NULL;
       
   544 
       
   545     // We must walk the client's heap in order to build statistics
       
   546     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - calling heap walker constructor..."));
       
   547     RMemSpyDriverHeapWalker heapWalker( aHeap, aIsDebugAllocator );
       
   548     if  ( aTransferBuffer )
       
   549         {
       
   550         // This will allow us to identify that we're writing directly to the stream
       
   551         stream = OpenXferStream();
       
   552         iStackStream = &stream;
       
   553 
       
   554         // Writer marker value which we'll update after the traversal completes
       
   555         pCount = stream.WriteInt32( 0 );
       
   556 
       
   557         // Receive cell info as we walk the heap...
       
   558         heapWalker.SetObserver( this );
       
   559         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - collecting free cells - iStackStream: 0x%08x, isOpen: %d, pCount: 0x%08x", iStackStream, stream.IsOpen(), pCount ));
       
   560         }
       
   561     else
       
   562         {
       
   563         iStackStream = NULL;
       
   564         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - not collecting free cells"));
       
   565         }
       
   566 
       
   567     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - locking system..." ));
       
   568     NKern::LockSystem();
       
   569     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - disabling interrupts..." ));
       
   570     const TInt irq = NKern::DisableAllInterrupts();
       
   571     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - starting traversal..." ));
       
   572 
       
   573 #if defined( TRACE_TYPE_KERNELHEAP )
       
   574     heapWalker.SetPrintDebug();
       
   575 #endif
       
   576     r = heapWalker.Traverse();
       
   577 
       
   578     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - restoring interrupts..." ));
       
   579     NKern::RestoreInterrupts( irq );
       
   580     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - finished traversal - err: %d, iStackStream: 0x%08x, pCount: 0x%08x, isOpen: %d", r, iStackStream, pCount, ( iStackStream == NULL ? 0 : iStackStream->IsOpen() ) ));
       
   581     NKern::UnlockSystem();
       
   582     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - unlocked system" ));
       
   583 
       
   584     // Write free cells if requested
       
   585     if  ( r == KErrNone && iStackStream && iStackStream->IsOpen() && pCount )
       
   586         {
       
   587         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - final free cell count: %d", iFreeCellCount ));
       
   588         *pCount = iFreeCellCount;
       
   589         r = stream.WriteAndClose( aTransferBuffer );
       
   590         iStackStream = NULL;
       
   591         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - stream commit result: %d", r ));
       
   592         }
       
   593 
       
   594     TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics();
       
   595     heapWalker.CopyStatsTo( rHeapStats );
       
   596 
       
   597     // Get remaining meta data that isn't stored elsewhere
       
   598     TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
       
   599     rHeapMetaData.SetChunkName( aChunkName );
       
   600     rHeapMetaData.SetChunkSize( (TUint) aHeap.Chunk().Size() );
       
   601     rHeapMetaData.SetChunkHandle( &aHeap.Chunk() );
       
   602     rHeapMetaData.SetChunkBaseAddress( aHeap.Chunk().Base() );
       
   603     rHeapMetaData.SetDebugAllocator( aIsDebugAllocator );
       
   604     rHeapMetaData.SetHeaderSizeFree( RMemSpyDriverRHeapBase::FreeCellHeaderSize() );
       
   605     rHeapMetaData.SetHeaderSizeAllocated( RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( aIsDebugAllocator ) );
       
   606     rHeapMetaData.SetUserThread( EFalse );
       
   607     rHeapMetaData.SetSharedHeap( ETrue );
       
   608 
       
   609     // Get any heap-specific info
       
   610     aHeap.GetHeapSpecificInfo( masterHeapInfo );
       
   611 
       
   612     PrintHeapInfo( masterHeapInfo );
       
   613 
       
   614     // Update info ready for writing back to the user-side
       
   615     if  ( r == KErrNone )
       
   616         {
       
   617         // Write results back to user-side
       
   618         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - writing to user-side..."));
       
   619         r = Kern::ThreadRawWrite( &ClientThread(), aHeapInfo, &masterHeapInfo, sizeof( TMemSpyHeapInfo ) );
       
   620         }
       
   621 
       
   622     NKern::ThreadLeaveCS();
       
   623 
       
   624 	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel() - END - ret: %d", r) );
       
   625     return r;
       
   626     }
       
   627 
       
   628 
       
   629 
       
   630 
       
   631 
       
   632 
       
   633 
       
   634 
       
   635 
       
   636 
       
   637     
       
   638 
       
   639 
       
   640 
       
   641 
       
   642 
       
   643 
       
   644 TBool DMemSpyDriverLogChanHeapBase::HandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt /*aNestingLevel*/, TInt /*aAllocNumber*/ )
       
   645     {
       
   646     TInt error = KErrNone;
       
   647     //
       
   648     if  ( aCellType == EMemSpyDriverGoodFreeCell || aCellType == EMemSpyDriverBadFreeCellAddress || aCellType == EMemSpyDriverBadFreeCellSize )
       
   649         {
       
   650         TMemSpyDriverFreeCell cell;
       
   651         cell.iType = aCellType;
       
   652         cell.iAddress = aCellAddress;
       
   653         cell.iLength = aLength;
       
   654         //
       
   655         if  ( iStackStream )
       
   656             {
       
   657             if  ( !iStackStream->IsFull() )
       
   658                 {
       
   659                 ++iFreeCellCount;
       
   660                 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::HandleHeapCell - writing free cell %d @ 0x%08x, space left: %u", iFreeCellCount, aCellAddress, iStackStream->Remaining() ));
       
   661                 //
       
   662                 iStackStream->WriteInt32( aCellType );
       
   663                 iStackStream->WriteUint32( reinterpret_cast<TUint32>( aCellAddress ) );
       
   664                 iStackStream->WriteInt32( aLength );
       
   665                 }
       
   666             else
       
   667                 {
       
   668                 Kern::Printf( "DMemSpyDriverLogChanHeapBase::HandleHeapCell - Kernel Free Cell stack stream IS FULL!" );
       
   669                 error = KErrAbort;
       
   670                 }
       
   671             }
       
   672         else
       
   673             {
       
   674             NKern::ThreadEnterCS();
       
   675             error = iFreeCells.Append( cell );
       
   676             NKern::ThreadLeaveCS();
       
   677             //
       
   678             if ( error == KErrNone )
       
   679                 {
       
   680                 ++iFreeCellCount;
       
   681                 }
       
   682             }
       
   683         }
       
   684     //
       
   685     return ( error == KErrNone );
       
   686     }
       
   687 
       
   688 
       
   689 void DMemSpyDriverLogChanHeapBase::HandleHeapWalkInit()
       
   690     {
       
   691     // Can't delete the free cell list here as we might be walking the kernel heap
       
   692     iFreeCellCount = 0;
       
   693     }
       
   694 
       
   695 
       
   696 
       
   697 
       
   698 
       
   699 
       
   700 TInt DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer()
       
   701     {
       
   702     // Transfer free cells immediately from xfer stream
       
   703     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - START - iHeapStream: 0x%08x", iHeapStream ));
       
   704     __ASSERT_ALWAYS( !iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotClosed ) );
       
   705     //
       
   706     TInt r = KErrNoMemory;
       
   707     //
       
   708     NKern::ThreadEnterCS();
       
   709     //
       
   710     iHeapStream = new RMemSpyMemStreamWriter();
       
   711     if  ( iHeapStream )
       
   712         {
       
   713         const TInt requiredMemory = CalculateFreeCellBufferSize();
       
   714         r = OpenXferStream( *iHeapStream, requiredMemory );
       
   715         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - requested %d bytes for free cell list, r: %d", requiredMemory, r ));
       
   716 
       
   717         if  ( r == KErrNone )
       
   718             {
       
   719             const TInt count = iFreeCells.Count();
       
   720             TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - free cell count: %d", count ));
       
   721             //
       
   722             iHeapStream->WriteInt32( count );
       
   723             for( TInt i=0; i<count; i++ )
       
   724                 {
       
   725                 const TMemSpyDriverFreeCell& cell = iFreeCells[ i ];
       
   726                 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - storing entry: %d", i ));
       
   727                 //
       
   728                 iHeapStream->WriteInt32( cell.iType );
       
   729                 iHeapStream->WriteUint32( reinterpret_cast<TUint32>( cell.iAddress ) );
       
   730                 iHeapStream->WriteInt32( cell.iLength );
       
   731                 }
       
   732 
       
   733             // Finished with the array now
       
   734             iFreeCells.Reset();
       
   735 
       
   736             // We return the amount of client-side memory that needs to be allocated to hold the buffer
       
   737             r = requiredMemory;
       
   738             }
       
   739         }
       
   740     //
       
   741     NKern::ThreadLeaveCS();
       
   742                
       
   743     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - END - r: %d", r));
       
   744 	return r;
       
   745     }
       
   746 
       
   747 
       
   748 TInt DMemSpyDriverLogChanHeapBase::FetchFreeCells( TDes8* aBufferSink )
       
   749     {
       
   750     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::FetchFreeCells() - START - iHeapStream: 0x%08x", iHeapStream ));
       
   751     __ASSERT_ALWAYS( iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotOpen ) );
       
   752 
       
   753     TInt r = KErrNone;
       
   754 
       
   755     // Write buffer to client
       
   756     NKern::ThreadEnterCS();
       
   757     r = iHeapStream->WriteAndClose( aBufferSink );
       
   758 
       
   759     // Tidy up
       
   760     ReleaseFreeCells();
       
   761 
       
   762     NKern::ThreadLeaveCS();
       
   763     //
       
   764     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::FetchFreeCells() - END - r: %d", r));
       
   765 	return r;
       
   766     }
       
   767 
       
   768 
       
   769 
       
   770 TInt DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() const
       
   771     {
       
   772     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() - START" ));
       
   773 
       
   774     const TInt count = iFreeCells.Count();
       
   775     const TInt entrySize = sizeof( TInt32 ) + sizeof( TInt32 ) + sizeof( TUint32 );
       
   776     const TInt r = ( count * entrySize ) + sizeof( TInt ); // Extra TInt to hold count
       
   777                 
       
   778     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() - END - r: %d, count: %d, entrySize: %d", r, count, entrySize ));
       
   779 	return r;
       
   780     }
       
   781 
       
   782 
       
   783 
       
   784 void DMemSpyDriverLogChanHeapBase::ReleaseFreeCells()
       
   785     {
       
   786 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::ReleaseFreeCells() - START - this: 0x%08x", this ));
       
   787 
       
   788     // Housekeeping
       
   789     NKern::ThreadEnterCS();
       
   790     iFreeCells.Reset();
       
   791     //
       
   792     iStackStream = NULL;
       
   793     //
       
   794     delete iHeapStream;
       
   795     iHeapStream = NULL;
       
   796     NKern::ThreadLeaveCS();
       
   797 
       
   798     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::ReleaseFreeCells() - END - this: 0x%08x", this ));
       
   799     }
       
   800 
       
   801 
       
   802 
       
   803 
       
   804 
       
   805 
       
   806 
       
   807 
       
   808 
       
   809 
       
   810 
       
   811 
       
   812 
       
   813 
       
   814 
       
   815 
       
   816 
       
   817 
       
   818 
       
   819 
       
   820 
       
   821 
       
   822 
       
   823 
       
   824 
       
   825 
       
   826 
       
   827 
       
   828 
       
   829 
       
   830 TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RHeapK*& aHeap, DChunk*& aChunk, TDes8* aClientHeapChunkName )
       
   831     {
       
   832     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap() - START") );
       
   833 
       
   834     // This is what we're searching for...
       
   835     RHeapK* kernelHeap = NULL;
       
   836     DChunk* kernelHeapChunk = NULL;
       
   837 
       
   838     // Find the SvHeap chunk....
       
   839     _LIT( KKernelServerHeapChunkName, "SvHeap" );
       
   840  	NKern::ThreadEnterCS();
       
   841    
       
   842     DObjectCon* chunkContainer = Kern::Containers()[EChunk];
       
   843     chunkContainer->Wait();
       
   844     NKern::LockSystem();
       
   845     const TInt chunkCount = chunkContainer->Count();
       
   846 
       
   847     for(TInt i=0; i<chunkCount; i++)
       
   848         {
       
   849         DChunk* chunk = (DChunk*) (*chunkContainer)[ i ];
       
   850         //
       
   851         if  ( chunk->NameBuf() )
       
   852             {
       
   853             const TInt findResult = chunk->NameBuf()->Find( KKernelServerHeapChunkName );
       
   854     	    TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap - checking chunk: %O against %S => %d", chunk, &KKernelServerHeapChunkName, findResult ) );
       
   855             if  ( findResult != KErrNotFound )
       
   856                 {
       
   857                 // Found it.
       
   858                 kernelHeapChunk = chunk;
       
   859                 TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - found chunk with base: 0x%08x", chunk->iBase ) );
       
   860                 break;
       
   861                 }
       
   862             }
       
   863         }
       
   864 
       
   865     NKern::UnlockSystem();
       
   866     chunkContainer->Signal();
       
   867 
       
   868     TInt r = KErrNotFound;
       
   869     if  ( kernelHeapChunk != NULL )
       
   870         {
       
   871 #ifndef __WINS__
       
   872         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - kernelHeapChunk: 0x%08x", kernelHeapChunk ) );
       
   873 
       
   874         const TRomHeader& romHdr = Epoc::RomHeader();
       
   875 	    const TRomEntry* primaryEntry = (const TRomEntry*) Kern::SuperPage().iPrimaryEntry;
       
   876         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - primaryEntry: 0x%08x, primaryEntry->iAddressLin: 0x%08x", primaryEntry, primaryEntry->iAddressLin ) );
       
   877 	    const TRomImageHeader* primaryImageHeader = (const TRomImageHeader*) primaryEntry->iAddressLin;
       
   878         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - primaryEntry: 0x%08x", primaryImageHeader ) );
       
   879 
       
   880         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iCodeSize:            0x%08x", primaryImageHeader->iCodeSize ) );
       
   881         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iTextSize:            0x%08x", primaryImageHeader->iTextSize ) );
       
   882         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iDataSize:            0x%08x", primaryImageHeader->iDataSize ) );
       
   883         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iBssSize:             0x%08x", primaryImageHeader->iBssSize ) );
       
   884         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iHeapSizeMin:         0x%08x", primaryImageHeader->iHeapSizeMin ) );
       
   885         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iHeapSizeMax:         0x%08x", primaryImageHeader->iHeapSizeMax ) );
       
   886         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iStackSize:           0x%08x", primaryImageHeader->iStackSize ) );
       
   887 
       
   888         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - romHdr.iKernDataAddress: 0x%08x", romHdr.iKernDataAddress ) );
       
   889         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - Kern::RoundToPageSize( romHdr.iTotalSvDataSize ): 0x%08x", Kern::RoundToPageSize( romHdr.iTotalSvDataSize ) ) );
       
   890         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - Kern::RoundToPageSize( kernelProcessCreateInfo.iStackSize ): 0x%08x", Kern::RoundToPageSize( primaryImageHeader->iStackSize ) ) );
       
   891 
       
   892         TAny* stack = (TAny*)( romHdr.iKernDataAddress + Kern::RoundToPageSize( romHdr.iTotalSvDataSize ));
       
   893         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - aStack: 0x%08x", stack ) );
       
   894         
       
   895         // NB: This is supposed to be Kern::RoundToPageSize( kernelProcessCreateInfo.iStackSize ) but that
       
   896         // sometimes returns very dodgy values on ARMv5 Multiple Memory Model when using MemSpy's driver
       
   897         // installed via a SIS file. No idea why. Cache problem? 
       
   898         TAny* heap = (TAny*)(TLinAddr( stack ) + Kern::RoundToPageSize( primaryImageHeader->iStackSize ));
       
   899         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - aHeap: 0x%08x", heap ) );
       
   900 
       
   901         kernelHeap = (RHeapK*) heap;
       
   902 #else
       
   903         kernelHeap = (RHeapK*) kernelHeapChunk->Base();
       
   904 #endif
       
   905         // Finalise construction of heap 
       
   906         if  ( kernelHeap != NULL )
       
   907             {
       
   908             TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - kernelHeap->Base(): 0x%08x, kernelHeapChunk->Base(): 0x%08x", kernelHeap->Base(), kernelHeapChunk->Base() ) );
       
   909             aHeap = kernelHeap;
       
   910             aChunk = kernelHeapChunk;
       
   911 
       
   912             // Get the chunk name (if the caller asked for it)
       
   913             if  ( aClientHeapChunkName )
       
   914                 {
       
   915                 kernelHeapChunk->FullName( *aClientHeapChunkName );
       
   916                 }
       
   917 
       
   918             // Opened okay
       
   919             r = KErrNone;
       
   920             }
       
   921         else
       
   922             {
       
   923             TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap - kernel heap was NULL..."));
       
   924             }
       
   925         }
       
   926     else
       
   927         {
       
   928         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap - couldnt find kernel chunk..."));
       
   929         r = KErrNotFound;
       
   930         }
       
   931 
       
   932  	NKern::ThreadLeaveCS();
       
   933 
       
   934 	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap() - END - ret: %d", r ) );
       
   935     return r;
       
   936     }
       
   937 
       
   938 
       
   939 TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RMemSpyDriverRHeapKernelInPlace& aHeap, TDes8* aClientHeapChunkName )
       
   940     {
       
   941     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(IP) - START") );
       
   942 
       
   943     RHeapK* heap = NULL;
       
   944     DChunk* chunk = NULL;
       
   945     TInt r = OpenKernelHeap( heap, chunk, aClientHeapChunkName );
       
   946 	
       
   947     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(IP) - open err: %d", r ) );
       
   948     if  ( r == KErrNone )
       
   949         {
       
   950         aHeap.SetKernelHeap( *heap );
       
   951         aHeap.AssociateWithKernelChunk( chunk, TLinAddr( chunk->iBase ), 0 );
       
   952         }
       
   953 
       
   954 	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(IP) - END - ret: %d", r ) );
       
   955     return r;
       
   956     }
       
   957 
       
   958 
       
   959 TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RMemSpyDriverRHeapKernelFromCopy& aHeap, TDes8* aClientHeapChunkName )
       
   960     {
       
   961     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - START") );
       
   962 
       
   963     RHeapK* heap = NULL;
       
   964     DChunk* chunk = NULL;
       
   965     TInt r = OpenKernelHeap( heap, chunk, aClientHeapChunkName );
       
   966 	
       
   967     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - open err: %d", r ) );
       
   968     if  ( r == KErrNone )
       
   969         {
       
   970         const TInt heapSize = heap->Size();
       
   971         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - heapSize: %d, heap: 0x%08x, chunkBase: 0x%08x", heapSize, heap, chunk->Base() ) );
       
   972 
       
   973         // Make a new chunk that we can copy the kernel heap into. We cannot lock the system the entire time
       
   974         // we need to do this, therefore there is no guarantee that the chunk will be large enough to hold the
       
   975         // (current) heap data at the time we need to make the copy. We oversize the chunk by 1mb in the "hope"
       
   976         // that it will be enough... :(
       
   977         TChunkCreateInfo info;
       
   978         info.iType         = TChunkCreateInfo::ESharedKernelSingle;
       
   979         info.iMaxSize      = heapSize + ( 1024 * 1024 );
       
   980         info.iOwnsMemory   = ETrue; // Use memory from system's free pool
       
   981         info.iDestroyedDfc = NULL;
       
   982         #ifdef __EPOC32__
       
   983         info.iMapAttr      = (TInt)EMapAttrFullyBlocking; // Full caching
       
   984         #endif
       
   985 
       
   986         // Holds a copy of the client's heap chunk
       
   987         DChunk* heapCopyChunk;
       
   988         TLinAddr heapCopyChunkAddress;
       
   989         TUint32 heapCopyChunkMappingAttributes;
       
   990         r = Kern::ChunkCreate( info, heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes );
       
   991         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - creating chunk returned: %d", r));
       
   992 
       
   993         if  ( r == KErrNone )
       
   994             {
       
   995             TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - copy chunk base: 0x%08x, heapCopyChunkAddress: 0x%08x", heapCopyChunk->iBase, heapCopyChunkAddress));
       
   996 
       
   997             // Commit memory for entire buffer
       
   998             TUint32 physicalAddress = 0;
       
   999             r = Kern::ChunkCommitContiguous( heapCopyChunk, 0, heapSize, physicalAddress );
       
  1000             TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - commiting chunk returned: %d", r));
       
  1001 
       
  1002             if  ( r != KErrNone)
       
  1003                 {
       
  1004                 // On error, throw away the chunk we have created
       
  1005                 Kern::ChunkClose( heapCopyChunk );
       
  1006                 heapCopyChunk = NULL;
       
  1007                 }
       
  1008             else
       
  1009                 {
       
  1010                 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - heapCopyChunk->iSize: 0x%08x, heapCopyChunk->iBase: 0x%08x, heapCopyChunkAddress: 0x%08x, physicalAddress: 0x%08x", heapCopyChunk->iSize, heapCopyChunk->iBase, heapCopyChunkAddress, physicalAddress));
       
  1011 
       
  1012                 NKern::LockSystem();
       
  1013                 const TUint32 copyLength = Min( heap->Size(), heapSize );
       
  1014 
       
  1015                 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - trying to copy %d (vs orig estimate of %d) bytes from kernel allocator address: 0x%08x", copyLength, heapSize, heap->Base() ));
       
  1016                 memcpy( (TUint8*) heapCopyChunkAddress, heap, copyLength );
       
  1017 
       
  1018                 NKern::UnlockSystem();
       
  1019 
       
  1020                 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - copied kernel heap data" ));
       
  1021 
       
  1022                 // Transfer ownership of the copy heap chunk to the heap object. This also calculates the delta
       
  1023                 // beween the heap addresses in the client's address space and the kernel address space.
       
  1024                 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - associate chunk and transfer ownership..." ));
       
  1025                 aHeap.SetKernelHeap( *heap );
       
  1026                 aHeap.AssociateWithKernelChunk( heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes );
       
  1027                 }
       
  1028             }
       
  1029         else
       
  1030             {
       
  1031 	        TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - copy chunk create error: %d", r ) );
       
  1032             }
       
  1033         }
       
  1034 
       
  1035 	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - END - ret: %d", r ) );
       
  1036     return r;
       
  1037     }
       
  1038 
       
  1039 
       
  1040