memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapInfo.cpp
changeset 0 a03f92240627
child 20 ca8a1b6995f6
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 "MemSpyDriverLogChanHeapInfo.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 "MemSpyDriverOSAdaption.h"
       
    34 #include "MemSpyDriverHeapWalker.h"
       
    35 #include "MemSpyDriverSuspensionManager.h"
       
    36 
       
    37 
       
    38 
       
    39 DMemSpyDriverLogChanHeapInfo::DMemSpyDriverLogChanHeapInfo( DMemSpyDriverDevice& aDevice, DThread& aThread )
       
    40 :	DMemSpyDriverLogChanHeapBase( aDevice, aThread )
       
    41     {
       
    42     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::DMemSpyDriverLogChanHeapInfo() - this: 0x%08x", this ));
       
    43     }
       
    44 
       
    45 
       
    46 DMemSpyDriverLogChanHeapInfo::~DMemSpyDriverLogChanHeapInfo()
       
    47 	{
       
    48 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::~DMemSpyDriverLogChanHeapInfo() - START - this: 0x%08x", this ));
       
    49 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::~DMemSpyDriverLogChanHeapInfo() - END - this: 0x%08x", this ));
       
    50 	}
       
    51 
       
    52 
       
    53 
       
    54 
       
    55 
       
    56 
       
    57 
       
    58 
       
    59 TInt DMemSpyDriverLogChanHeapInfo::Request( TInt aFunction, TAny* a1, TAny* a2 )
       
    60 	{
       
    61 	TInt r = DMemSpyDriverLogChanHeapBase::Request( aFunction, a1, a2 );
       
    62     if  ( r == KErrNone )
       
    63         {
       
    64         if  ( aFunction != EMemSpyDriverOpCodeHeapInfoFetchFreeCells )
       
    65             {
       
    66             ReleaseFreeCells();
       
    67             }
       
    68         //
       
    69         switch( aFunction )
       
    70 		    {
       
    71         case EMemSpyDriverOpCodeHeapInfoGetUser:
       
    72             r = GetHeapInfoUser( (TMemSpyDriverInternalHeapRequestParameters*) a1 );
       
    73             break;
       
    74 	    case EMemSpyDriverOpCodeHeapInfoGetKernel:
       
    75             r = GetHeapInfoKernel( (TMemSpyDriverInternalHeapRequestParameters*) a1, (TDes8*) a2 );
       
    76             break;
       
    77         case EMemSpyDriverOpCodeHeapInfoGetIsDebugKernel:
       
    78             r = GetIsDebugKernel( (TBool*) a1 );
       
    79             break;
       
    80         case EMemSpyDriverOpCodeHeapInfoFetchFreeCells:
       
    81             r = FetchFreeCells( (TDes8*) a1 );
       
    82             break;
       
    83 
       
    84         default:
       
    85             r = KErrNotSupported;
       
    86 		    break;
       
    87             }
       
    88         }
       
    89     //
       
    90     return r;
       
    91 	}
       
    92 
       
    93 
       
    94 TBool DMemSpyDriverLogChanHeapInfo::IsHandler( TInt aFunction ) const
       
    95     {
       
    96     return ( aFunction > EMemSpyDriverOpCodeHeapInfoBase && aFunction < EMemSpyDriverOpCodeHeapInfoEnd );
       
    97     }
       
    98 
       
    99 
       
   100 
       
   101 
       
   102 
       
   103 
       
   104 
       
   105 
       
   106 
       
   107 
       
   108 
       
   109 
       
   110 
       
   111 TInt DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser( TMemSpyDriverInternalHeapRequestParameters* aParams )
       
   112     {
       
   113     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser() - START" ) );
       
   114 
       
   115     TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &iHeapInfoParams, sizeof(TMemSpyDriverInternalHeapRequestParameters) );
       
   116     if  ( r != KErrNone )
       
   117         {
       
   118     	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - params read error: %d", r));
       
   119         }
       
   120     else
       
   121         {
       
   122         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapInfoParams.iTid, iHeapInfoParams.iRHeapVTable, iHeapInfoParams.iDebugAllocator) );
       
   123 
       
   124 	    r = OpenTempObject( iHeapInfoParams.iTid, EThread );
       
   125 	    if  ( r != KErrNone )
       
   126 		    {
       
   127     	    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - thread not found") );
       
   128             }
       
   129         else
       
   130             {
       
   131             // Check that the process' thread's are suspended
       
   132             DThread* thread = (DThread*) TempObject();
       
   133             if  ( SuspensionManager().IsSuspended( *thread ) )
       
   134                 {
       
   135                 TFullName chunkName;
       
   136 
       
   137                 // Open client's heap
       
   138                 RMemSpyDriverRHeapUser rHeap( OSAdaption() );
       
   139                 DChunk* userHeapChunk = NULL;
       
   140                 r = OpenUserHeap( *thread, iHeapInfoParams.iRHeapVTable, rHeap, userHeapChunk, &chunkName );
       
   141                 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - opening client heap returned: %d", r) );
       
   142 
       
   143                 if  ( r == KErrNone )
       
   144                     {
       
   145                     // This object holds all of the info we will accumulate for the client.
       
   146                     TMemSpyHeapInfo masterHeapInfo;
       
   147                     masterHeapInfo.SetType( TMemSpyHeapInfo::ETypeRHeap );
       
   148                     masterHeapInfo.SetTid( iHeapInfoParams.iTid );
       
   149                     masterHeapInfo.SetPid( OSAdaption().DThread().GetOwningProcessId( *thread ) );
       
   150 
       
   151                     // This is the RHeap-specific object that contains all RHeap info
       
   152                     TMemSpyHeapInfoRHeap& rHeapInfo = masterHeapInfo.AsRHeap();
       
   153 
       
   154                     // This is the object data for the RHeap instance
       
   155                     TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData();
       
   156                     rHeap.CopyObjectDataTo( rHeapObjectData );
       
   157 
       
   158                     // We must walk the client's heap in order to build statistics
       
   159                     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - calling heap walker constructor..."));
       
   160                     TMemSpyHeapWalkerNullObserver observer; 
       
   161                     RMemSpyDriverHeapWalker heapWalker( rHeap, iHeapInfoParams.iDebugAllocator );
       
   162                     if  ( iHeapInfoParams.iBuildFreeCellList )
       
   163                         {
       
   164                         heapWalker.SetObserver( this );
       
   165                         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - collecting free cells"));
       
   166                         }
       
   167                     else
       
   168                         {
       
   169                         heapWalker.SetObserver( &observer );
       
   170                         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - not collecting free cells"));
       
   171                         }
       
   172 
       
   173                     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - starting traversal..." ));
       
   174 
       
   175 #if ( defined( TRACE_TYPE_USERHEAP ) && defined( TRACE_TYPE_HEAPWALK ) )
       
   176                     heapWalker.SetPrintDebug();
       
   177 #endif
       
   178                     r = heapWalker.Traverse();
       
   179                     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - finished traversal - err: %d", r ));
       
   180 
       
   181                     TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics();
       
   182                     heapWalker.CopyStatsTo( rHeapStats );
       
   183 
       
   184                     // Get remaining meta data that isn't stored elsewhere
       
   185                     TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
       
   186                     rHeapMetaData.SetChunkName( chunkName );
       
   187                     rHeapMetaData.SetChunkSize( (TUint) OSAdaption().DChunk().GetSize( *userHeapChunk ) );
       
   188                     rHeapMetaData.SetChunkHandle( userHeapChunk );
       
   189                     rHeapMetaData.SetChunkBaseAddress( OSAdaption().DChunk().GetBase( *userHeapChunk ) );
       
   190                     rHeapMetaData.SetDebugAllocator( iHeapInfoParams.iDebugAllocator );
       
   191                     rHeapMetaData.SetHeaderSizeFree( RMemSpyDriverRHeapBase::FreeCellHeaderSize() );
       
   192                     rHeapMetaData.SetHeaderSizeAllocated( RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( iHeapInfoParams.iDebugAllocator ) );
       
   193                     rHeapMetaData.SetUserThread( ETrue );
       
   194 
       
   195                     // Get any heap-specific info
       
   196                     rHeap.GetHeapSpecificInfo( masterHeapInfo );
       
   197 
       
   198                     PrintHeapInfo( masterHeapInfo );
       
   199 
       
   200                     // Write free cells if requested
       
   201                     if  ( r == KErrNone && iHeapInfoParams.iBuildFreeCellList )
       
   202                         {
       
   203                         r = PrepareFreeCellTransferBuffer();
       
   204                         }
       
   205 
       
   206                     // Update info ready for writing back to the user-side
       
   207                     if  ( r >= KErrNone )
       
   208                         {
       
   209                         // Write results back to user-side
       
   210                         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - writing to user-side..."));
       
   211                         TMemSpyHeapInfo* userMasterInfo = iHeapInfoParams.iMasterInfo;
       
   212                         const TInt error = Kern::ThreadRawWrite( &ClientThread(), userMasterInfo, &masterHeapInfo, sizeof(TMemSpyHeapInfo) );
       
   213                         if  ( error < 0 )
       
   214                             {
       
   215                             r = error;
       
   216                             }
       
   217                         }
       
   218 
       
   219                     // Release resources
       
   220                     rHeap.DisassociateWithKernelChunk();
       
   221                     }
       
   222                 }
       
   223             else
       
   224                 {
       
   225                 r = KErrAccessDenied;
       
   226                 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - parent process not suspended => KErrAccessDenied"));
       
   227                 }
       
   228 
       
   229 	        CloseTempObject();
       
   230             }
       
   231         }
       
   232 
       
   233 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser() - END - ret: %d", r));
       
   234     return r;
       
   235     }
       
   236 
       
   237 
       
   238 
       
   239 
       
   240 
       
   241 
       
   242 
       
   243 TInt DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel( TMemSpyDriverInternalHeapRequestParameters* aParams, TDes8* aTransferBuffer )
       
   244     {
       
   245     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - START - aTransferBuffer: 0x%08x", aTransferBuffer ) );
       
   246 
       
   247     TMemSpyDriverInternalHeapRequestParameters params;
       
   248     TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverInternalHeapRequestParameters) );
       
   249     if  ( r == KErrNone )
       
   250         {
       
   251         // Open kernel heap
       
   252         TFullName heapChunkName;
       
   253         RMemSpyDriverRHeapKernelInPlace rHeap;
       
   254         r = OpenKernelHeap( rHeap, &heapChunkName );
       
   255         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - open err: %d", r ) );
       
   256 
       
   257         if  ( r == KErrNone )
       
   258             {
       
   259             // We must identify if we have a debug kernel allocator
       
   260             const TBool debugAllocator = IsDebugKernel( rHeap );
       
   261             TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - debugAllocator: %d", debugAllocator ) );
       
   262 
       
   263             r = DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel( rHeap, debugAllocator, heapChunkName, params.iMasterInfo, aTransferBuffer );
       
   264             TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - base class get heap info: %d", r) );
       
   265             }
       
   266         }
       
   267     else
       
   268         {
       
   269     	Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - params read error: %d", r);
       
   270         }
       
   271 
       
   272 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - END - ret: %d", r) );
       
   273     return r;
       
   274     }
       
   275 
       
   276 
       
   277 
       
   278 
       
   279 
       
   280 
       
   281 TInt DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel( TBool* aIsDebugKernel )
       
   282     {
       
   283     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - START") );
       
   284     
       
   285     TInt r = KErrNone;
       
   286     TBool debugKernel = EFalse;
       
   287 
       
   288     NKern::ThreadEnterCS();
       
   289     
       
   290     RMemSpyDriverRHeapKernelInPlace rHeap;
       
   291     r = OpenKernelHeap( rHeap );
       
   292     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - open kernel heap returned: %d", r) );
       
   293 
       
   294     if  ( r == KErrNone )
       
   295         {
       
   296         debugKernel = IsDebugKernel( rHeap );
       
   297 
       
   298         // Tidy up
       
   299         rHeap.DisassociateWithKernelChunk();
       
   300         }
       
   301 
       
   302     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - debugKernel: %d", debugKernel) );
       
   303 
       
   304     // Write back to user-land
       
   305     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - writing to user-side...") );
       
   306     r = Kern::ThreadRawWrite( &ClientThread(), aIsDebugKernel, &debugKernel, sizeof(TBool) );
       
   307 
       
   308     NKern::ThreadLeaveCS();
       
   309 
       
   310  	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - END - ret: %d", r) );
       
   311     return r;
       
   312     }
       
   313 
       
   314 
       
   315 
       
   316 
       
   317 
       
   318 
       
   319 
       
   320 
       
   321 
       
   322 
       
   323 
       
   324 
       
   325 
       
   326 
       
   327 
       
   328 
       
   329 
       
   330 
       
   331 
       
   332 
       
   333 
       
   334 
       
   335 
       
   336 
       
   337 
       
   338 
       
   339 
       
   340 
       
   341 
       
   342 
       
   343 
       
   344 
       
   345 
       
   346 
       
   347 
       
   348 
       
   349