perfsrv/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapDataKernel.cpp
changeset 55 f2950aff7424
equal deleted inserted replaced
48:516af714ebb4 55:f2950aff7424
       
     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 "MemSpyDriverLogChanHeapDataKernel.h"
       
    19 
       
    20 // System includes
       
    21 #include <u32hal.h>
       
    22 #include <e32rom.h>
       
    23 #include <memspy/driver/memspydriverconstants.h>
       
    24 #include <memspy/driver/memspydriverobjectsshared.h>
       
    25 
       
    26 // Shared includes
       
    27 #include "MemSpyDriverOpCodes.h"
       
    28 #include "MemSpyDriverObjectsInternal.h"
       
    29 
       
    30 // User includes
       
    31 #include "MemSpyDriverHeap.h"
       
    32 #include "MemSpyDriverUtils.h"
       
    33 #include "MemSpyDriverDevice.h"
       
    34 #include "MemSpyDriverOSAdaption.h"
       
    35 #include "MemSpyDriverHeapWalker.h"
       
    36 #include "MemSpyDriverUserEventMonitor.h"
       
    37 #include "MemSpyDriverSuspensionManager.h"
       
    38 
       
    39 DMemSpyDriverLogChanHeapDataKernel::DMemSpyDriverLogChanHeapDataKernel( DMemSpyDriverDevice& aDevice, DThread& aThread )
       
    40 :   DMemSpyDriverLogChanHeapDataBase( aDevice, aThread ), iKernelHeap( aDevice.OSAdaption() )
       
    41     {
       
    42     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::DMemSpyDriverLogChanHeapDataKernel() - this: 0x%08x", this ));
       
    43     }
       
    44 
       
    45 TInt DMemSpyDriverLogChanHeapDataKernel::Request( TInt aFunction, TAny* a1, TAny* a2 )
       
    46 	{
       
    47 	TInt r = DMemSpyDriverLogChanHeapBase::Request( aFunction, a1, a2 );
       
    48     if  ( r == KErrNone )
       
    49         {
       
    50         if  ( aFunction != EMemSpyDriverOpCodeHeapKernelDataFetchCellList )
       
    51             {
       
    52             ReleaseCellList();
       
    53             }
       
    54         //
       
    55         switch( aFunction )
       
    56 		    {
       
    57 	    case EMemSpyDriverOpCodeHeapKernelDataGetInfo:
       
    58             r = GetInfoData( (TMemSpyDriverInternalHeapRequestParameters*) a1 );
       
    59             break;
       
    60         case EMemSpyDriverOpCodeHeapKernelDataGetIsDebugKernel:
       
    61             r = GetIsDebugKernel(a1);
       
    62             break;
       
    63         case EMemSpyDriverOpCodeHeapKernelDataFetchCellList:
       
    64             r = FetchCellList( (TDes8*) a1 );
       
    65             break;
       
    66         case EMemSpyDriverOpCodeHeapKernelDataCopyHeap:
       
    67             r = MakeKernelHeapCopy();
       
    68             break;
       
    69         case EMemSpyDriverOpCodeHeapKernelDataGetFull:
       
    70             r = DMemSpyDriverLogChanHeapDataBase::GetFullData( (TMemSpyDriverInternalHeapDataParams*) a1 );
       
    71             break;
       
    72         case EMemSpyDriverOpCodeHeapKernelDataFreeHeapCopy:
       
    73             FreeKernelHeapCopy();
       
    74             break;
       
    75 
       
    76         default:
       
    77             r = KErrNotSupported;
       
    78 		    break;
       
    79             }
       
    80         }
       
    81     //
       
    82     return r;
       
    83 	}
       
    84 
       
    85 
       
    86 TBool DMemSpyDriverLogChanHeapDataKernel::IsHandler( TInt aFunction ) const
       
    87     {
       
    88     return ( aFunction > EMemSpyDriverOpCodeHeapKernelDataBase && aFunction < EMemSpyDriverOpCodeHeapKernelDataEnd );
       
    89     }
       
    90 
       
    91 TInt DMemSpyDriverLogChanHeapDataKernel::GetInfoData( TMemSpyDriverInternalHeapRequestParameters* aParams )
       
    92     {
       
    93     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetInfoData() - START" ) );
       
    94 
       
    95     TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &iHeapInfoParams, sizeof(TMemSpyDriverInternalHeapRequestParameters) );
       
    96     if  ( r != KErrNone )
       
    97         {
       
    98     	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetInfoDataUser - params read error: %d", r));
       
    99         }
       
   100     else
       
   101         {
       
   102         if (iHeapInfoParams.iUseKernelHeapCopy)
       
   103             {
       
   104             __ASSERT_ALWAYS( iKernelHeap.IsOpen(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapKernelCopyExpected ) );
       
   105             r = DMemSpyDriverLogChanHeapDataKernel::GetInfoData(iKernelHeap);
       
   106             }
       
   107         else
       
   108             {
       
   109             RMemSpyDriverRHeapKernelInPlace rHeap(OSAdaption());
       
   110             r = rHeap.OpenKernelHeap();
       
   111             if  ( r == KErrNone )
       
   112                 {
       
   113                 r = DMemSpyDriverLogChanHeapDataKernel::GetInfoData(rHeap);
       
   114                 }
       
   115             else 
       
   116                 {
       
   117                 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetInfoData() - open err: %d", r ) );                
       
   118                 }
       
   119             }
       
   120         }
       
   121 
       
   122 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetInfoData() - END - ret: %d", r) );
       
   123     return r;
       
   124     }
       
   125 
       
   126 TInt DMemSpyDriverLogChanHeapDataKernel::GetInfoData(RMemSpyDriverRHeapBase& aHeap)
       
   127     {
       
   128     NKern::ThreadEnterCS();
       
   129 
       
   130     TInt r = KErrNone;
       
   131     
       
   132     // This object holds all of the info we will accumulate for the client.
       
   133     TMemSpyHeapInfo masterHeapInfo;
       
   134     masterHeapInfo.SetType(aHeap.GetTypeFromHelper());
       
   135     masterHeapInfo.SetTid( 2 );
       
   136     masterHeapInfo.SetPid( 1 );
       
   137 
       
   138     // This is the RHeap-specific object that contains all RHeap info
       
   139     TMemSpyHeapInfoRHeap& rHeapInfo = masterHeapInfo.AsRHeap();
       
   140 
       
   141     // We must walk the heap in order to build statistics
       
   142     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetInfoData - calling heap walker constructor..."));
       
   143     RMemSpyDriverHeapWalker heapWalker(aHeap);
       
   144     if  (iHeapInfoParams.iBuildFreeCellList || iHeapInfoParams.iBuildAllocCellList)
       
   145         {
       
   146         heapWalker.SetObserver( this );
       
   147         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetInfoData - collecting cells"));
       
   148         }
       
   149     else
       
   150         {
       
   151         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetInfoData - not collecting cells"));
       
   152         }
       
   153 
       
   154     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetInfoData - starting traversal..." ));
       
   155 
       
   156 #if defined( TRACE_TYPE_KERNELHEAP )
       
   157     heapWalker.SetPrintDebug();
       
   158 #endif
       
   159     if (r == KErrNone) r = heapWalker.Traverse();
       
   160     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetInfoData - finished traversal - err: %d", r ));
       
   161 
       
   162     TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics();
       
   163     heapWalker.CopyStatsTo( rHeapStats );
       
   164 
       
   165     // Get remaining meta data that isn't stored elsewhere
       
   166     TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
       
   167     TFullName chunkName;
       
   168     aHeap.Chunk().FullName(chunkName);
       
   169     rHeapMetaData.SetChunkName(chunkName);
       
   170     rHeapMetaData.SetChunkSize( (TUint) aHeap.Chunk().Size() );
       
   171     rHeapMetaData.SetChunkHandle( &aHeap.Chunk() );
       
   172     rHeapMetaData.SetChunkBaseAddress( OSAdaption().DChunk().GetBase(aHeap.Chunk()) );
       
   173     rHeapMetaData.SetDebugAllocator(aHeap.Helper()->AllocatorIsUdeb());
       
   174     rHeapMetaData.SetUserThread( EFalse );
       
   175     rHeapMetaData.SetSharedHeap( ETrue );
       
   176     rHeapMetaData.iHeapSize = aHeap.Helper()->CommittedSize();
       
   177     rHeapMetaData.iAllocatorAddress = (TAny*)aHeap.Helper()->AllocatorAddress();
       
   178     rHeapMetaData.iMinHeapSize = aHeap.Helper()->MinCommittedSize();
       
   179     rHeapMetaData.iMaxHeapSize = aHeap.Helper()->MaxCommittedSize();
       
   180 
       
   181     PrintHeapInfo( masterHeapInfo );
       
   182 
       
   183     // Write free cells if requested
       
   184     if  ( r == KErrNone && (iHeapInfoParams.iBuildFreeCellList || iHeapInfoParams.iBuildAllocCellList))
       
   185     	{
       
   186         r = PrepareCellListTransferBuffer();
       
   187         }
       
   188 
       
   189     if  ( r >= KErrNone )
       
   190     	{
       
   191         // Write results back to user-side
       
   192         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetInfoData - writing to user-side..."));
       
   193         TMemSpyHeapInfo* kernelMasterInfo = iHeapInfoParams.iMasterInfo;
       
   194         const TInt error = Kern::ThreadRawWrite( &ClientThread(), kernelMasterInfo, &masterHeapInfo, sizeof(TMemSpyHeapInfo) );
       
   195         if  ( error < 0 )
       
   196         	{
       
   197             r = error;
       
   198         	}
       
   199         }
       
   200 
       
   201     NKern::ThreadLeaveCS();
       
   202     
       
   203     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetInfoData() - END - ret: %d", r) );
       
   204     return r;
       
   205     }
       
   206 
       
   207 TInt DMemSpyDriverLogChanHeapDataKernel::GetIsDebugKernel(TAny* aResult)
       
   208     {
       
   209     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetIsDebugKernel() - START") );
       
   210     
       
   211     TInt r = KErrNone;
       
   212     TBool debugKernel = EFalse;
       
   213 
       
   214     NKern::ThreadEnterCS();
       
   215     
       
   216     RMemSpyDriverRHeapKernelInPlace rHeap(OSAdaption());
       
   217     r = rHeap.OpenKernelHeap();
       
   218     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetIsDebugKernel() - open kernel heap returned: %d", r) );
       
   219 
       
   220     if  ( r == KErrNone )
       
   221         {
       
   222         debugKernel = rHeap.Helper()->AllocatorIsUdeb();
       
   223 
       
   224         // Tidy up
       
   225         rHeap.Close();
       
   226         }
       
   227 
       
   228     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetIsDebugKernel() - debugKernel: %d", debugKernel) );
       
   229 
       
   230     // Write back to user-land
       
   231     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetIsDebugKernel() - writing to user-side...") );
       
   232     r = Kern::ThreadRawWrite( &ClientThread(), aResult, &debugKernel, sizeof(TBool) );
       
   233 
       
   234     NKern::ThreadLeaveCS();
       
   235 
       
   236  	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetIsDebugKernel() - END - ret: %d", r) );
       
   237     return r;
       
   238     }
       
   239 
       
   240 TInt DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap( RMemSpyDriverRHeapKernelFromCopy& aHeap )
       
   241     {
       
   242     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap(CP) - START") );
       
   243 
       
   244     RAllocatorHelper kernelHeapHelper;
       
   245     TInt r = kernelHeapHelper.OpenKernelHeap();
       
   246     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap(CP) - open err: %d", r ) );
       
   247     if  ( r == KErrNone )
       
   248         {
       
   249         DChunk* kernelChunk = kernelHeapHelper.OpenUnderlyingChunk();
       
   250         if (kernelChunk) {
       
   251             // TODO can we lock just the kernel heap here to avoid the problem below?
       
   252             
       
   253             // Make a new chunk that we can copy the kernel heap into. We cannot lock the system the entire time
       
   254             // we need to do this, therefore there is no guarantee that the chunk will be large enough to hold the
       
   255             // (current) heap data at the time we need to make the copy. We oversize the chunk by 1mb in the "hope"
       
   256             // that it will be enough... :(
       
   257             TChunkCreateInfo info;
       
   258             info.iType         = TChunkCreateInfo::ESharedKernelSingle;
       
   259             info.iMaxSize      = kernelChunk->MaxSize() + ( 1024 * 1024 );
       
   260             info.iOwnsMemory   = ETrue; // Use memory from system's free pool
       
   261             info.iDestroyedDfc = NULL;
       
   262             #ifdef __EPOC32__
       
   263             info.iMapAttr      = (TInt)EMapAttrFullyBlocking; // Full caching
       
   264             #endif
       
   265             
       
   266             // Holds a copy of the client's heap chunk
       
   267             DChunk* heapCopyChunk;
       
   268             TLinAddr heapCopyChunkAddress;
       
   269             TUint32 heapCopyChunkMappingAttributes;
       
   270             r = Kern::ChunkCreate( info, heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes );
       
   271             TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap(CP) - creating chunk returned: %d", r));
       
   272     
       
   273             // Unfortunately we have to commit every page in the copied chunk irrespective of whether that's the case
       
   274             // with the kernel chunk due to mutex ordering enforced by the kernel. See the note about this below.  
       
   275             // This results in waste but with the way the kernel heap currently works it's not too bad.
       
   276             // TODO fix this so it's more generic and doesn't rely on details of how the kernel heap works.
       
   277             r = Kern::ChunkCommit(heapCopyChunk, 0, info.iMaxSize);            
       
   278             
       
   279             // Keep track of the pages we need to de-commit from the copy
       
   280             // We allocate enough space here so we don't attempt to resise
       
   281             TLinAddr* pageAddrsToDeCommit = new TLinAddr[info.iMaxSize / KPageSize];
       
   282             TUint pageAddrsToDeCommitIndex = 0;
       
   283             
       
   284             TBool cleanupCopyChunk = EFalse;
       
   285             if  ( r == KErrNone )
       
   286                 {
       
   287                 HBuf8* data = HBuf8::New(KPageSize);
       
   288                 if (data)
       
   289                     {
       
   290                     TAny* dataPtr = (TAny*) data->Ptr();
       
   291                 
       
   292                     r = kernelHeapHelper.TryLock();
       
   293                     TInt actualKernelChunkSize = kernelChunk->Size();
       
   294                     
       
   295                     if ( r == KErrNone )
       
   296                         {
       
   297                         
       
   298                         // We now attempt to copy the kernel heap page by page
       
   299                         // This is because the kernel chunk is disconnected and hence can have pages
       
   300                         // in the middle of the heap that havent' been committed yet.
       
   301                         // TODO can we make this more efficient?
       
   302                         TInt err = KErrNone;
       
   303                         TUint8* kernChunkAddr = kernelChunk->Base();
       
   304                         TUint8* copyChunkAddr = (TUint8*) heapCopyChunkAddress;
       
   305                         while(err == KErrNone && 
       
   306                               kernChunkAddr < kernelChunk->Base() + kernelChunk->MaxSize())
       
   307                             {
       
   308                             XTRAP(err, XT_DEFAULT, memcpy(dataPtr, kernChunkAddr, KPageSize));
       
   309                             if (!err)
       
   310                                 {
       
   311                                 // It'd be nice if we could just commit the pages of the copy chunk to match 
       
   312                                 // the commited pages in the kernel heap here but that violates the following
       
   313                                 // mutex ordering:
       
   314                                 // mutex KernHeap order 8 [from kernelHeapHelper.TryLock()] vs 
       
   315                                 // mutex MemoryObjectMutex1 order 9 [from Kern::ChunkCommit()]
       
   316                                 memcpy(copyChunkAddr, dataPtr, KPageSize);
       
   317                                 }
       
   318                             else
       
   319                                 {
       
   320                                 // This page in the kernel heap wasn't committed so we can continue onto the next   
       
   321                                 err = KErrNone;
       
   322                                 // but we do need to remember this so ...
       
   323                                 pageAddrsToDeCommit[pageAddrsToDeCommitIndex++] = (TLinAddr) copyChunkAddr;                                  
       
   324                                 }
       
   325                             kernChunkAddr += KPageSize;    
       
   326                             copyChunkAddr += KPageSize;
       
   327                             }
       
   328                         kernelHeapHelper.TryUnlock();
       
   329                         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap(CP) - copied kernel heap data" ));
       
   330 
       
   331                         // Now remove the bits we didn't actually need to commit
       
   332                         for(TUint i=0; i < pageAddrsToDeCommitIndex; i++) 
       
   333                             {
       
   334                             r = heapCopyChunk->Decommit(pageAddrsToDeCommit[i], KPageSize);
       
   335                             if (r != KErrNone) 
       
   336                                 {
       
   337                                 break;
       
   338                                 }
       
   339                             }
       
   340                         if (r != KErrNone)
       
   341                             {
       
   342                             TInt oversizedEndLength = heapCopyChunk->Size() - actualKernelChunkSize;
       
   343                             r = heapCopyChunk->Decommit(actualKernelChunkSize, oversizedEndLength);                                    
       
   344                             }
       
   345                         
       
   346                         if (r == KErrNone)
       
   347                             {
       
   348                             // Transfer ownership of the copy heap chunk to the heap object.
       
   349                             TInt offset = (TInt) heapCopyChunkAddress - (TInt) kernelChunk->Base();
       
   350                             TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap(CP) - heapCopyChunkAddress: 0x%08x, kernel chunk base: 0x%08x",
       
   351                                                     heapCopyChunkAddress, kernelChunk->Base()));
       
   352                             r = aHeap.AssociateWithKernelChunk( kernelChunk, heapCopyChunk, heapCopyChunkAddress, offset );
       
   353                             }
       
   354                         else
       
   355                             {
       
   356                             TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap(CP) - failed to decommit all the unnecessary pages from the copy chunk - %d", r ));
       
   357                             cleanupCopyChunk = ETrue;
       
   358                             }                        
       
   359                         }         
       
   360                     else
       
   361                         {
       
   362                         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap(CP) - failed to lock the kernel heap" ));
       
   363                         cleanupCopyChunk = ETrue;
       
   364                         }
       
   365                     
       
   366                     delete data;
       
   367                     }
       
   368                 else
       
   369                     {
       
   370                     TRACE_KH( Kern::Printf("Failed to allocate a 4K buffer" ) );
       
   371                     r = KErrNoMemory;
       
   372                     cleanupCopyChunk = ETrue;
       
   373                     }
       
   374                 }
       
   375             else
       
   376                 {
       
   377                 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap(CP) - copy chunk create error: %d", r ) );
       
   378                 cleanupCopyChunk = ETrue;
       
   379                 }
       
   380             
       
   381             if (cleanupCopyChunk)
       
   382                 {
       
   383                 NKern::ThreadEnterCS();
       
   384                 Kern::ChunkClose( heapCopyChunk );
       
   385                 heapCopyChunk = NULL;
       
   386                 NKern::ThreadLeaveCS();
       
   387                 }
       
   388             
       
   389             delete[] pageAddrsToDeCommit;
       
   390             pageAddrsToDeCommit = NULL;
       
   391             }
       
   392         else
       
   393             {
       
   394             TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap(CP) - failed to open the kernel chunk" ) );
       
   395             }
       
   396         }
       
   397     else
       
   398         {
       
   399         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap(CP) - failed to open the kernel heap: %d", r ) );
       
   400         }
       
   401     
       
   402     kernelHeapHelper.Close();
       
   403 
       
   404     if  ( r != KErrNone )
       
   405         {                    
       
   406         aHeap.Close(); // also deals with the chunk                    
       
   407         }                           
       
   408     
       
   409     
       
   410     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::OpenKernelHeap(CP) - END - ret: %d", r ) );
       
   411     return r;
       
   412     }
       
   413 
       
   414 TInt DMemSpyDriverLogChanHeapDataKernel::MakeKernelHeapCopy()
       
   415     {
       
   416     // First phase is to 
       
   417     // a) Open kernel heap
       
   418     // b) Make a copy of the heap data
       
   419     //
       
   420     // The driver leaves kernel context with the copy of the kernel heap still associated with MemSpy's process.
       
   421     // The second driver call will copy the chunk data to user side and release the kernel side chunk.
       
   422 
       
   423     iKernelHeap.Reset();
       
   424     NKern::ThreadEnterCS();
       
   425 
       
   426     TInt r = OpenKernelHeap( iKernelHeap );
       
   427     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetFullDataInit() - open err: %d", r));
       
   428 
       
   429     NKern::ThreadLeaveCS();
       
   430 
       
   431     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetFullDataInit() - END - ret: %d", r));
       
   432     return r;
       
   433     }
       
   434 
       
   435 void DMemSpyDriverLogChanHeapDataKernel::FreeKernelHeapCopy()
       
   436     {
       
   437     iKernelHeap.Close();
       
   438     }
       
   439 
       
   440 TInt DMemSpyDriverLogChanHeapDataKernel::GetFullData( TMemSpyDriverInternalHeapDataParams& aParams )
       
   441     {
       
   442     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetFullData() - START") );
       
   443 
       
   444     TInt r = OpenTempObject( aParams.iTid, EThread );
       
   445     if  ( r != KErrNone )
       
   446         {
       
   447         Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetFullData() - END - thread not found");
       
   448         return r;
       
   449         }
       
   450     // Don't need to check if the kernel heap contains DRM data unlike for user heaps
       
   451 
       
   452     DThread* thread = (DThread*) TempObject();
       
   453     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetFullData - thread: %O", thread) );
       
   454 
       
   455     r = DoGetFullData(aParams, thread, iKernelHeap);
       
   456 
       
   457     CloseTempObject();
       
   458 
       
   459     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapDataKernel::GetFullData() - END - ret: %d", r) );
       
   460     return r;
       
   461     }