memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryHeap.cpp
changeset 0 a03f92240627
child 30 86a2e675b80a
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 "MemSpyEngineHelperSysMemTrackerEntryHeap.h"
       
    19 
       
    20 // System includes
       
    21 #include <e32base.h>
       
    22 #include <badesca.h>
       
    23 
       
    24 // Driver includes
       
    25 #include <memspy/driver/memspydriverclient.h>
       
    26 
       
    27 // User includes
       
    28 #include <memspy/engine/memspyengine.h>
       
    29 #include <memspy/engine/memspyengineutils.h>
       
    30 #include <memspy/engine/memspyengineoutputsink.h>
       
    31 #include <memspy/engine/memspyengineoutputlist.h>
       
    32 #include <memspy/engine/memspyenginehelperheap.h>
       
    33 #include <memspy/engine/memspyenginehelperchunk.h>
       
    34 #include <memspy/engine/memspyengineobjectthread.h>
       
    35 #include <memspy/engine/memspyengineobjectprocess.h>
       
    36 #include <memspy/engine/memspyengineobjectcontainer.h>
       
    37 #include <memspy/engine/memspyenginehelpercodesegment.h>
       
    38 #include "MemSpyEngineHelperSysMemTrackerImp.h"
       
    39 #include <memspy/engine/memspyenginehelpersysmemtrackercycle.h>
       
    40 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
       
    41 #include <memspy/engine/memspyenginehelpersysmemtracker.h>
       
    42 
       
    43 
       
    44 
       
    45 
       
    46 
       
    47 
       
    48 
       
    49 
       
    50 
       
    51 CMemSpyEngineHelperSysMemTrackerEntryHeap::CMemSpyEngineHelperSysMemTrackerEntryHeap( CMemSpyEngineHelperSysMemTrackerImp& aTracker, TMemSpyEngineSysMemTrackerType aType )
       
    52 :   CMemSpyEngineHelperSysMemTrackerEntry( aTracker, aType )
       
    53     {
       
    54     }
       
    55 
       
    56 
       
    57 CMemSpyEngineHelperSysMemTrackerEntryHeap::~CMemSpyEngineHelperSysMemTrackerEntryHeap()
       
    58     {
       
    59     delete iThreadName;
       
    60     }
       
    61 
       
    62 
       
    63 void CMemSpyEngineHelperSysMemTrackerEntryHeap::ConstructL()
       
    64     {
       
    65     // Kernel
       
    66     TFullName name;
       
    67     MemSpyEngineUtils::GetKernelHeapThreadName( name );
       
    68     iThreadName = name.AllocL();
       
    69     //
       
    70     UpdateHeapInfoL( iLast );
       
    71     iCurrent = iLast;
       
    72     //
       
    73     SetHandle( iCurrent.AsRHeap().MetaData().ChunkHandle() );
       
    74     }
       
    75 
       
    76 
       
    77 void CMemSpyEngineHelperSysMemTrackerEntryHeap::ConstructL( CMemSpyThread& aThread )
       
    78     {
       
    79     TFullName* name = new(ELeave) TFullName();
       
    80     CleanupStack::PushL( name );
       
    81     aThread.FullName( *name );
       
    82     iThreadName = name->AllocL();
       
    83     CleanupStack::PopAndDestroy( name );
       
    84     //
       
    85     SetThread( aThread.Id() );
       
    86     SetProcess( aThread.Process().Id() );
       
    87     //
       
    88     UpdateHeapInfoL( iLast );
       
    89     iCurrent = iLast;
       
    90     //
       
    91     SetHandle( iCurrent.AsRHeap().MetaData().ChunkHandle() );
       
    92     }
       
    93 
       
    94 
       
    95 CMemSpyEngineHelperSysMemTrackerEntryHeap* CMemSpyEngineHelperSysMemTrackerEntryHeap::NewUserLC( CMemSpyEngineHelperSysMemTrackerImp& aTracker, CMemSpyThread& aThread )
       
    96     {
       
    97     CMemSpyEngineHelperSysMemTrackerEntryHeap* self = new(ELeave) CMemSpyEngineHelperSysMemTrackerEntryHeap( aTracker, EMemSpyEngineSysMemTrackerTypeHeapUser );
       
    98     CleanupStack::PushL( self );
       
    99     self->ConstructL( aThread );
       
   100     return self;
       
   101     }
       
   102 
       
   103 
       
   104 CMemSpyEngineHelperSysMemTrackerEntryHeap* CMemSpyEngineHelperSysMemTrackerEntryHeap::NewKernelLC( CMemSpyEngineHelperSysMemTrackerImp& aTracker )
       
   105     {
       
   106     CMemSpyEngineHelperSysMemTrackerEntryHeap* self = new(ELeave) CMemSpyEngineHelperSysMemTrackerEntryHeap( aTracker, EMemSpyEngineSysMemTrackerTypeHeapKernel );
       
   107     CleanupStack::PushL( self );
       
   108     self->ConstructL();
       
   109     return self;
       
   110     }
       
   111 
       
   112 
       
   113 TUint64 CMemSpyEngineHelperSysMemTrackerEntryHeap::Key() const
       
   114     {
       
   115     const TUint32 val = ( Type() << 28 ) + ThreadId(); 
       
   116     TUint64 ret = val;
       
   117     ret <<= 32;
       
   118     ret += Handle();
       
   119     return ret;
       
   120     }
       
   121 
       
   122 
       
   123 void CMemSpyEngineHelperSysMemTrackerEntryHeap::UpdateFromL( const CMemSpyEngineHelperSysMemTrackerEntry& aEntry )
       
   124     {
       
   125     const CMemSpyEngineHelperSysMemTrackerEntryHeap& entry = static_cast< const CMemSpyEngineHelperSysMemTrackerEntryHeap& >( aEntry );
       
   126     
       
   127     // Update state
       
   128     iLast = iCurrent;
       
   129     iCurrent = entry.iCurrent;
       
   130     }
       
   131 
       
   132 
       
   133 TBool CMemSpyEngineHelperSysMemTrackerEntryHeap::HasChangedL( const TMemSpyEngineHelperSysMemTrackerConfig& /*aConfig*/ ) const
       
   134     {
       
   135     TBool hasChanged = EFalse;
       
   136 
       
   137     // Work out if something has changed...
       
   138     if  ( HasHeapSizeChanged() )
       
   139         {
       
   140         hasChanged = ETrue;
       
   141         }
       
   142     else if ( HaveAllocCellsChanged() )
       
   143         {
       
   144         hasChanged = ETrue;
       
   145         }
       
   146     else if ( HaveFreeCellsChanged() )
       
   147         {
       
   148         hasChanged = ETrue;
       
   149         }
       
   150 
       
   151     return hasChanged;
       
   152     }
       
   153 
       
   154 
       
   155 void CMemSpyEngineHelperSysMemTrackerEntryHeap::CreateChangeDescriptorL( CMemSpyEngineHelperSysMemTrackerCycle& aCycle )
       
   156     {
       
   157     CMemSpyEngineHelperSysMemTrackerCycleChangeHeap* changeDescriptor = CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::NewLC( Attributes(), *iThreadName, iCurrent, IsNew() ? NULL : &iLast );
       
   158     aCycle.AddAndPopL( changeDescriptor );
       
   159     }
       
   160 
       
   161 
       
   162 void CMemSpyEngineHelperSysMemTrackerEntryHeap::UpdateCycleStatistics( CMemSpyEngineHelperSysMemTrackerCycle& aCycle )
       
   163     {
       
   164     const TMemSpyHeapMetaDataRHeap& metaC = iCurrent.AsRHeap().MetaData();
       
   165     const TMemSpyHeapStatisticsRHeap& statsC = iCurrent.AsRHeap().Statistics();
       
   166     //
       
   167     aCycle.AddToMemoryUsed( metaC.ChunkSize() );
       
   168     aCycle.AddToCellCountAlloc( statsC.StatsAllocated().TypeCount() );
       
   169     aCycle.AddToMemoryHeapAllocs( statsC.StatsAllocated().TypeSize() );
       
   170     aCycle.AddToCellCountFree( statsC.StatsFree().TypeCount() );
       
   171     aCycle.AddToMemoryHeapFrees( statsC.StatsFree().TypeSize() );
       
   172     }
       
   173 
       
   174 
       
   175 void CMemSpyEngineHelperSysMemTrackerEntryHeap::SetAsShared( TBool aShared )
       
   176     {
       
   177     iCurrent.AsRHeap().MetaData().SetSharedHeap( aShared );
       
   178     }
       
   179 
       
   180 
       
   181 void CMemSpyEngineHelperSysMemTrackerEntryHeap::UpdateHeapInfoL( TMemSpyHeapInfo& aInfo )
       
   182     {
       
   183     TInt error = KErrNone;
       
   184     //
       
   185     if  ( Type() == EMemSpyEngineSysMemTrackerTypeHeapUser )
       
   186         {
       
   187         // Get the heap info first of all
       
   188         Engine().ProcessSuspendLC( ProcessId() );
       
   189         error = Engine().Driver().GetHeapInfoUser( aInfo, ThreadId() );
       
   190         CleanupStack::PopAndDestroy(); // ProcessSuspendLC
       
   191         }
       
   192     else if ( Type() == EMemSpyEngineSysMemTrackerTypeHeapKernel )
       
   193         {
       
   194         // Kernel
       
   195         error = Engine().Driver().GetHeapInfoKernel( aInfo );
       
   196         }
       
   197     else
       
   198         {
       
   199         User::Invariant();
       
   200         }
       
   201     //
       
   202     User::LeaveIfError( error );
       
   203     //
       
   204     if  ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown )
       
   205         {
       
   206         User::Leave( KErrNotSupported );
       
   207         }
       
   208     }
       
   209 
       
   210 
       
   211 TBool CMemSpyEngineHelperSysMemTrackerEntryHeap::HasHeapSizeChanged() const
       
   212     {
       
   213     return ( iCurrent.AsRHeap().MetaData().ChunkSize() != iLast.AsRHeap().MetaData().ChunkSize() );
       
   214     }
       
   215 
       
   216 
       
   217 TBool CMemSpyEngineHelperSysMemTrackerEntryHeap::HaveFreeCellsChanged() const
       
   218     {
       
   219     TBool changed = 
       
   220         ( iCurrent.AsRHeap().ObjectData().iFree.next != iLast.AsRHeap().ObjectData().iFree.next ) ||
       
   221         ( iCurrent.AsRHeap().ObjectData().iFree.len != iLast.AsRHeap().ObjectData().iFree.len );
       
   222     //
       
   223     if ( !changed )
       
   224         {
       
   225         changed |= ( iCurrent.AsRHeap().Statistics().StatsFree().TypeCount() != iLast.AsRHeap().Statistics().StatsFree().TypeCount() );
       
   226         changed |= ( iCurrent.AsRHeap().Statistics().StatsFree().SlackSpaceCellSize() != iLast.AsRHeap().Statistics().StatsFree().SlackSpaceCellSize() );
       
   227         }
       
   228     //
       
   229     return changed;
       
   230     }
       
   231 
       
   232 
       
   233 TBool CMemSpyEngineHelperSysMemTrackerEntryHeap::HaveAllocCellsChanged() const
       
   234     {
       
   235     return 
       
   236         ( iCurrent.AsRHeap().Statistics().StatsAllocated().TypeCount() != iLast.AsRHeap().Statistics().StatsAllocated().TypeCount() ) ||
       
   237         ( iCurrent.AsRHeap().Statistics().StatsAllocated().TypeSize() != iLast.AsRHeap().Statistics().StatsAllocated().TypeSize() );
       
   238     }
       
   239 
       
   240 
       
   241 
       
   242 
       
   243 
       
   244 
       
   245 
       
   246 CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::CMemSpyEngineHelperSysMemTrackerCycleChangeHeap( TUint8 aAttribs, const TMemSpyHeapInfo& aCurrent )
       
   247 :   CMemSpyEngineHelperSysMemTrackerCycleChange( aAttribs ), iCurrent( aCurrent )
       
   248     {
       
   249     }
       
   250 
       
   251 
       
   252 CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::~CMemSpyEngineHelperSysMemTrackerCycleChangeHeap()
       
   253     {
       
   254     delete iLast;
       
   255     delete iThreadName;
       
   256     }
       
   257 
       
   258 
       
   259 void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::ConstructL( const TDesC& aThreadName, const TMemSpyHeapInfo* aLast )
       
   260     {
       
   261     BaseConstructL();
       
   262 
       
   263     // Save the thread name
       
   264     iThreadName = aThreadName.AllocL();
       
   265 
       
   266     // Save last heap data (if available)
       
   267     if ( aLast )
       
   268         {
       
   269         iLast = new (ELeave) TMemSpyHeapInfo();
       
   270         *iLast = *aLast;
       
   271         }
       
   272     }
       
   273 
       
   274 
       
   275 CMemSpyEngineHelperSysMemTrackerCycleChangeHeap* CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::NewLC( TUint8 aAttribs, const TDesC& aThreadName, const TMemSpyHeapInfo& aCurrent, const TMemSpyHeapInfo* aLast )
       
   276     {
       
   277     CMemSpyEngineHelperSysMemTrackerCycleChangeHeap* self = new(ELeave) CMemSpyEngineHelperSysMemTrackerCycleChangeHeap( aAttribs, aCurrent );
       
   278     CleanupStack::PushL( self );
       
   279     self->ConstructL( aThreadName, aLast );
       
   280     return self;
       
   281     }
       
   282 
       
   283 
       
   284 TMemSpyEngineSysMemTrackerType CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::Type() const
       
   285     {
       
   286     TMemSpyEngineSysMemTrackerType ret = EMemSpyEngineSysMemTrackerTypeHeapUser;
       
   287     //
       
   288     if  ( IsKernel() )
       
   289         {
       
   290         ret = EMemSpyEngineSysMemTrackerTypeHeapKernel;
       
   291         }
       
   292     //
       
   293     return ret;
       
   294     }
       
   295 
       
   296 
       
   297 void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::OutputHeaderL( CMemSpyEngineOutputSink& aSink, CMemSpyEngineHelperSysMemTrackerCycle& /*aCycle*/ )
       
   298     {
       
   299     _LIT( KHeaderHeap, "Type, Thread, Chunk, Handle, Base Addr, Size, Min, Max, 1st Free Addr, 1st Free Len, Alloc Count, Alloc Space, Free Count, Free Space, Free Slack, F.Largest, A.Largest, Attribs");
       
   300     aSink.OutputLineL( KHeaderHeap );
       
   301     }
       
   302 
       
   303 
       
   304 void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::OutputContentL( CMemSpyEngineOutputSink& aSink, CMemSpyEngineHelperSysMemTrackerCycle& /*aCycle*/ )
       
   305     {
       
   306     _LIT( KFormat, "%S,%S,%S,0x%08x,0x%08x,%d,%d,%d,0x%08x,%d,%d,%d,%d,%d,%d,%d,%d,%S" );
       
   307     //
       
   308     TMemSpySWMTTypeName type;;
       
   309     FormatType( type );
       
   310     //
       
   311     TBuf<20> attribs;
       
   312     FormatAttributes( attribs );
       
   313     //
       
   314     HBufC* buf = HBufC::NewLC( 1024 );
       
   315     TPtr pBuf(buf->Des());
       
   316 
       
   317     const TMemSpyHeapMetaDataRHeap& metaData = iCurrent.AsRHeap().MetaData();
       
   318     const TMemSpyHeapObjectDataRHeap& objectData = iCurrent.AsRHeap().ObjectData();
       
   319     const TMemSpyHeapStatisticsRHeap& stats = iCurrent.AsRHeap().Statistics();
       
   320 
       
   321     // Strip any process & thread
       
   322     const TPtrC pChunkName( MemSpyEngineUtils::TextAfterLastDoubleColon( metaData.ChunkName() ) );
       
   323 
       
   324     pBuf.Format( KFormat, 
       
   325                  &type,
       
   326                  iThreadName, 
       
   327                  &pChunkName,
       
   328                  metaData.ChunkHandle(),
       
   329                  objectData.Base(),
       
   330                  metaData.ChunkSize(),
       
   331                  objectData.iMinLength,
       
   332                  objectData.iMaxLength,
       
   333                  objectData.iFree.next,
       
   334                  objectData.iFree.len,
       
   335                  stats.StatsAllocated().TypeCount(),
       
   336                  stats.StatsAllocated().TypeSize(),
       
   337                  stats.StatsFree().TypeCount(),
       
   338                  stats.StatsFree().TypeSize(),
       
   339                  stats.StatsFree().SlackSpaceCellSize(),
       
   340                  stats.StatsFree().LargestCellSize(),
       
   341                  stats.StatsAllocated().LargestCellSize(),
       
   342                  &attribs
       
   343                  );
       
   344 
       
   345     aSink.OutputLineL( pBuf );
       
   346     CleanupStack::PopAndDestroy( buf );
       
   347     }
       
   348 
       
   349 
       
   350 void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::OutputDataL( CMemSpyEngineOutputSink& aSink, CMemSpyEngineHelperSysMemTrackerCycle& aCycle )
       
   351     {
       
   352     CMemSpyEngine& engine = aSink.Engine();
       
   353 
       
   354     // First check that we can find the user-thread okay.
       
   355     CMemSpyThread* thread = NULL;
       
   356     CMemSpyProcess* process = NULL;
       
   357     TBool allowedToDump = ETrue;
       
   358     TMemSpyEngineHelperSysMemTrackerConfig config;
       
   359     engine.HelperSysMemTracker().GetConfig( config );
       
   360     if ( config.iThreadNameFilter.Length() > 0 && iThreadName->FindF( config.iThreadNameFilter ) == KErrNotFound )
       
   361         {
       
   362         allowedToDump = EFalse;
       
   363         }
       
   364     if  ( allowedToDump && !IsKernel() )
       
   365         {
       
   366         allowedToDump = ( engine.Container().ProcessAndThreadByThreadId( iCurrent.Tid(), process, thread ) == KErrNone );
       
   367         }
       
   368 
       
   369 	// Now dump the heap data
       
   370     if  ( allowedToDump )
       
   371         {
       
   372         // Starts a data Stream
       
   373         aCycle.DataStreamBeginL( aSink, *iThreadName );
       
   374 
       
   375         if  ( IsKernel() )
       
   376             {
       
   377             engine.HelperHeap().OutputHeapDataKernelL( KMemSpyEngineSinkDoNotCreateOwnDataStream );
       
   378             }
       
   379         else if ( thread )
       
   380             {
       
   381             engine.HelperHeap().OutputHeapDataUserL( *thread, KMemSpyEngineSinkDoNotCreateOwnDataStream ); 
       
   382             }
       
   383 
       
   384         // End the stream (commit the file)
       
   385         aCycle.DataStreamEndL( aSink );
       
   386         }
       
   387     }
       
   388 
       
   389 
       
   390 TBool CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::IsKernel() const
       
   391     {
       
   392     return ( iCurrent.Pid() == 0 && iCurrent.Tid() == 0 );
       
   393     }
       
   394 
       
   395 
       
   396 void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::FormatAttributes( TDes& aBuffer ) const
       
   397     {
       
   398     _LIT( KAttribShared, "[S]" ); // Attribute for Shared Heap
       
   399     _LIT( KAttribPlus,  "+" );
       
   400     CMemSpyEngineHelperSysMemTrackerCycleChange::FormatAttributes( aBuffer );
       
   401     if ( iCurrent.AsRHeap().MetaData().IsSharedHeap() )
       
   402         {
       
   403         if ( aBuffer.Length() )
       
   404             {
       
   405             aBuffer.Append( KAttribPlus );
       
   406             }
       
   407         aBuffer.Append( KAttribShared );
       
   408         }
       
   409     }
       
   410 
       
   411