perfsrv/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapBase.cpp
changeset 48 516af714ebb4
child 52 c2f44e33b468
equal deleted inserted replaced
45:185201be11b0 48:516af714ebb4
       
     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 	}
       
    51 
       
    52 
       
    53 TInt DMemSpyDriverLogChanHeapBase::Construct()
       
    54 	{
       
    55 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::Construct() - START - this: 0x%08x", this ));
       
    56     
       
    57     const TInt ret = BaseConstruct( KMemSpyDriverLogChanHeapBaseXferBufferSize );
       
    58 
       
    59 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::Construct() - END - this: 0x%08x, err: %d", this, ret ));
       
    60     return ret;
       
    61 	}
       
    62 
       
    63 
       
    64 
       
    65 
       
    66 
       
    67 
       
    68 
       
    69 
       
    70 
       
    71 
       
    72 
       
    73 TInt DMemSpyDriverLogChanHeapBase::Request( TInt aFunction, TAny* a1, TAny* a2 )
       
    74 	{
       
    75 	const TInt r = DMemSpyDriverLogChanBase::Request( aFunction, a1, a2 );
       
    76     return r;
       
    77 	}
       
    78 
       
    79 
       
    80 
       
    81 
       
    82 
       
    83 
       
    84 
       
    85 
       
    86 
       
    87 
       
    88 
       
    89 
       
    90 
       
    91 DMemSpyDriverLogChanHeapBase::TDrmMatchType DMemSpyDriverLogChanHeapBase::IsDrmThread( DThread& aThread )
       
    92     {
       
    93     TDrmMatchType ret = EMatchTypeNone;
       
    94     //
       
    95     const TUid procUid = aThread.iOwningProcess->iUids.iUid[ 2 ];
       
    96     TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::IsDrmThread() - START - aThread: %O, process uid: 0x%08x", &aThread, procUid.iUid ));
       
    97 
       
    98     // Some more rudimentary checks based upon process name and
       
    99     // known uids.
       
   100     TFullName fullName;
       
   101     aThread.FullName( fullName );
       
   102 
       
   103     // Exclude threads containing "DRM"
       
   104     _LIT( KDrmThreadMatchText, "*DRM*" );
       
   105     const TInt matchPos = fullName.MatchF( KDrmThreadMatchText );
       
   106     if ( matchPos >= 0 )
       
   107         {
       
   108         TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::IsDrmThread() - found \'DRM\' at pos: %d (%S)", matchPos, &fullName ));
       
   109         ret = EMatchTypeName;
       
   110         }
       
   111     else
       
   112         {
       
   113         // Some known DRM related process UIDs
       
   114         switch( procUid.iUid )
       
   115             {
       
   116         case 0x10005A22: // DRMEncryptor.exe
       
   117         case 0x01105901: // DRMEncryptor.exe
       
   118         case 0x101F85C7: // DRMRightsManager.exe
       
   119         case 0x10205CA8: // DcfRepSrv.exe
       
   120         case 0x101F51F2: // RightsServer.exe
       
   121         case 0x101F6DC5: // DRMHelperServer.exe
       
   122         case 0x10282F1B: // wmdrmserver.exe
       
   123             ret = EMatchTypeUid;
       
   124             break;
       
   125         default:
       
   126             ret = EMatchTypeNone;
       
   127             break;
       
   128             }
       
   129         }
       
   130 
       
   131     TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::IsDrmThread() - END - procUid: 0x%08x, matchType: %d", procUid.iUid, ret ));
       
   132     return ret;
       
   133     }
       
   134 
       
   135 
       
   136 
       
   137 
       
   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 void DMemSpyDriverLogChanHeapBase::PrintHeapInfo( const TMemSpyHeapInfo& aInfo )
       
   172     {
       
   173     const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
       
   174     //const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData();
       
   175     const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics();
       
   176     const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
       
   177 
       
   178     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   179     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Free)                                    -" ) );
       
   180     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   181     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell count:                     %d", rHeapStats.StatsFree().TypeCount() ) );
       
   182     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell size:                      %d", rHeapStats.StatsFree().TypeSize() ) );
       
   183     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest:                   0x%08x", rHeapStats.StatsFree().LargestCellAddress() ) );
       
   184     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest size:              %d", rHeapStats.StatsFree().LargestCellSize() ) );
       
   185     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - slack:                          0x%08x", rHeapStats.StatsFree().SlackSpaceCellAddress() ) );
       
   186     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - slack size:                     %d", rHeapStats.StatsFree().SlackSpaceCellSize() ) );
       
   187     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - checksum:                       0x%08x", rHeapStats.StatsFree().Checksum() ) );
       
   188     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) );
       
   189 
       
   190     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   191     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Alloc)                                   -" ) );
       
   192     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   193     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell count:                     %d", rHeapStats.StatsAllocated().TypeCount() ) );
       
   194     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell size:                      %d", rHeapStats.StatsAllocated().TypeSize() ) );
       
   195     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest:                   0x%08x", rHeapStats.StatsAllocated().LargestCellAddress() ) );
       
   196     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest size:              %d", rHeapStats.StatsAllocated().LargestCellSize() ) );
       
   197     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) );
       
   198 
       
   199     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   200     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Misc. Info                                      -" ) );
       
   201     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
       
   202     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk size:                     %d", rHeapMetaData.ChunkSize() ) );
       
   203     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk handle:                   0x%08x", rHeapMetaData.ChunkHandle() ) );
       
   204     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk base address:             0x%08x", rHeapMetaData.ChunkBaseAddress() ) );
       
   205     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - debug allocator:                %d", rHeapMetaData.IsDebugAllocator() ) );
       
   206     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - shared heap:                    %d", rHeapMetaData.IsSharedHeap() ) );
       
   207     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - user thread:                    %d", rHeapMetaData.IsUserThread() ) );
       
   208     //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (free):        %d", rHeapMetaData.HeaderSizeFree() ) );
       
   209     //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (alloc):       %d", rHeapMetaData.HeaderSizeAllocated() ) );
       
   210     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap vTable:                    0x%08x", rHeapMetaData.VTable() ) );
       
   211     //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap object size:               %d", rHeapMetaData.ClassSize() ) );
       
   212     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap size:                      %d", rHeapMetaData.iHeapSize ) );
       
   213     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - allocator address:              0x%08x", rHeapMetaData.iAllocatorAddress ) );
       
   214     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - min heap size:                  %d", rHeapMetaData.iMinHeapSize ) );
       
   215     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - max heap size:                  %d", rHeapMetaData.iMaxHeapSize ) );
       
   216     }
       
   217 
       
   218 TInt DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel(RMemSpyDriverRHeapBase& aHeap, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer )
       
   219     {
       
   220     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel() - START - aTransferBuffer: 0x%08x", aTransferBuffer ) );
       
   221 
       
   222     TInt r = KErrNone;
       
   223     NKern::ThreadEnterCS();
       
   224 
       
   225     // This object holds all of the info we will accumulate for the client.
       
   226     TMemSpyHeapInfo masterHeapInfo;
       
   227     masterHeapInfo.SetType(aHeap.GetTypeFromHelper());
       
   228     masterHeapInfo.SetTid( 2 );
       
   229     masterHeapInfo.SetPid( 1 );
       
   230 
       
   231     // This is the RHeap-specific object that contains all RHeap info
       
   232     TMemSpyHeapInfoRHeap& rHeapInfo = masterHeapInfo.AsRHeap();
       
   233 
       
   234 
       
   235     // When walking the kernel heap we must keep track of the free cells
       
   236     // without allocating any more memory (on the kernel heap...)
       
   237     //
       
   238     // Therefore, we start a stream immediately, which is actually already
       
   239     // pre-allocated.
       
   240     //
       
   241     // Start stream and pad with zero count, which we'll repopulate later on
       
   242     // once we know the final score.
       
   243     RMemSpyMemStreamWriter stream;
       
   244     TInt32* pCount = NULL;
       
   245 
       
   246     // We must walk the client's heap in order to build statistics
       
   247     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - calling heap walker constructor..."));
       
   248     RMemSpyDriverHeapWalker heapWalker(aHeap);
       
   249     if  ( aTransferBuffer )
       
   250         {
       
   251         // This will allow us to identify that we're writing directly to the stream
       
   252         stream = OpenXferStream();
       
   253         iStackStream = &stream;
       
   254 
       
   255         // Writer marker value which we'll update after the traversal completes
       
   256         pCount = stream.WriteInt32( 0 );
       
   257 
       
   258         // Receive cell info as we walk the heap...
       
   259         heapWalker.SetObserver( this );
       
   260         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - collecting free cells - iStackStream: 0x%08x, isOpen: %d, pCount: 0x%08x", iStackStream, stream.IsOpen(), pCount ));
       
   261         }
       
   262     else
       
   263         {
       
   264         iStackStream = NULL;
       
   265         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - not collecting free cells"));
       
   266         }
       
   267 
       
   268     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - starting traversal..." ));
       
   269 
       
   270 #if defined( TRACE_TYPE_KERNELHEAP )
       
   271     heapWalker.SetPrintDebug();
       
   272 #endif
       
   273     r = heapWalker.Traverse();
       
   274 
       
   275     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - finished traversal - err: %d, iStackStream: 0x%08x, pCount: 0x%08x, isOpen: %d", 
       
   276                             r, iStackStream, pCount, ( iStackStream == NULL ? 0 : iStackStream->IsOpen() ) ));
       
   277 
       
   278     // Write free cells if requested
       
   279     if  ( r == KErrNone && iStackStream && iStackStream->IsOpen() && pCount )
       
   280         {
       
   281         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - final free cell count: %d", iFreeCellCount ));
       
   282         *pCount = iFreeCellCount;
       
   283         r = stream.WriteAndClose( aTransferBuffer );
       
   284         iStackStream = NULL;
       
   285         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - stream commit result: %d", r ));
       
   286         }
       
   287 
       
   288     TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics();
       
   289     heapWalker.CopyStatsTo( rHeapStats );
       
   290 
       
   291     // Get remaining meta data that isn't stored elsewhere
       
   292     TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
       
   293 	TFullName chunkName;
       
   294 	aHeap.Chunk().FullName(chunkName);
       
   295     rHeapMetaData.SetChunkName(chunkName);
       
   296     rHeapMetaData.SetChunkSize( (TUint) aHeap.Chunk().Size() );
       
   297     rHeapMetaData.SetChunkHandle( &aHeap.Chunk() );
       
   298     rHeapMetaData.SetChunkBaseAddress( OSAdaption().DChunk().GetBase(aHeap.Chunk()) );
       
   299     rHeapMetaData.SetDebugAllocator(aHeap.Helper()->AllocatorIsUdeb());
       
   300     rHeapMetaData.SetUserThread( EFalse );
       
   301     rHeapMetaData.SetSharedHeap( ETrue );
       
   302 	rHeapMetaData.iHeapSize = aHeap.Helper()->CommittedSize();
       
   303 	rHeapMetaData.iAllocatorAddress = (TAny*)aHeap.Helper()->AllocatorAddress();
       
   304 	rHeapMetaData.iMinHeapSize = aHeap.Helper()->MinCommittedSize();
       
   305 	rHeapMetaData.iMaxHeapSize = aHeap.Helper()->MaxCommittedSize();
       
   306 
       
   307     PrintHeapInfo( masterHeapInfo );
       
   308 
       
   309     // Update info ready for writing back to the user-side
       
   310     if  ( r == KErrNone )
       
   311         {
       
   312         // Write results back to user-side
       
   313         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - writing to user-side..."));
       
   314         r = Kern::ThreadRawWrite( &ClientThread(), aHeapInfo, &masterHeapInfo, sizeof( TMemSpyHeapInfo ) );
       
   315         }
       
   316 
       
   317     NKern::ThreadLeaveCS();
       
   318 
       
   319 	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel() - END - ret: %d", r) );
       
   320     return r;
       
   321     }
       
   322 
       
   323 
       
   324 
       
   325 
       
   326 
       
   327 
       
   328 
       
   329 
       
   330 
       
   331 
       
   332     
       
   333 
       
   334 
       
   335 
       
   336 
       
   337 
       
   338 
       
   339 TBool DMemSpyDriverLogChanHeapBase::HandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt /*aNestingLevel*/, TInt /*aAllocNumber*/)
       
   340     {
       
   341     TInt error = KErrNone;
       
   342     //
       
   343     if  (aCellType & EMemSpyDriverFreeCellMask)
       
   344         {
       
   345         if  ( iStackStream )
       
   346             {
       
   347             if  ( !iStackStream->IsFull() )
       
   348                 {
       
   349                 ++iFreeCellCount;
       
   350                 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::HandleHeapCell - writing free cell %d @ 0x%08x, space left: %u", iFreeCellCount, aCellAddress, iStackStream->Remaining() ));
       
   351                 //
       
   352                 iStackStream->WriteInt32( aCellType );
       
   353                 iStackStream->WriteUint32( reinterpret_cast<TUint32>( aCellAddress ) );
       
   354                 iStackStream->WriteInt32( aLength );
       
   355                 }
       
   356             else
       
   357                 {
       
   358                 Kern::Printf( "DMemSpyDriverLogChanHeapBase::HandleHeapCell - Kernel Free Cell stack stream IS FULL!" );
       
   359                 error = KErrAbort;
       
   360                 }
       
   361             }
       
   362        }
       
   363     //
       
   364     return ( error == KErrNone );
       
   365     }
       
   366 
       
   367 
       
   368 void DMemSpyDriverLogChanHeapBase::HandleHeapWalkInit()
       
   369 	{
       
   370 	iFreeCellCount = 0;
       
   371 	}
       
   372 
       
   373 TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RHeapK*& aHeap, DChunk*& aChunk, TDes8* aClientHeapChunkName )
       
   374     {
       
   375     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap() - START") );
       
   376 
       
   377     // This is what we're searching for...
       
   378     RHeapK* kernelHeap = NULL;
       
   379     DChunk* kernelHeapChunk = NULL;
       
   380 
       
   381     // Find the SvHeap chunk....
       
   382     _LIT( KKernelServerHeapChunkName, "SvHeap" );
       
   383  	NKern::ThreadEnterCS();
       
   384    
       
   385     DObjectCon* chunkContainer = Kern::Containers()[EChunk];
       
   386     chunkContainer->Wait();
       
   387     NKern::LockSystem();
       
   388     const TInt chunkCount = chunkContainer->Count();
       
   389 
       
   390     for(TInt i=0; i<chunkCount; i++)
       
   391         {
       
   392         DChunk* chunk = (DChunk*) (*chunkContainer)[ i ];
       
   393         //
       
   394         if  ( chunk->NameBuf() )
       
   395             {
       
   396             const TInt findResult = chunk->NameBuf()->Find( KKernelServerHeapChunkName );
       
   397     	    TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap - checking chunk: %O against %S => %d", chunk, &KKernelServerHeapChunkName, findResult ) );
       
   398             if  ( findResult != KErrNotFound )
       
   399                 {
       
   400                 // Found it.
       
   401                 kernelHeapChunk = chunk;
       
   402                 TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - found chunk with base: 0x%08x", chunk->iBase ) );
       
   403                 break;
       
   404                 }
       
   405             }
       
   406         }
       
   407 
       
   408     NKern::UnlockSystem();
       
   409     chunkContainer->Signal();
       
   410 
       
   411     TInt r = KErrNotFound;
       
   412     if  ( kernelHeapChunk != NULL )
       
   413         {
       
   414 #ifndef __WINS__
       
   415         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - kernelHeapChunk: 0x%08x", kernelHeapChunk ) );
       
   416 
       
   417         const TRomHeader& romHdr = Epoc::RomHeader();
       
   418 	    const TRomEntry* primaryEntry = (const TRomEntry*) Kern::SuperPage().iPrimaryEntry;
       
   419         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - primaryEntry: 0x%08x, primaryEntry->iAddressLin: 0x%08x", primaryEntry, primaryEntry->iAddressLin ) );
       
   420 	    const TRomImageHeader* primaryImageHeader = (const TRomImageHeader*) primaryEntry->iAddressLin;
       
   421         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - primaryEntry: 0x%08x", primaryImageHeader ) );
       
   422 
       
   423         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iCodeSize:            0x%08x", primaryImageHeader->iCodeSize ) );
       
   424         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iTextSize:            0x%08x", primaryImageHeader->iTextSize ) );
       
   425         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iDataSize:            0x%08x", primaryImageHeader->iDataSize ) );
       
   426         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iBssSize:             0x%08x", primaryImageHeader->iBssSize ) );
       
   427         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iHeapSizeMin:         0x%08x", primaryImageHeader->iHeapSizeMin ) );
       
   428         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iHeapSizeMax:         0x%08x", primaryImageHeader->iHeapSizeMax ) );
       
   429         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - TRomImageHeader::iStackSize:           0x%08x", primaryImageHeader->iStackSize ) );
       
   430 
       
   431         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - romHdr.iKernDataAddress: 0x%08x", romHdr.iKernDataAddress ) );
       
   432         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - Kern::RoundToPageSize( romHdr.iTotalSvDataSize ): 0x%08x", Kern::RoundToPageSize( romHdr.iTotalSvDataSize ) ) );
       
   433         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - Kern::RoundToPageSize( kernelProcessCreateInfo.iStackSize ): 0x%08x", Kern::RoundToPageSize( primaryImageHeader->iStackSize ) ) );
       
   434 
       
   435         TAny* stack = (TAny*)( romHdr.iKernDataAddress + Kern::RoundToPageSize( romHdr.iTotalSvDataSize ));
       
   436         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - aStack: 0x%08x", stack ) );
       
   437         
       
   438         // NB: This is supposed to be Kern::RoundToPageSize( kernelProcessCreateInfo.iStackSize ) but that
       
   439         // sometimes returns very dodgy values on ARMv5 Multiple Memory Model when using MemSpy's driver
       
   440         // installed via a SIS file. No idea why. Cache problem? 
       
   441         TAny* heap = (TAny*)(TLinAddr( stack ) + Kern::RoundToPageSize( primaryImageHeader->iStackSize ));
       
   442         TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - aHeap: 0x%08x", heap ) );
       
   443 
       
   444         kernelHeap = (RHeapK*) heap;
       
   445 #else
       
   446         kernelHeap = (RHeapK*) kernelHeapChunk->Base();
       
   447 #endif
       
   448         // Finalise construction of heap 
       
   449         if  ( kernelHeap != NULL )
       
   450             {
       
   451             TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - kernelHeapChunk->Base(): 0x%08x", kernelHeapChunk->Base() ) );
       
   452             aHeap = kernelHeap;
       
   453             aChunk = kernelHeapChunk;
       
   454 
       
   455             // Get the chunk name (if the caller asked for it)
       
   456             if  ( aClientHeapChunkName )
       
   457                 {
       
   458                 kernelHeapChunk->FullName( *aClientHeapChunkName );
       
   459                 }
       
   460 
       
   461             // Opened okay
       
   462             r = KErrNone;
       
   463             }
       
   464         else
       
   465             {
       
   466             TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap - kernel heap was NULL..."));
       
   467             }
       
   468         }
       
   469     else
       
   470         {
       
   471         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap - couldnt find kernel chunk..."));
       
   472         r = KErrNotFound;
       
   473         }
       
   474 
       
   475  	NKern::ThreadLeaveCS();
       
   476 
       
   477 	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap() - END - ret: %d", r ) );
       
   478     return r;
       
   479     }
       
   480 
       
   481 TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RMemSpyDriverRHeapKernelFromCopy& aHeap, TDes8* aClientHeapChunkName )
       
   482     {
       
   483     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - START") );
       
   484 
       
   485     RHeapK* heap = NULL;
       
   486     DChunk* chunk = NULL;
       
   487     TInt r = OpenKernelHeap( heap, chunk, aClientHeapChunkName );
       
   488 	
       
   489     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - open err: %d", r ) );
       
   490     if  ( r == KErrNone )
       
   491         {
       
   492 #ifdef __SYMBIAN_KERNEL_HYBRID_HEAP__
       
   493 		// RAllocator::Size() not exported on hybrid heap
       
   494 		const TInt heapSize = heap->DebugFunction(RAllocator::EGetSize);
       
   495 #else
       
   496         const TInt heapSize = heap->Size();
       
   497 #endif
       
   498         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - heapSize: %d, heap: 0x%08x, chunkBase: 0x%08x", heapSize, heap, chunk->Base() ) );
       
   499 
       
   500         // Make a new chunk that we can copy the kernel heap into. We cannot lock the system the entire time
       
   501         // we need to do this, therefore there is no guarantee that the chunk will be large enough to hold the
       
   502         // (current) heap data at the time we need to make the copy. We oversize the chunk by 1mb in the "hope"
       
   503         // that it will be enough... :(
       
   504         TChunkCreateInfo info;
       
   505         info.iType         = TChunkCreateInfo::ESharedKernelSingle;
       
   506         info.iMaxSize      = heapSize + ( 1024 * 1024 );
       
   507         info.iOwnsMemory   = ETrue; // Use memory from system's free pool
       
   508         info.iDestroyedDfc = NULL;
       
   509         #ifdef __EPOC32__
       
   510         info.iMapAttr      = (TInt)EMapAttrFullyBlocking; // Full caching
       
   511         #endif
       
   512 
       
   513         // Holds a copy of the client's heap chunk
       
   514         DChunk* heapCopyChunk;
       
   515         TLinAddr heapCopyChunkAddress;
       
   516         TUint32 heapCopyChunkMappingAttributes;
       
   517         r = Kern::ChunkCreate( info, heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes );
       
   518         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - creating chunk returned: %d", r));
       
   519 
       
   520         if  ( r == KErrNone )
       
   521             {
       
   522             TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - copy chunk base: 0x%08x, heapCopyChunkAddress: 0x%08x", heapCopyChunk->iBase, heapCopyChunkAddress));
       
   523 
       
   524             // Commit memory for entire buffer
       
   525             TUint32 physicalAddress = 0;
       
   526             r = Kern::ChunkCommitContiguous( heapCopyChunk, 0, heapSize, physicalAddress );
       
   527             TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - commiting chunk returned: %d", r));
       
   528 
       
   529             if  ( r != KErrNone)
       
   530                 {
       
   531                 // On error, throw away the chunk we have created
       
   532                 Kern::ChunkClose( heapCopyChunk );
       
   533                 heapCopyChunk = NULL;
       
   534                 }
       
   535             else
       
   536                 {
       
   537                 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));
       
   538 
       
   539                 NKern::LockSystem();
       
   540                 const TUint32 copyLength = heapSize; // TODO Min( heap->Size(), heapSize );
       
   541 
       
   542                 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));
       
   543                 memcpy( (TUint8*) heapCopyChunkAddress, heap, copyLength );
       
   544 
       
   545                 NKern::UnlockSystem();
       
   546 
       
   547                 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - copied kernel heap data" ));
       
   548 
       
   549                 // Transfer ownership of the copy heap chunk to the heap object. This also calculates the delta
       
   550                 // beween the heap addresses in the client's address space and the kernel address space.
       
   551                 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - associate chunk and transfer ownership..." ));
       
   552                 aHeap.SetKernelHeap( *heap );
       
   553                 aHeap.AssociateWithKernelChunk( heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes );
       
   554                 }
       
   555             }
       
   556         else
       
   557             {
       
   558 	        TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - copy chunk create error: %d", r ) );
       
   559             }
       
   560         }
       
   561 
       
   562 	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - END - ret: %d", r ) );
       
   563     return r;
       
   564     }
       
   565 
       
   566 
       
   567