memana/analyzetoolclient/dynamicmemoryhook/src/analyzetoolallocator.cpp
changeset 2 6a82cd05fb1e
parent 1 3ff3fecb12fe
equal deleted inserted replaced
1:3ff3fecb12fe 2:6a82cd05fb1e
     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:  Definitions for the class RAnalyzeToolAllocator.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "analyzetoolallocator.h"
       
    20 #include "analyzetoolmemoryallocator.h"
       
    21 #include "atlog.h"
       
    22 #include "analyzetoolpanics.pan"
       
    23 #include "analyzetoolfastlog.h"
       
    24 #include <e32svr.h>
       
    25 
       
    26 // CONSTANTS
       
    27 
       
    28 // Length of the callstack address
       
    29 const TUint32 KAddressLength = 4;
       
    30 
       
    31 // Thread count
       
    32 const TInt KThreadCount = 1;
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 // RAnalyzeToolAllocator::RAnalyzeToolAllocator()
       
    36 // C++ default constructor can NOT contain any code, that
       
    37 // might leave.
       
    38 // -----------------------------------------------------------------------------
       
    39 //
       
    40 RAnalyzeToolAllocator::RAnalyzeToolAllocator( TBool aNotFirst, 
       
    41                                               RATStorageServer& aStorageServer, 
       
    42                                               RArray<TCodeblock>& aCodeblocks, 
       
    43                                               RMutex& aMutex,
       
    44                                               TUint aProcessId,
       
    45                                               RAnalyzeTool& aAnalyzeTool,
       
    46                                               TBool aStorageServerOpen,
       
    47                                               TUint32 aLogOption,
       
    48                                               TUint32 aAllocCallStackSize,
       
    49                                               TUint32 aFreeCallStackSize ) :
       
    50     RAnalyzeToolMemoryAllocator( aNotFirst ),
       
    51     iStorageServer( aStorageServer ), 
       
    52     iCodeblocks( aCodeblocks ), 
       
    53     iMutex( aMutex ),
       
    54     iProcessId( aProcessId ),
       
    55     iThreadArray( KATMaxCallstackLength ),
       
    56     iAnalyzeTool( aAnalyzeTool ),
       
    57     iStorageServerOpen( aStorageServerOpen ),
       
    58     iLogOption( aLogOption ),
       
    59     iAllocMaxCallStack( aAllocCallStackSize ),
       
    60     iFreeMaxCallStack( aFreeCallStackSize )
       
    61     {
       
    62     LOGSTR1( "ATMH RAnalyzeToolAllocator::RAnalyzeToolAllocator()" );
       
    63     
       
    64     // Append thread to array of the users of this allocator
       
    65     TThreadParamsBuf params;
       
    66     params().iThreadId = RThread().Id().operator TUint();
       
    67     TInt error = iAnalyzeTool.ThreadStack( params );
       
    68     if ( KErrNone == error )
       
    69         {
       
    70         LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
       
    71         LOGSTR2( "ATMH Thread stack size:    %x", params().iStackSize );
       
    72         error = iThreadArray.Append( TThreadStack( RThread().Id(), 
       
    73                              params().iStackAddress + params().iStackSize ) );
       
    74         }
       
    75     
       
    76     __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) ); 
       
    77     }
       
    78 
       
    79 // -----------------------------------------------------------------------------
       
    80 // RAnalyzeToolAllocator::~RAnalyzeToolAllocator()
       
    81 // Destructor.
       
    82 // -----------------------------------------------------------------------------
       
    83 //
       
    84 RAnalyzeToolAllocator::~RAnalyzeToolAllocator()
       
    85     {
       
    86     LOGSTR1( "ATMH RAnalyzeToolAllocator::~RAnalyzeToolAllocator()" );
       
    87     
       
    88     // Close the thread array 
       
    89     iThreadArray.Close();
       
    90     }
       
    91     
       
    92 // -----------------------------------------------------------------------------
       
    93 // RAnalyzeToolAllocator::Uninstall()
       
    94 // Uninstalls the current allocator
       
    95 // -----------------------------------------------------------------------------
       
    96 //
       
    97 void RAnalyzeToolAllocator::Uninstall()
       
    98     {
       
    99     LOGSTR1( "ATMH RAnalyzeToolAllocator::Uninstall()" );
       
   100 
       
   101     // Switch back to the original allocator
       
   102     SwitchOriginalAllocator();
       
   103     
       
   104     // Check if this is shared allocator between threads
       
   105     if ( iThreadArray.Count() > KThreadCount )
       
   106         {
       
   107         // Close the shared allocator
       
   108         Close();
       
   109         return;
       
   110         }
       
   111 
       
   112 #if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
       
   113     #ifndef __WINS__ 
       
   114     // Remove dummy Tls handle
       
   115     UserSvr::DllFreeTls( KDummyHandle );
       
   116     #endif
       
   117 #endif
       
   118     
       
   119     // Since this is the last thread using this allocator it can be deleted
       
   120     delete this;
       
   121     }
       
   122 
       
   123 #ifdef __WINS__
       
   124 
       
   125 // -----------------------------------------------------------------------------
       
   126 // RAnalyzeToolAllocator::Alloc() WINS version
       
   127 // Allocates a cell of specified size from the heap.
       
   128 // -----------------------------------------------------------------------------
       
   129 //
       
   130 UEXPORT_C TAny* RAnalyzeToolAllocator::Alloc( TInt aSize )
       
   131     {
       
   132     LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc()" );
       
   133     
       
   134     // Acquire the mutex
       
   135     iMutex.Wait();
       
   136     
       
   137     // Alloc memory from the original allocator
       
   138     TAny* p = iAllocator->Alloc( aSize );
       
   139     
       
   140     LOGSTR3( "ATMH RAnalyzeToolAllocator::Alloc() - aSize: %i, address: %x", 
       
   141              aSize,  (TUint32) p );
       
   142     
       
   143     // Don't collect call stack and log data
       
   144     // if storage server not open or logging mode not fast xti.
       
   145     if ( iStorageServerOpen || iLogOption == EATLogToXtiFast )
       
   146         {
       
   147         // Reset the callstack
       
   148         iCallStack.Reset();
       
   149     
       
   150         // Find the current thread callstack start address
       
   151         TUint32 stackstart( 0 );
       
   152         TBool found( FindCurrentThreadStack( stackstart ) );
       
   153         LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   154         
       
   155         TUint32 _sp;
       
   156         __asm
       
   157             {
       
   158             mov [_sp], esp
       
   159             }
       
   160         
       
   161         // Get codeblocks count
       
   162         TInt blocksCount( iCodeblocks.Count() );
       
   163         TInt error( KErrNone );
       
   164         TUint arrayCounter = 0;
       
   165         
       
   166         for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   167             {
       
   168             TUint32 addr = (TUint32) *( (TUint32*) i );
       
   169             if ( ! IsAddressLoadedCode( addr ) )
       
   170                 continue;
       
   171             for ( TInt j = 0; j < blocksCount; j++ )
       
   172                 {
       
   173                 if ( iCodeblocks[j].CheckAddress( addr ) )
       
   174                     {
       
   175                     // To avoid recursive call to ReAlloc specifying granularity
       
   176                     // Add address to the callstack
       
   177                     iCallStack[arrayCounter] = addr;
       
   178                     arrayCounter++;
       
   179                     break;
       
   180                     }
       
   181                 }
       
   182             if ( arrayCounter == KATMaxCallstackLength ||
       
   183                  arrayCounter == iAllocMaxCallStack )
       
   184                 {
       
   185                 LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   186                 break;
       
   187                 }
       
   188             }
       
   189         // Log the memory allocation information
       
   190         if ( iLogOption == EATLogToXtiFast )
       
   191             {
       
   192             // Using fast xti.
       
   193             ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize );
       
   194             }
       
   195         else
       
   196             {
       
   197             // Using storage server.
       
   198             error = iStorageServer.LogMemoryAllocated( (TUint32) p,
       
   199                                                        iCallStack,
       
   200                                                        aSize );
       
   201             if ( KErrNone != error )
       
   202                 {
       
   203                 LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
       
   204                 switch ( error )
       
   205                     {
       
   206                     case KErrNoMemory:
       
   207                     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - KErrNoMemory case"  );
       
   208                     if ( iStorageServerOpen )
       
   209                         {
       
   210                         iStorageServerOpen = EFalse;
       
   211                         LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - close iStorageServer"  );
       
   212                         iStorageServer.Close();
       
   213                         }
       
   214                     break;
       
   215                     }
       
   216                 }
       
   217             }
       
   218         }
       
   219     // Release the mutex
       
   220     iMutex.Signal();
       
   221     
       
   222     return p;
       
   223     }
       
   224 #else
       
   225 
       
   226 // -----------------------------------------------------------------------------
       
   227 // RAnalyzeToolAllocator::Alloc() ARMV5 version
       
   228 // Allocates a cell of specified size from the heap.
       
   229 // -----------------------------------------------------------------------------
       
   230 //
       
   231 TAny* RAnalyzeToolAllocator::Alloc( TInt aSize )
       
   232     {
       
   233     LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc()" );
       
   234     
       
   235     // Acquire the mutex
       
   236     iMutex.Wait();
       
   237     
       
   238     // Alloc memory from the original allocator
       
   239     TAny* p = iAllocator->Alloc( aSize );
       
   240     
       
   241     // Don't collect call stack and log data
       
   242     // if storage server not open or logging mode not fast xti.
       
   243     if ( iStorageServerOpen || iLogOption == EATLogToXtiFast )
       
   244         {
       
   245         // Reset the callstack
       
   246         iCallStack.Reset(); 
       
   247         
       
   248         // Find the current thread callstack start address
       
   249         TUint32 stackstart( 0 );
       
   250         TBool found( FindCurrentThreadStack( stackstart ) );
       
   251         LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   252         
       
   253         // Get codeblocks count
       
   254         TInt blocksCount( iCodeblocks.Count() );
       
   255         TInt error( KErrNone );
       
   256         TUint arrayCounter = 0;
       
   257         
       
   258         for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   259             {
       
   260             for ( TInt j = 0; j < blocksCount; j++ )
       
   261                 {
       
   262                 if ( iCodeblocks[j].CheckAddress( (TUint32) *( (TUint32*) i ) ) )
       
   263                     {
       
   264                     // To avoid recursive call to ReAlloc specifying granularity
       
   265                     // Add address to the callstack
       
   266                     iCallStack[arrayCounter] = ( (TUint32) *( (TUint32*) i ) );
       
   267                     arrayCounter++;
       
   268                     break;
       
   269                     }
       
   270                 }
       
   271             if ( arrayCounter == KATMaxCallstackLength ||
       
   272                  arrayCounter == iAllocMaxCallStack )
       
   273                 {
       
   274                 LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   275                 break;
       
   276                 }
       
   277             }
       
   278         // Log the memory allocation information
       
   279         if ( iLogOption == EATLogToXtiFast )
       
   280             {
       
   281             // Fast xti.
       
   282             ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize );
       
   283             }
       
   284         else
       
   285             {
       
   286             // Using storage server.
       
   287             error = iStorageServer.LogMemoryAllocated( (TUint32) p, 
       
   288                                                         iCallStack, 
       
   289                                                         aSize );
       
   290             if ( KErrNone != error )
       
   291                 {
       
   292                 LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
       
   293                 switch ( error )
       
   294                     {
       
   295                     case KErrNoMemory:
       
   296                     LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc() - KErrNoMemory case"  );
       
   297                     if ( iStorageServerOpen )
       
   298                         {
       
   299                         iStorageServerOpen = EFalse;
       
   300                         LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc() - close iStorageServer"  );
       
   301                         iStorageServer.Close();
       
   302                         }
       
   303                     break;
       
   304                     }
       
   305                 }
       
   306             }
       
   307         }
       
   308  
       
   309     // Release the mutex
       
   310     iMutex.Signal(); 
       
   311     
       
   312     // Return the allocatated memory
       
   313     return p;
       
   314     }
       
   315 #endif // __WINS__
       
   316 
       
   317 // -----------------------------------------------------------------------------
       
   318 // RAnalyzeToolAllocator::Free()
       
   319 // Frees the allocated memory
       
   320 // -----------------------------------------------------------------------------
       
   321 //
       
   322 TAny RAnalyzeToolAllocator::Free( TAny* aPtr )
       
   323     {
       
   324     LOGSTR1( "ATMH RAnalyzeToolAllocator::Free()" );
       
   325 
       
   326     // Acquire the mutex
       
   327     iMutex.Wait();
       
   328     
       
   329     // Don't collect or log data if storage server not open or logging mode not fast xti.
       
   330     if ( iStorageServerOpen || iLogOption == EATLogToXtiFast )
       
   331         {
       
   332         // Reset the callstack
       
   333         iFreeCallStack.Reset();
       
   334         
       
   335         // Check if XTI logging mode because free call stack is not used in other log options.
       
   336         if ( (iLogOption == EATUseDefault || iLogOption == EATLogToXti || iLogOption == EATLogToXtiFast )
       
   337                 && iFreeMaxCallStack > 0 )
       
   338             {
       
   339             // Find the current thread callstack start address
       
   340             TUint32 stackstart( 0 );
       
   341             TBool found( FindCurrentThreadStack( stackstart ) );
       
   342             LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   343             TUint32 _sp;
       
   344             
       
   345             #ifdef __WINS__
       
   346                 __asm
       
   347                     {
       
   348                     mov [_sp], esp
       
   349                     }
       
   350             #else
       
   351                 _sp = __current_sp();
       
   352             #endif
       
   353             
       
   354             // Get codeblocks count
       
   355             TInt blocksCount( iCodeblocks.Count() );
       
   356             TUint arrayCounter = 0;
       
   357         
       
   358             for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   359                 {
       
   360                 TUint32 addr = (TUint32) *( (TUint32*) i );
       
   361                 if ( ! IsAddressLoadedCode( addr ) )
       
   362                     continue;
       
   363                 for ( TInt j = 0; j < blocksCount; j++ )
       
   364                     {
       
   365                     if ( iCodeblocks[j].CheckAddress( addr ) )
       
   366                         {
       
   367                         // To avoid recursive call to ReAlloc specifying granularity
       
   368                         // Add address to the callstack
       
   369                         iFreeCallStack[arrayCounter] = addr;
       
   370                         arrayCounter++;
       
   371                         break;
       
   372                         }
       
   373                     }
       
   374                 if ( arrayCounter == KATMaxFreeCallstackLength ||
       
   375                      arrayCounter == iFreeMaxCallStack )
       
   376                     {
       
   377                     break;
       
   378                     }
       
   379                 }
       
   380             LOGSTR2( "ATMH > iFreeCallStack count ( %i )", arrayCounter );
       
   381             }
       
   382         
       
   383         // Log freed memory.
       
   384         if ( iLogOption == EATLogToXtiFast )
       
   385             {
       
   386             // Using fast xti.
       
   387             ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
       
   388             }
       
   389         else
       
   390             {
       
   391             // Using storage server.
       
   392             TInt err( iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack ) );
       
   393             if ( err != KErrNone )
       
   394                 {
       
   395                 LOGSTR2( "ATMH > LogMemoryFreed err( %i )", err );
       
   396                 }
       
   397             }
       
   398         }
       
   399     
       
   400     // Free the memory using original allocator
       
   401     iAllocator->Free( aPtr ); 
       
   402     
       
   403     LOGSTR2( "ATMH RAnalyzeToolAllocator::Free() - aPtr: %x", (TUint32)aPtr );
       
   404     
       
   405     // Release the mutex
       
   406     iMutex.Signal();
       
   407     }
       
   408 
       
   409 // -----------------------------------------------------------------------------
       
   410 // RAnalyzeToolAllocator::Open()
       
   411 // Opens this heap for shared access. Opening the heap increases 
       
   412 // the heap's access count by one.
       
   413 // -----------------------------------------------------------------------------
       
   414 //
       
   415 TInt RAnalyzeToolAllocator::Open()
       
   416     {
       
   417     LOGSTR1( "ATMH RAnalyzeToolAllocator::Open()");
       
   418     
       
   419     // Acquire the mutex
       
   420     iMutex.Wait();
       
   421     
       
   422     // Share the memory using original allocator
       
   423     TInt error = iAllocator->Open();
       
   424     
       
   425     // If everything is OK add thread to the array which use this allocator
       
   426     if ( KErrNone == error )
       
   427         {
       
   428         TThreadParamsBuf params;
       
   429         params().iThreadId = RThread().Id().operator TUint();
       
   430         error = iAnalyzeTool.ThreadStack( params );
       
   431 
       
   432         __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
       
   433 
       
   434         if ( KErrNone == error )
       
   435             {
       
   436             LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
       
   437             LOGSTR2( "ATMH Thread stack size:    %x", params().iStackSize );
       
   438             iThreadArray.Append( TThreadStack( RThread().Id(), 
       
   439                     params().iStackAddress + params().iStackSize ) );
       
   440             }
       
   441         }
       
   442     
       
   443     // Release the mutex
       
   444     iMutex.Signal();
       
   445     
       
   446     // Return the error code
       
   447     return error;
       
   448     }
       
   449 
       
   450 // -----------------------------------------------------------------------------
       
   451 // RAnalyzeToolAllocator::Close()
       
   452 // Closes this shared heap. Closing the heap decreases the heap's 
       
   453 // access count by one.
       
   454 // -----------------------------------------------------------------------------
       
   455 //
       
   456 void RAnalyzeToolAllocator::Close()
       
   457     {
       
   458     LOGSTR1( "ATMH RAnalyzeToolAllocator::Close()" );
       
   459     
       
   460     // Acquire the mutex
       
   461     iMutex.Wait();
       
   462     
       
   463     // Close the memory using original allocator
       
   464     iAllocator->Close();
       
   465     
       
   466     TInt count = iThreadArray.Count();
       
   467     
       
   468     // Iterate through array of threads to remove current thread
       
   469     for ( TInt i = 0; i < count; i++ )
       
   470         {
       
   471         // Check if this is current thread
       
   472         if ( iThreadArray[ i ].Match() )
       
   473             {
       
   474             // Remove the thread
       
   475             iThreadArray.Remove( i );
       
   476             break;
       
   477             }
       
   478         }
       
   479     
       
   480     // Release the mutex
       
   481     iMutex.Signal();
       
   482     }
       
   483 
       
   484 #ifdef __WINS__
       
   485 
       
   486 // -----------------------------------------------------------------------------
       
   487 // RAnalyzeToolAllocator::ReAlloc()
       
   488 // Increases or decreases the size of an existing cell.
       
   489 // -----------------------------------------------------------------------------
       
   490 //
       
   491 TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
       
   492     {
       
   493     LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" );
       
   494 
       
   495     // Acquire the mutex
       
   496     iMutex.Wait();
       
   497 
       
   498     // Realloc the memory using original allocator
       
   499     TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
       
   500     
       
   501     // NULL addresses are not in a process under test
       
   502     if ( ptr && !( aMode & ENeverMove ) )
       
   503         {
       
   504         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
       
   505                 (TUint32)aPtr, (TUint32)ptr );
       
   506         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i", 
       
   507                 aSize, aMode );
       
   508 
       
   509         // Don't collect or log data if storage server not open or logging mode fast xti.
       
   510         if ( iStorageServerOpen || iLogOption == EATLogToXtiFast )
       
   511             {
       
   512             // Reset the callstack
       
   513             iReCallStack.Reset(); 
       
   514 
       
   515             // Find the current thread callstack start address
       
   516             TUint32 stackstart( 0 ); 
       
   517             TBool found( FindCurrentThreadStack( stackstart ) );
       
   518             LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   519             
       
   520             // Get current sp
       
   521             TUint32 _sp( 0 );
       
   522             __asm
       
   523                 {
       
   524                 mov [_sp], esp
       
   525                 }
       
   526             
       
   527             // Get codeblocks count
       
   528             TInt blocksCount( iCodeblocks.Count() );
       
   529             TInt error( KErrNone );
       
   530             TUint arrayCounter = 0;
       
   531             
       
   532             for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   533                 {
       
   534                 TUint32 addr = (TUint32) *( (TUint32*) i );
       
   535                 if ( ! IsAddressLoadedCode( addr ) )
       
   536                     continue;
       
   537                 for ( TInt j = 0; j < blocksCount; j++ )
       
   538                     {
       
   539                     if ( iCodeblocks[j].CheckAddress( addr ) )
       
   540                         {
       
   541                         // To avoid recursive call to ReAlloc specifying granularity
       
   542                         // Add address to the callstack
       
   543                         iReCallStack[arrayCounter] = addr;
       
   544                         arrayCounter++;
       
   545                         break;
       
   546                         }
       
   547                     }
       
   548                 if ( arrayCounter == KATMaxCallstackLength || 
       
   549                      arrayCounter == iAllocMaxCallStack )
       
   550                     {
       
   551                     LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   552                     break;
       
   553                     }
       
   554                 }
       
   555             
       
   556             // No need to report free if the aPtr was NULL
       
   557             if ( aPtr != NULL )
       
   558                 {
       
   559                 // Reset the free callstack
       
   560                 iFreeCallStack.Reset();
       
   561                 
       
   562                 // if XTI logging mode(s) we also log call stack in free.
       
   563                 if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToXti || iLogOption == EATLogToXtiFast )
       
   564                         && iFreeMaxCallStack > 0 )
       
   565                     {
       
   566                     for ( TInt i = 0; i < arrayCounter; i++ )
       
   567                         {
       
   568                         if ( i == KATMaxFreeCallstackLength || i == iFreeMaxCallStack )
       
   569                             {
       
   570                             break;
       
   571                             }
       
   572                         iFreeCallStack[i] = iReCallStack[i];
       
   573                         }
       
   574                     }
       
   575                 
       
   576                 // Try to remove old address from the storage server's
       
   577                 // leak array. If found it's removed from the array because system frees
       
   578                 // old address directly in the RHeap in ReAlloc case.
       
   579                 if ( iLogOption == EATLogToXtiFast )
       
   580                     {
       
   581                     ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
       
   582                     }
       
   583                 else
       
   584                     {
       
   585                     iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
       
   586                     }
       
   587                 }
       
   588             
       
   589             // Log the memory allocation information
       
   590             if ( iLogOption == EATLogToXtiFast )
       
   591                 {
       
   592                 // Using fast xti.
       
   593                 ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iFreeCallStack, aSize);
       
   594                 }
       
   595             else
       
   596                 {
       
   597                 // Using storage server.
       
   598                 error = iStorageServer.LogMemoryAllocated( (TUint32) ptr, 
       
   599                                                             iReCallStack, 
       
   600                                                             aSize );
       
   601                 if ( KErrNone != error )
       
   602                     {
       
   603                     LOGSTR2( "ATMH LogMemoryAllocated ReAlloc error %i", error );
       
   604                     switch ( error )
       
   605                         {
       
   606                         case KErrNoMemory:
       
   607                         LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - KErrNoMemory case"  );
       
   608                         if ( iStorageServerOpen )
       
   609                             {
       
   610                             iStorageServerOpen = EFalse;
       
   611                             LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - close iStorageServer"  );
       
   612                             iStorageServer.Close();
       
   613                             }
       
   614                         break;
       
   615                         }
       
   616                     }
       
   617                 }
       
   618             }
       
   619         }
       
   620     
       
   621     // Release the mutex
       
   622     iMutex.Signal();
       
   623 
       
   624     // Return pointer to the reallocated cell
       
   625     return ptr; 
       
   626     }
       
   627 
       
   628 #else
       
   629 
       
   630 // -----------------------------------------------------------------------------
       
   631 // RAnalyzeToolAllocator::ReAlloc()
       
   632 // Increases or decreases the size of an existing cell.
       
   633 // -----------------------------------------------------------------------------
       
   634 //
       
   635 TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
       
   636     {
       
   637     LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" );
       
   638 
       
   639     // Acquire the mutex
       
   640     iMutex.Wait();
       
   641 
       
   642     // Realloc the memory using original allocator
       
   643     TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
       
   644 
       
   645     // NULL addresses are not in a process under test
       
   646     if ( ptr && !( aMode & ENeverMove ) )
       
   647         {
       
   648         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
       
   649                 (TUint32)aPtr, (TUint32)ptr );
       
   650         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i", 
       
   651                 aSize, aMode );
       
   652 
       
   653         // Don't collect or log data if storage server not open or logging mode fast xti.
       
   654         if ( iStorageServerOpen || iLogOption == EATLogToXtiFast )
       
   655             {
       
   656             // Reset the callstack
       
   657             iReCallStack.Reset(); 
       
   658 
       
   659             // Find the current thread callstack start address
       
   660             TUint32 stackstart( 0 ); 
       
   661             TBool found( FindCurrentThreadStack( stackstart ) );
       
   662             LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   663             
       
   664             // Get codeblocks count
       
   665             TInt blocksCount( iCodeblocks.Count() );
       
   666             TInt error( KErrNone );
       
   667             TUint arrayCounter = 0;
       
   668             
       
   669             for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   670                 {
       
   671                 for ( TInt j = 0; j < blocksCount; j++ )
       
   672                     {
       
   673                     if ( iCodeblocks[j].CheckAddress( (TUint32) *( (TUint32*) i ) ) )
       
   674                         {
       
   675                         // To avoid recursive call to ReAlloc specifying granularity
       
   676                         // Add address to the callstack
       
   677                         iReCallStack[arrayCounter] = ( (TUint32) *( (TUint32*) i ) );
       
   678                         arrayCounter++;
       
   679                         break;
       
   680                         }
       
   681                     }
       
   682                 if ( arrayCounter == KATMaxCallstackLength || 
       
   683                      arrayCounter == iAllocMaxCallStack )
       
   684                     {
       
   685                     LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   686                     break;
       
   687                     }
       
   688                 }
       
   689             
       
   690             // No need to report free if the aPtr was NULL
       
   691             if ( aPtr != NULL )
       
   692                 {
       
   693                 // Reset the free callstack
       
   694                 iFreeCallStack.Reset();
       
   695                 
       
   696                 // if XTI logging mode(s) we also log call stack with free.
       
   697                 if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToXti || iLogOption == EATLogToXtiFast )
       
   698                         && iFreeMaxCallStack > 0 )
       
   699                     {
       
   700                     for ( TInt i = 0; i < arrayCounter; i++ )
       
   701                         {
       
   702                         if ( i == iFreeCallStack.Count() )
       
   703                             {
       
   704                             break;
       
   705                             }
       
   706                         iFreeCallStack[i] = iReCallStack[i];
       
   707                         }
       
   708                     }
       
   709                 
       
   710                 // Try to remove old address from the storage server's
       
   711                 // leak array. If found it's removed from the array because system frees
       
   712                 // old address directly in the RHeap in ReAlloc case.
       
   713                 if ( iLogOption == EATLogToXtiFast )
       
   714                     {
       
   715                     ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
       
   716                     }
       
   717                 else
       
   718                     {
       
   719                     iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
       
   720                     }
       
   721                 }
       
   722         
       
   723             // Log the memory allocation information
       
   724             if ( iLogOption == EATLogToXtiFast )
       
   725                 {
       
   726                 // Using fast xti.
       
   727                 ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iReCallStack, aSize );
       
   728                 }
       
   729             else
       
   730                 {
       
   731                 // Using storage server.
       
   732                 error = iStorageServer.LogMemoryAllocated( (TUint32) ptr, 
       
   733                                                             iReCallStack, 
       
   734                                                             aSize );
       
   735                 if ( KErrNone != error )
       
   736                     {
       
   737                     LOGSTR2( "ATMH LogMemoryAllocated ReAlloc error %i", error );
       
   738                     switch ( error )
       
   739                         {
       
   740                         case KErrNoMemory:
       
   741                         LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - KErrNoMemory case"  );
       
   742                         if ( iStorageServerOpen )
       
   743                             {
       
   744                             iStorageServerOpen = EFalse;
       
   745                             LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - close iStorageServer"  );
       
   746                             iStorageServer.Close();
       
   747                             }
       
   748                         break;
       
   749                         }
       
   750                     }
       
   751                 }
       
   752             }
       
   753         }
       
   754 
       
   755     // Release the mutex
       
   756     iMutex.Signal();
       
   757 
       
   758     // Return pointer to the reallocated cell
       
   759     return ptr; 
       
   760     }
       
   761 
       
   762 #endif // __WINS__
       
   763 
       
   764 // -----------------------------------------------------------------------------
       
   765 // RAnalyzeToolAllocator::Compress()
       
   766 // The function frees excess committed space from the top of the heap.
       
   767 // The size of the heap is never reduced below the minimum size 
       
   768 // specified during creation of the heap.
       
   769 // -----------------------------------------------------------------------------
       
   770 //
       
   771 TInt RAnalyzeToolAllocator::Compress()
       
   772     {
       
   773     LOGSTR1( "ATMH RAnalyzeToolAllocator::Compress()" );
       
   774 
       
   775     // Acquire the mutex
       
   776     iMutex.Wait();
       
   777 
       
   778     // Compress the memory using original allocator
       
   779     TInt compress = iAllocator->Compress();
       
   780 
       
   781     // Release the mutex
       
   782     iMutex.Signal();
       
   783 
       
   784     // Return the space reclaimed
       
   785     return compress;
       
   786     }
       
   787 
       
   788 // -----------------------------------------------------------------------------
       
   789 // RAnalyzeToolAllocator::Reset()
       
   790 // Frees all allocated cells on this heap. 
       
   791 // -----------------------------------------------------------------------------
       
   792 //
       
   793 void RAnalyzeToolAllocator::Reset()
       
   794     {
       
   795     LOGSTR1( "ATMH RAnalyzeToolAllocator::Reset()" );
       
   796 
       
   797     // Acquire the mutex
       
   798     iMutex.Wait();
       
   799 
       
   800     // Reset the memory using original allocator
       
   801     iAllocator->Reset();
       
   802 
       
   803     // Release the mutex
       
   804     iMutex.Signal();
       
   805     }
       
   806 
       
   807 // -----------------------------------------------------------------------------
       
   808 // RAnalyzeToolAllocator::AllocSize()
       
   809 // Gets the number of cells allocated on this heap, and 
       
   810 // the total space allocated to them.
       
   811 // -----------------------------------------------------------------------------
       
   812 //
       
   813 TInt RAnalyzeToolAllocator::AllocSize( TInt& aTotalAllocSize ) const
       
   814     {
       
   815     LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocSize()" );
       
   816     
       
   817     // Acquire the mutex
       
   818     iMutex.Wait();
       
   819     
       
   820     // Acquire the memory information using original allocator
       
   821     TInt size = iAllocator->AllocSize( aTotalAllocSize );
       
   822     
       
   823     // Release the mutex
       
   824     iMutex.Signal();
       
   825     
       
   826     // Return the number of cells allocated on this heap.
       
   827     return size;
       
   828     }
       
   829 
       
   830 // -----------------------------------------------------------------------------
       
   831 // RAnalyzeToolAllocator::Available()
       
   832 // Gets the total free space currently available on the heap and the 
       
   833 // space available in the largest free block. The space available 
       
   834 // represents the total space which can be allocated. Note that 
       
   835 // compressing the heap may reduce the total free space available 
       
   836 // and the space available in the largest free block.
       
   837 // -----------------------------------------------------------------------------
       
   838 //
       
   839 TInt RAnalyzeToolAllocator::Available( TInt& aBiggestBlock ) const
       
   840     {
       
   841     LOGSTR1( "ATMH RAnalyzeToolAllocator::Available()" );
       
   842     
       
   843     // Acquire the mutex
       
   844     iMutex.Wait();
       
   845     
       
   846     // Acquire the memory information using original allocator
       
   847     TInt available = iAllocator->Available( aBiggestBlock );
       
   848     
       
   849     // Release the mutex
       
   850     iMutex.Signal();
       
   851     
       
   852     // Return the total free space currently available on the heap
       
   853     return available;
       
   854     }
       
   855 
       
   856 // -----------------------------------------------------------------------------
       
   857 // RAnalyzeToolAllocator::AllocLen()
       
   858 // Gets the length of the available space in the specified 
       
   859 // allocated cell.
       
   860 // -----------------------------------------------------------------------------
       
   861 //
       
   862 TInt RAnalyzeToolAllocator::AllocLen( const TAny* aCell ) const
       
   863     {
       
   864     LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocLen()" ); 
       
   865     
       
   866     // Acquire the mutex
       
   867     iMutex.Wait();
       
   868     
       
   869     // Acquire the memory information using original allocator
       
   870     TInt len = iAllocator->AllocLen( aCell );
       
   871     
       
   872     // Release the mutex
       
   873     iMutex.Signal();
       
   874     
       
   875     // Return the length of the available space in the allocated cell.
       
   876     return len;
       
   877     }
       
   878 
       
   879 // -----------------------------------------------------------------------------
       
   880 // RAnalyzeToolAllocator::DebugFunction()
       
   881 // Invocates specified debug funtionality.
       
   882 // -----------------------------------------------------------------------------
       
   883 //
       
   884 TInt RAnalyzeToolAllocator::DebugFunction( TInt aFunc, TAny* a1, TAny* a2 )
       
   885     {
       
   886     LOGSTR2( "ATMH RAnalyzeToolAllocator::DebugFunction() %i", aFunc );
       
   887     
       
   888     // Acquire the mutex
       
   889     iMutex.Wait();
       
   890     
       
   891     // Invocate debug funtion using original allocator
       
   892     TInt debug = iAllocator->DebugFunction( aFunc, a1, a2 );
       
   893     
       
   894     switch( aFunc )
       
   895 		{  
       
   896 		case EMarkEnd:
       
   897 			{
       
   898 			// Disables the __UHEAP_MARKEND macro
       
   899 			LOGSTR1( "ATMH __UHEAP_MARKEND macro called" );
       
   900 			if ( debug > 0 )
       
   901 				{
       
   902 				LOGSTR2( "ATMH __UHEAP_MARKEND detects leaks: %d", debug );
       
   903 				// Because there is leaks the alloc panic will occur but
       
   904 				// lets return a zero to pretend that everything is OK
       
   905 				debug = 0;
       
   906 				}
       
   907 			}
       
   908 		break;
       
   909 		
       
   910 		default:
       
   911 			{
       
   912 			}
       
   913 		break;
       
   914 		}
       
   915     
       
   916     // Release the mutex
       
   917     iMutex.Signal();
       
   918     
       
   919     // Return information of the debug function success
       
   920     return debug;
       
   921     }
       
   922 
       
   923 // -----------------------------------------------------------------------------
       
   924 // RAnalyzeToolAllocator::Extension_()
       
   925 // Extension function
       
   926 // -----------------------------------------------------------------------------
       
   927 //
       
   928 TInt RAnalyzeToolAllocator::Extension_( TUint aExtensionId, TAny*& a0, 
       
   929     TAny* a1 ) 
       
   930     {
       
   931     LOGSTR1( "ATMH RAnalyzeToolAllocator::Extension_()" );
       
   932     
       
   933     // Acquire the mutex
       
   934     iMutex.Wait();
       
   935     
       
   936     // Invocate extension funtion using original allocator
       
   937     TInt ext = RAllocator::Extension_( aExtensionId, a0, a1 );
       
   938     
       
   939     // Release the mutex
       
   940     iMutex.Signal();
       
   941     
       
   942     // Return information of the extension function success
       
   943     return ext;
       
   944     }
       
   945 
       
   946 // -----------------------------------------------------------------------------
       
   947 // RAnalyzeToolAllocator::ShareHeap()
       
   948 // Share heap with other thread
       
   949 // -----------------------------------------------------------------------------
       
   950 //
       
   951 void RAnalyzeToolAllocator::ShareHeap()
       
   952     {
       
   953     LOGSTR1( "ATMH RAnalyzeToolAllocator::ShareHeap()" );
       
   954     
       
   955     // Call the overwrited Open function
       
   956     Open();
       
   957     }
       
   958     
       
   959 // -----------------------------------------------------------------------------
       
   960 // RAnalyzeToolAllocator::FindCurrentThreadStack()
       
   961 // Find the current thread which is using the heap
       
   962 // -----------------------------------------------------------------------------
       
   963 //
       
   964 TBool RAnalyzeToolAllocator::FindCurrentThreadStack( TUint32& aStackStart )
       
   965     {
       
   966     LOGSTR2( "ATMH RAnalyzeToolAllocator::FindCurrentThreadStack(), count( %i )", 
       
   967             iThreadArray.Count() );
       
   968     
       
   969     // Flag for indicating that right thread has been found
       
   970     TBool found( EFalse );
       
   971     // If threre is only one thread it must be the right thread
       
   972     if ( iThreadArray.Count() == KThreadCount )
       
   973         {
       
   974         if ( !iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
       
   975             {
       
   976             // This MUST BE the right thread
       
   977             //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
       
   978             }
       
   979         else if ( iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
       
   980             {
       
   981             found = ETrue;
       
   982             }
       
   983         }
       
   984     else
       
   985         {
       
   986         // Iterate through array to find right thread
       
   987         TInt count( iThreadArray.Count() );
       
   988         
       
   989         for ( TInt i = 0; i < count; i++ )
       
   990             {
       
   991             // Check if this is the right thread
       
   992             if ( iThreadArray[ i ].ThreadStackStart( aStackStart ) )
       
   993                 {
       
   994                 // Right thread found. Mark the flag
       
   995                 found = ETrue;
       
   996                 break;
       
   997                 }
       
   998             }
       
   999         // If right thread was not found the panic must be raised
       
  1000         if ( !found )
       
  1001             {
       
  1002             //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
       
  1003             }
       
  1004         }
       
  1005     return found;
       
  1006     }
       
  1007 
       
  1008 // End of File