analyzetool/dynamicmemoryhook/src/analyzetoolallocator.cpp
changeset 22 a009639409f5
child 49 7fdc9a71d314
equal deleted inserted replaced
17:67c6ff54ec25 22:a009639409f5
       
     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.
       
   145     if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
   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 == EATLogToTraceFast )
       
   191             {
       
   192             // Using fast mode.
       
   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.
       
   243     if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
   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             TUint32 addr = (TUint32) *( (TUint32*) i );
       
   261             if ( ! IsAddressLoadedCode( addr ) )
       
   262                 continue;
       
   263             for ( TInt j = 0; j < blocksCount; j++ )
       
   264                 {
       
   265                 if ( iCodeblocks[j].CheckAddress( addr ) )
       
   266                     {
       
   267                     // To avoid recursive call to ReAlloc specifying granularity
       
   268                     // Add address to the callstack
       
   269                     iCallStack[arrayCounter] = ( addr );
       
   270                     arrayCounter++;
       
   271                     break;
       
   272                     }
       
   273                 }
       
   274             if ( arrayCounter == KATMaxCallstackLength ||
       
   275                  arrayCounter == iAllocMaxCallStack )
       
   276                 {
       
   277                 LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   278                 break;
       
   279                 }
       
   280             }
       
   281         // Log the memory allocation information
       
   282         if ( iLogOption == EATLogToTraceFast )
       
   283             {
       
   284             // Fast mode.
       
   285             ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize );
       
   286             }
       
   287         else
       
   288             {
       
   289             // Using storage server.
       
   290             error = iStorageServer.LogMemoryAllocated( (TUint32) p, 
       
   291                                                         iCallStack, 
       
   292                                                         aSize );
       
   293             if ( KErrNone != error )
       
   294                 {
       
   295                 LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
       
   296                 switch ( error )
       
   297                     {
       
   298                     case KErrNoMemory:
       
   299                     LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc() - KErrNoMemory case"  );
       
   300                     if ( iStorageServerOpen )
       
   301                         {
       
   302                         iStorageServerOpen = EFalse;
       
   303                         LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc() - close iStorageServer"  );
       
   304                         iStorageServer.Close();
       
   305                         }
       
   306                     break;
       
   307                     }
       
   308                 }
       
   309             }
       
   310         }
       
   311  
       
   312     // Release the mutex
       
   313     iMutex.Signal(); 
       
   314     
       
   315     // Return the allocatated memory
       
   316     return p;
       
   317     }
       
   318 #endif // __WINS__
       
   319 
       
   320 // -----------------------------------------------------------------------------
       
   321 // RAnalyzeToolAllocator::Free()
       
   322 // Frees the allocated memory
       
   323 // -----------------------------------------------------------------------------
       
   324 //
       
   325 TAny RAnalyzeToolAllocator::Free( TAny* aPtr )
       
   326     {
       
   327     LOGSTR1( "ATMH RAnalyzeToolAllocator::Free()" );
       
   328 
       
   329     // Acquire the mutex
       
   330     iMutex.Wait();
       
   331     
       
   332     // Don't collect or log data if storage server not open or logging mode not fast.
       
   333     if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
   334         {
       
   335         // Reset the callstack
       
   336         iFreeCallStack.Reset();
       
   337         
       
   338         // Check if trace logging mode because free call stack is not used in other log options.
       
   339         if ( (iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
       
   340                 && iFreeMaxCallStack > 0 )
       
   341             {
       
   342             // Find the current thread callstack start address
       
   343             TUint32 stackstart( 0 );
       
   344             TBool found( FindCurrentThreadStack( stackstart ) );
       
   345             LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   346             TUint32 _sp;
       
   347             
       
   348             #ifdef __WINS__
       
   349                 __asm
       
   350                     {
       
   351                     mov [_sp], esp
       
   352                     }
       
   353             #else
       
   354                 _sp = __current_sp();
       
   355             #endif
       
   356             
       
   357             // Get codeblocks count
       
   358             TInt blocksCount( iCodeblocks.Count() );
       
   359             TUint arrayCounter = 0;
       
   360         
       
   361             for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   362                 {
       
   363                 TUint32 addr = (TUint32) *( (TUint32*) i );
       
   364                 if ( ! IsAddressLoadedCode( addr ) )
       
   365                     continue;
       
   366                 for ( TInt j = 0; j < blocksCount; j++ )
       
   367                     {
       
   368                     if ( iCodeblocks[j].CheckAddress( addr ) )
       
   369                         {
       
   370                         // To avoid recursive call to ReAlloc specifying granularity
       
   371                         // Add address to the callstack
       
   372                         iFreeCallStack[arrayCounter] = addr;
       
   373                         arrayCounter++;
       
   374                         break;
       
   375                         }
       
   376                     }
       
   377                 if ( arrayCounter == KATMaxFreeCallstackLength ||
       
   378                      arrayCounter == iFreeMaxCallStack )
       
   379                     {
       
   380                     break;
       
   381                     }
       
   382                 }
       
   383             LOGSTR2( "ATMH > iFreeCallStack count ( %i )", arrayCounter );
       
   384             }
       
   385         
       
   386         // Log freed memory.
       
   387         if ( iLogOption == EATLogToTraceFast )
       
   388             {
       
   389             // Using fast mode.
       
   390             ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
       
   391             }
       
   392         else
       
   393             {
       
   394             // Using storage server.
       
   395             TInt err( iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack ) );
       
   396             if ( err != KErrNone )
       
   397                 {
       
   398                 LOGSTR2( "ATMH > LogMemoryFreed err( %i )", err );
       
   399                 }
       
   400             }
       
   401         }
       
   402     
       
   403     // Free the memory using original allocator
       
   404     iAllocator->Free( aPtr ); 
       
   405     
       
   406     LOGSTR2( "ATMH RAnalyzeToolAllocator::Free() - aPtr: %x", (TUint32)aPtr );
       
   407     
       
   408     // Release the mutex
       
   409     iMutex.Signal();
       
   410     }
       
   411 
       
   412 // -----------------------------------------------------------------------------
       
   413 // RAnalyzeToolAllocator::Open()
       
   414 // Opens this heap for shared access. Opening the heap increases 
       
   415 // the heap's access count by one.
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 TInt RAnalyzeToolAllocator::Open()
       
   419     {
       
   420     LOGSTR1( "ATMH RAnalyzeToolAllocator::Open()");
       
   421     
       
   422     // Acquire the mutex
       
   423     iMutex.Wait();
       
   424     
       
   425     // Share the memory using original allocator
       
   426     TInt error = iAllocator->Open();
       
   427     
       
   428     // If everything is OK add thread to the array which use this allocator
       
   429     if ( KErrNone == error )
       
   430         {
       
   431         TThreadParamsBuf params;
       
   432         params().iThreadId = RThread().Id().operator TUint();
       
   433         error = iAnalyzeTool.ThreadStack( params );
       
   434 
       
   435         __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
       
   436 
       
   437         if ( KErrNone == error )
       
   438             {
       
   439             LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
       
   440             LOGSTR2( "ATMH Thread stack size:    %x", params().iStackSize );
       
   441             iThreadArray.Append( TThreadStack( RThread().Id(), 
       
   442                     params().iStackAddress + params().iStackSize ) );
       
   443             }
       
   444         }
       
   445     
       
   446     // Release the mutex
       
   447     iMutex.Signal();
       
   448     
       
   449     // Return the error code
       
   450     return error;
       
   451     }
       
   452 
       
   453 // -----------------------------------------------------------------------------
       
   454 // RAnalyzeToolAllocator::Close()
       
   455 // Closes this shared heap. Closing the heap decreases the heap's 
       
   456 // access count by one.
       
   457 // -----------------------------------------------------------------------------
       
   458 //
       
   459 void RAnalyzeToolAllocator::Close()
       
   460     {
       
   461     LOGSTR1( "ATMH RAnalyzeToolAllocator::Close()" );
       
   462     
       
   463     // Acquire the mutex
       
   464     iMutex.Wait();
       
   465     
       
   466     // Close the memory using original allocator
       
   467     iAllocator->Close();
       
   468     
       
   469     TInt count = iThreadArray.Count();
       
   470     
       
   471     // Iterate through array of threads to remove current thread
       
   472     for ( TInt i = 0; i < count; i++ )
       
   473         {
       
   474         // Check if this is current thread
       
   475         if ( iThreadArray[ i ].Match() )
       
   476             {
       
   477             // Remove the thread
       
   478             iThreadArray.Remove( i );
       
   479             break;
       
   480             }
       
   481         }
       
   482     
       
   483     // Release the mutex
       
   484     iMutex.Signal();
       
   485     }
       
   486 
       
   487 #ifdef __WINS__
       
   488 
       
   489 // -----------------------------------------------------------------------------
       
   490 // RAnalyzeToolAllocator::ReAlloc()
       
   491 // Increases or decreases the size of an existing cell.
       
   492 // -----------------------------------------------------------------------------
       
   493 //
       
   494 TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
       
   495     {
       
   496     LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" );
       
   497 
       
   498     // Acquire the mutex
       
   499     iMutex.Wait();
       
   500 
       
   501     // Realloc the memory using original allocator
       
   502     TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
       
   503     
       
   504     // NULL addresses are not in a process under test
       
   505     if ( ptr && !( aMode & ENeverMove ) )
       
   506         {
       
   507         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
       
   508                 (TUint32)aPtr, (TUint32)ptr );
       
   509         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i", 
       
   510                 aSize, aMode );
       
   511 
       
   512         // Don't collect or log data if storage server not open or logging mode fast.
       
   513         if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
   514             {
       
   515             // Reset the callstack
       
   516             iReCallStack.Reset(); 
       
   517 
       
   518             // Find the current thread callstack start address
       
   519             TUint32 stackstart( 0 ); 
       
   520             TBool found( FindCurrentThreadStack( stackstart ) );
       
   521             LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   522             
       
   523             // Get current sp
       
   524             TUint32 _sp( 0 );
       
   525             __asm
       
   526                 {
       
   527                 mov [_sp], esp
       
   528                 }
       
   529             
       
   530             // Get codeblocks count
       
   531             TInt blocksCount( iCodeblocks.Count() );
       
   532             TInt error( KErrNone );
       
   533             TUint arrayCounter = 0;
       
   534             
       
   535             for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   536                 {
       
   537                 TUint32 addr = (TUint32) *( (TUint32*) i );
       
   538                 if ( ! IsAddressLoadedCode( addr ) )
       
   539                     continue;
       
   540                 for ( TInt j = 0; j < blocksCount; j++ )
       
   541                     {
       
   542                     if ( iCodeblocks[j].CheckAddress( addr ) )
       
   543                         {
       
   544                         // To avoid recursive call to ReAlloc specifying granularity
       
   545                         // Add address to the callstack
       
   546                         iReCallStack[arrayCounter] = addr;
       
   547                         arrayCounter++;
       
   548                         break;
       
   549                         }
       
   550                     }
       
   551                 if ( arrayCounter == KATMaxCallstackLength || 
       
   552                      arrayCounter == iAllocMaxCallStack )
       
   553                     {
       
   554                     LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   555                     break;
       
   556                     }
       
   557                 }
       
   558             
       
   559             // No need to report free if the aPtr was NULL
       
   560             if ( aPtr != NULL )
       
   561                 {
       
   562                 // Reset the free callstack
       
   563                 iFreeCallStack.Reset();
       
   564                 
       
   565                 // if trace logging mode(s) we also log call stack in free.
       
   566                 if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
       
   567                         && iFreeMaxCallStack > 0 )
       
   568                     {
       
   569                     for ( TInt i = 0; i < arrayCounter; i++ )
       
   570                         {
       
   571                         if ( i == KATMaxFreeCallstackLength || i == iFreeMaxCallStack )
       
   572                             {
       
   573                             break;
       
   574                             }
       
   575                         iFreeCallStack[i] = iReCallStack[i];
       
   576                         }
       
   577                     }
       
   578                 
       
   579                 // Try to remove old address from the storage server's
       
   580                 // leak array. If found it's removed from the array because system frees
       
   581                 // old address directly in the RHeap in ReAlloc case.
       
   582                 if ( iLogOption == EATLogToTraceFast )
       
   583                     {
       
   584                     ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
       
   585                     }
       
   586                 else
       
   587                     {
       
   588                     iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
       
   589                     }
       
   590                 }
       
   591             
       
   592             // Log the memory allocation information
       
   593             if ( iLogOption == EATLogToTraceFast )
       
   594                 {
       
   595                 // Using fast mode.
       
   596                 ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iFreeCallStack, aSize);
       
   597                 }
       
   598             else
       
   599                 {
       
   600                 // Using storage server.
       
   601                 error = iStorageServer.LogMemoryAllocated( (TUint32) ptr, 
       
   602                                                             iReCallStack, 
       
   603                                                             aSize );
       
   604                 if ( KErrNone != error )
       
   605                     {
       
   606                     LOGSTR2( "ATMH LogMemoryAllocated ReAlloc error %i", error );
       
   607                     switch ( error )
       
   608                         {
       
   609                         case KErrNoMemory:
       
   610                         LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - KErrNoMemory case"  );
       
   611                         if ( iStorageServerOpen )
       
   612                             {
       
   613                             iStorageServerOpen = EFalse;
       
   614                             LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - close iStorageServer"  );
       
   615                             iStorageServer.Close();
       
   616                             }
       
   617                         break;
       
   618                         }
       
   619                     }
       
   620                 }
       
   621             }
       
   622         }
       
   623     
       
   624     // Release the mutex
       
   625     iMutex.Signal();
       
   626 
       
   627     // Return pointer to the reallocated cell
       
   628     return ptr; 
       
   629     }
       
   630 
       
   631 #else
       
   632 
       
   633 // -----------------------------------------------------------------------------
       
   634 // RAnalyzeToolAllocator::ReAlloc()
       
   635 // Increases or decreases the size of an existing cell.
       
   636 // -----------------------------------------------------------------------------
       
   637 //
       
   638 TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
       
   639     {
       
   640     LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" );
       
   641 
       
   642     // Acquire the mutex
       
   643     iMutex.Wait();
       
   644 
       
   645     // Realloc the memory using original allocator
       
   646     TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
       
   647 
       
   648     // NULL addresses are not in a process under test
       
   649     if ( ptr && !( aMode & ENeverMove ) )
       
   650         {
       
   651         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
       
   652                 (TUint32)aPtr, (TUint32)ptr );
       
   653         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i", 
       
   654                 aSize, aMode );
       
   655 
       
   656         // Don't collect or log data if storage server not open or logging mode fast.
       
   657         if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
   658             {
       
   659             // Reset the callstack
       
   660             iReCallStack.Reset(); 
       
   661 
       
   662             // Find the current thread callstack start address
       
   663             TUint32 stackstart( 0 ); 
       
   664             TBool found( FindCurrentThreadStack( stackstart ) );
       
   665             LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   666             
       
   667             // Get codeblocks count
       
   668             TInt blocksCount( iCodeblocks.Count() );
       
   669             TInt error( KErrNone );
       
   670             TUint arrayCounter = 0;
       
   671             
       
   672             for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   673                 {
       
   674                 TUint32 addr = (TUint32) *( (TUint32*) i );
       
   675                 if ( ! IsAddressLoadedCode( addr ) )
       
   676                     continue;
       
   677                 for ( TInt j = 0; j < blocksCount; j++ )
       
   678                     {
       
   679                     if ( iCodeblocks[j].CheckAddress( addr ) )
       
   680                         {
       
   681                         // To avoid recursive call to ReAlloc specifying granularity
       
   682                         // Add address to the callstack
       
   683                         iReCallStack[arrayCounter] = ( addr );
       
   684                         arrayCounter++;
       
   685                         break;
       
   686                         }
       
   687                     }
       
   688                 if ( arrayCounter == KATMaxCallstackLength || 
       
   689                      arrayCounter == iAllocMaxCallStack )
       
   690                     {
       
   691                     LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   692                     break;
       
   693                     }
       
   694                 }
       
   695             
       
   696             // No need to report free if the aPtr was NULL
       
   697             if ( aPtr != NULL )
       
   698                 {
       
   699                 // Reset the free callstack
       
   700                 iFreeCallStack.Reset();
       
   701                 
       
   702                 // if trace logging mode(s) we also log call stack with free.
       
   703                 if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
       
   704                         && iFreeMaxCallStack > 0 )
       
   705                     {
       
   706                     for ( TInt i = 0; i < arrayCounter; i++ )
       
   707                         {
       
   708                         if ( i == iFreeCallStack.Count() )
       
   709                             {
       
   710                             break;
       
   711                             }
       
   712                         iFreeCallStack[i] = iReCallStack[i];
       
   713                         }
       
   714                     }
       
   715                 
       
   716                 // Try to remove old address from the storage server's
       
   717                 // leak array. If found it's removed from the array because system frees
       
   718                 // old address directly in the RHeap in ReAlloc case.
       
   719                 if ( iLogOption == EATLogToTraceFast )
       
   720                     {
       
   721                     ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
       
   722                     }
       
   723                 else
       
   724                     {
       
   725                     iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
       
   726                     }
       
   727                 }
       
   728         
       
   729             // Log the memory allocation information
       
   730             if ( iLogOption == EATLogToTraceFast )
       
   731                 {
       
   732                 // Using fast mode.
       
   733                 ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iReCallStack, aSize );
       
   734                 }
       
   735             else
       
   736                 {
       
   737                 // Using storage server.
       
   738                 error = iStorageServer.LogMemoryAllocated( (TUint32) ptr, 
       
   739                                                             iReCallStack, 
       
   740                                                             aSize );
       
   741                 if ( KErrNone != error )
       
   742                     {
       
   743                     LOGSTR2( "ATMH LogMemoryAllocated ReAlloc error %i", error );
       
   744                     switch ( error )
       
   745                         {
       
   746                         case KErrNoMemory:
       
   747                         LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - KErrNoMemory case"  );
       
   748                         if ( iStorageServerOpen )
       
   749                             {
       
   750                             iStorageServerOpen = EFalse;
       
   751                             LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - close iStorageServer"  );
       
   752                             iStorageServer.Close();
       
   753                             }
       
   754                         break;
       
   755                         }
       
   756                     }
       
   757                 }
       
   758             }
       
   759         }
       
   760 
       
   761     // Release the mutex
       
   762     iMutex.Signal();
       
   763 
       
   764     // Return pointer to the reallocated cell
       
   765     return ptr; 
       
   766     }
       
   767 
       
   768 #endif // __WINS__
       
   769 
       
   770 // -----------------------------------------------------------------------------
       
   771 // RAnalyzeToolAllocator::Compress()
       
   772 // The function frees excess committed space from the top of the heap.
       
   773 // The size of the heap is never reduced below the minimum size 
       
   774 // specified during creation of the heap.
       
   775 // -----------------------------------------------------------------------------
       
   776 //
       
   777 TInt RAnalyzeToolAllocator::Compress()
       
   778     {
       
   779     LOGSTR1( "ATMH RAnalyzeToolAllocator::Compress()" );
       
   780 
       
   781     // Acquire the mutex
       
   782     iMutex.Wait();
       
   783 
       
   784     // Compress the memory using original allocator
       
   785     TInt compress = iAllocator->Compress();
       
   786 
       
   787     // Release the mutex
       
   788     iMutex.Signal();
       
   789 
       
   790     // Return the space reclaimed
       
   791     return compress;
       
   792     }
       
   793 
       
   794 // -----------------------------------------------------------------------------
       
   795 // RAnalyzeToolAllocator::Reset()
       
   796 // Frees all allocated cells on this heap. 
       
   797 // -----------------------------------------------------------------------------
       
   798 //
       
   799 void RAnalyzeToolAllocator::Reset()
       
   800     {
       
   801     LOGSTR1( "ATMH RAnalyzeToolAllocator::Reset()" );
       
   802 
       
   803     // Acquire the mutex
       
   804     iMutex.Wait();
       
   805 
       
   806     // Reset the memory using original allocator
       
   807     iAllocator->Reset();
       
   808 
       
   809     // Release the mutex
       
   810     iMutex.Signal();
       
   811     }
       
   812 
       
   813 // -----------------------------------------------------------------------------
       
   814 // RAnalyzeToolAllocator::AllocSize()
       
   815 // Gets the number of cells allocated on this heap, and 
       
   816 // the total space allocated to them.
       
   817 // -----------------------------------------------------------------------------
       
   818 //
       
   819 TInt RAnalyzeToolAllocator::AllocSize( TInt& aTotalAllocSize ) const
       
   820     {
       
   821     LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocSize()" );
       
   822     
       
   823     // Acquire the mutex
       
   824     iMutex.Wait();
       
   825     
       
   826     // Acquire the memory information using original allocator
       
   827     TInt size = iAllocator->AllocSize( aTotalAllocSize );
       
   828     
       
   829     // Release the mutex
       
   830     iMutex.Signal();
       
   831     
       
   832     // Return the number of cells allocated on this heap.
       
   833     return size;
       
   834     }
       
   835 
       
   836 // -----------------------------------------------------------------------------
       
   837 // RAnalyzeToolAllocator::Available()
       
   838 // Gets the total free space currently available on the heap and the 
       
   839 // space available in the largest free block. The space available 
       
   840 // represents the total space which can be allocated. Note that 
       
   841 // compressing the heap may reduce the total free space available 
       
   842 // and the space available in the largest free block.
       
   843 // -----------------------------------------------------------------------------
       
   844 //
       
   845 TInt RAnalyzeToolAllocator::Available( TInt& aBiggestBlock ) const
       
   846     {
       
   847     LOGSTR1( "ATMH RAnalyzeToolAllocator::Available()" );
       
   848     
       
   849     // Acquire the mutex
       
   850     iMutex.Wait();
       
   851     
       
   852     // Acquire the memory information using original allocator
       
   853     TInt available = iAllocator->Available( aBiggestBlock );
       
   854     
       
   855     // Release the mutex
       
   856     iMutex.Signal();
       
   857     
       
   858     // Return the total free space currently available on the heap
       
   859     return available;
       
   860     }
       
   861 
       
   862 // -----------------------------------------------------------------------------
       
   863 // RAnalyzeToolAllocator::AllocLen()
       
   864 // Gets the length of the available space in the specified 
       
   865 // allocated cell.
       
   866 // -----------------------------------------------------------------------------
       
   867 //
       
   868 TInt RAnalyzeToolAllocator::AllocLen( const TAny* aCell ) const
       
   869     {
       
   870     LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocLen()" ); 
       
   871     
       
   872     // Acquire the mutex
       
   873     iMutex.Wait();
       
   874     
       
   875     // Acquire the memory information using original allocator
       
   876     TInt len = iAllocator->AllocLen( aCell );
       
   877     
       
   878     // Release the mutex
       
   879     iMutex.Signal();
       
   880     
       
   881     // Return the length of the available space in the allocated cell.
       
   882     return len;
       
   883     }
       
   884 
       
   885 // -----------------------------------------------------------------------------
       
   886 // RAnalyzeToolAllocator::DebugFunction()
       
   887 // Invocates specified debug funtionality.
       
   888 // -----------------------------------------------------------------------------
       
   889 //
       
   890 TInt RAnalyzeToolAllocator::DebugFunction( TInt aFunc, TAny* a1, TAny* a2 )
       
   891     {
       
   892     LOGSTR2( "ATMH RAnalyzeToolAllocator::DebugFunction() %i", aFunc );
       
   893     
       
   894     // Acquire the mutex
       
   895     iMutex.Wait();
       
   896     
       
   897     // Invocate debug funtion using original allocator
       
   898     TInt debug = iAllocator->DebugFunction( aFunc, a1, a2 );
       
   899     
       
   900     switch( aFunc )
       
   901 		{  
       
   902 		case EMarkEnd:
       
   903 			{
       
   904 			// Disables the __UHEAP_MARKEND macro
       
   905 			LOGSTR1( "ATMH __UHEAP_MARKEND macro called" );
       
   906 			if ( debug > 0 )
       
   907 				{
       
   908 				LOGSTR2( "ATMH __UHEAP_MARKEND detects leaks: %d", debug );
       
   909 				// Because there is leaks the alloc panic will occur but
       
   910 				// lets return a zero to pretend that everything is OK
       
   911 				debug = 0;
       
   912 				}
       
   913 			}
       
   914 		break;
       
   915 		
       
   916 		default:
       
   917 			{
       
   918 			}
       
   919 		break;
       
   920 		}
       
   921     
       
   922     // Release the mutex
       
   923     iMutex.Signal();
       
   924     
       
   925     // Return information of the debug function success
       
   926     return debug;
       
   927     }
       
   928 
       
   929 // -----------------------------------------------------------------------------
       
   930 // RAnalyzeToolAllocator::Extension_()
       
   931 // Extension function
       
   932 // -----------------------------------------------------------------------------
       
   933 //
       
   934 TInt RAnalyzeToolAllocator::Extension_( TUint aExtensionId, TAny*& a0, 
       
   935     TAny* a1 ) 
       
   936     {
       
   937     LOGSTR1( "ATMH RAnalyzeToolAllocator::Extension_()" );
       
   938     
       
   939     // Acquire the mutex
       
   940     iMutex.Wait();
       
   941     
       
   942     // Invocate extension funtion using original allocator
       
   943     TInt ext = RAllocator::Extension_( aExtensionId, a0, a1 );
       
   944     
       
   945     // Release the mutex
       
   946     iMutex.Signal();
       
   947     
       
   948     // Return information of the extension function success
       
   949     return ext;
       
   950     }
       
   951 
       
   952 // -----------------------------------------------------------------------------
       
   953 // RAnalyzeToolAllocator::ShareHeap()
       
   954 // Share heap with other thread
       
   955 // -----------------------------------------------------------------------------
       
   956 //
       
   957 void RAnalyzeToolAllocator::ShareHeap()
       
   958     {
       
   959     LOGSTR1( "ATMH RAnalyzeToolAllocator::ShareHeap()" );
       
   960     
       
   961     // Call the overwrited Open function
       
   962     Open();
       
   963     }
       
   964     
       
   965 // -----------------------------------------------------------------------------
       
   966 // RAnalyzeToolAllocator::FindCurrentThreadStack()
       
   967 // Find the current thread which is using the heap
       
   968 // -----------------------------------------------------------------------------
       
   969 //
       
   970 TBool RAnalyzeToolAllocator::FindCurrentThreadStack( TUint32& aStackStart )
       
   971     {
       
   972     LOGSTR2( "ATMH RAnalyzeToolAllocator::FindCurrentThreadStack(), count( %i )", 
       
   973             iThreadArray.Count() );
       
   974     
       
   975     // Flag for indicating that right thread has been found
       
   976     TBool found( EFalse );
       
   977     // If threre is only one thread it must be the right thread
       
   978     if ( iThreadArray.Count() == KThreadCount )
       
   979         {
       
   980         if ( !iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
       
   981             {
       
   982             // This MUST BE the right thread
       
   983             //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
       
   984             }
       
   985         else if ( iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
       
   986             {
       
   987             found = ETrue;
       
   988             }
       
   989         }
       
   990     else
       
   991         {
       
   992         // Iterate through array to find right thread
       
   993         TInt count( iThreadArray.Count() );
       
   994         
       
   995         for ( TInt i = 0; i < count; i++ )
       
   996             {
       
   997             // Check if this is the right thread
       
   998             if ( iThreadArray[ i ].ThreadStackStart( aStackStart ) )
       
   999                 {
       
  1000                 // Right thread found. Mark the flag
       
  1001                 found = ETrue;
       
  1002                 break;
       
  1003                 }
       
  1004             }
       
  1005         // If right thread was not found the panic must be raised
       
  1006         if ( !found )
       
  1007             {
       
  1008             //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
       
  1009             }
       
  1010         }
       
  1011     return found;
       
  1012     }
       
  1013 
       
  1014 // End of File