analyzetool/dynamicmemoryhook/src/analyzetoolmainallocator.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 RAnalyzeToolMainAllocator.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "analyzetoolmainallocator.h"
       
    20 #include "atlog.h"
       
    21 #include "analyzetooleventhandler.h"
       
    22 #include "analyzetoolmemoryallocator.h"
       
    23 #include "analyzetoolpanics.pan"
       
    24 #include "analyzetoolfastlog.h"
       
    25 #include <e32svr.h>
       
    26 
       
    27 
       
    28 // CONSTANTS
       
    29 
       
    30 // The name of the memoryhook dll
       
    31 _LIT8( KMemoryHook, "AToolMemoryHook.dll" );
       
    32 
       
    33 // The name of the storage server dll
       
    34 _LIT8( KStorageServer, "AToolStorageServerClnt.dll" );
       
    35 
       
    36 // Length of the callstack address
       
    37 const TUint32 KAddressLength = 4;
       
    38 
       
    39 // Thread count
       
    40 const TInt KThreadCount = 1;
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // RAnalyzeToolMainAllocator::RAnalyzeToolMainAllocator()
       
    44 // C++ default constructor can NOT contain any code, that
       
    45 // might leave.
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 RAnalyzeToolMainAllocator::RAnalyzeToolMainAllocator( TBool aNotFirst, 
       
    49     const TFileName aFileName, TUint32 aLogOption, TUint32 aIsDebug,
       
    50     TUint32 aAllocCallStackSize, TUint32 aFreeCallStackSize ) :
       
    51     RAnalyzeToolMemoryAllocator( aNotFirst ),
       
    52     iAnalyzeToolOpen( EFalse ),
       
    53     iDeviceDriverLoaded( EFalse ),
       
    54     iCodeblocks( KATMaxCallstackLength ),
       
    55     iThreadArray( KATMaxCallstackLength ),
       
    56     iLogOption( aLogOption ),
       
    57     iProcessId( RProcess().Id().operator TUint() ),
       
    58     iAllocMaxCallStack( aAllocCallStackSize ),
       
    59     iFreeMaxCallStack( aFreeCallStackSize )
       
    60     {
       
    61     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::RAnalyzeToolMainAllocator()" );
       
    62 
       
    63     // Basic error variable used in method.
       
    64     TInt error( KErrNone );
       
    65     
       
    66     // Connect to the storage server if logging mode not fast trace.
       
    67     if ( iLogOption != EATLogToTraceFast )
       
    68         {
       
    69         error = iStorageServer.Connect();
       
    70 
       
    71         LOGSTR2( "ATMH Opening RATStorageServer error %i", error );
       
    72     
       
    73         if ( KErrNone == error )
       
    74             {
       
    75             iStorageServerOpen = ETrue;
       
    76             }
       
    77         else
       
    78             {
       
    79             iStorageServerOpen = EFalse;
       
    80             }
       
    81     
       
    82         if ( KErrNone == error )
       
    83             {
       
    84             // Make the storage server handle shared between threads
       
    85             error = iStorageServer.ShareAuto();
       
    86             }
       
    87     
       
    88         LOGSTR2( "ATMH Sharing RATStorageServer error %i", error );
       
    89         }
       
    90     
       
    91     // Create mutex for schedule access to shared resources
       
    92     error = iMutex.CreateLocal();
       
    93 
       
    94     __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantCreateMutex ) );
       
    95 
       
    96     LOGSTR2( "ATMH Creating mutex error %i", error );
       
    97 
       
    98     // Load the kernel side device driver
       
    99     error = User::LoadLogicalDevice( KAnalyzeToolLddName );
       
   100 
       
   101     if ( error != KErrNone && error != KErrAlreadyExists )
       
   102         {
       
   103         __ASSERT_ALWAYS( EFalse, AssertPanic( ECantLoadDeviceDriver ) );
       
   104         }
       
   105     else
       
   106         {
       
   107         iDeviceDriverLoaded = ETrue;
       
   108         }
       
   109 
       
   110     LOGSTR2( "ATMH Loading device driver error %i", error );
       
   111 
       
   112     // Open handle to the kernel sidedevice driver
       
   113     error = iAnalyzeTool.Open();
       
   114 
       
   115     __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantConnectDeviceDriver ) );
       
   116 
       
   117     if ( KErrNone == error )
       
   118         {
       
   119         iAnalyzeToolOpen = ETrue;
       
   120         }
       
   121 
       
   122     LOGSTR2( "ATMH Opening RAnalyzeTool handle %i error", error );
       
   123 
       
   124     // Set memory model by asking kernel side device driver
       
   125     if ( iAnalyzeToolOpen )
       
   126         {
       
   127         TATMemoryModelBuf model;
       
   128         if ( KErrNone == iAnalyzeTool.GetMemoryModel( model ) )
       
   129             {
       
   130             iMemoryModel = model().iMemoryModel;
       
   131             LOGSTR2( "ATMH AnalyzeTool MemoryModel: %i", iMemoryModel );
       
   132             }
       
   133         else
       
   134             LOGSTR2( "ATMH AnalyzeTool GetMemoryModel error: %i", error );
       
   135         }
       
   136     
       
   137     // Retrieve the initial process information
       
   138     LogProcessInformation( aFileName, aLogOption, aIsDebug );
       
   139 
       
   140     // Create handler for receiving kernel events
       
   141     iEventHandler = new CLibraryEventHandler( iAnalyzeTool,
       
   142                                               iCodeblocks,
       
   143                                               iStorageServer,
       
   144                                               iProcessId,
       
   145                                               iMutex, 
       
   146                                               *this,
       
   147                                               aLogOption);
       
   148 
       
   149     __ASSERT_ALWAYS( iEventHandler != NULL, AssertPanic( ENoMemory ) );
       
   150     }
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // RAnalyzeToolMainAllocator::~RAnalyzeToolMainAllocator()
       
   154 // Destructor.
       
   155 // -----------------------------------------------------------------------------
       
   156 //
       
   157 RAnalyzeToolMainAllocator::~RAnalyzeToolMainAllocator()
       
   158     {
       
   159     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::~RAnalyzeToolMainAllocator()" );
       
   160 
       
   161     TUint handleLeakCount( 0 );
       
   162     if ( iAnalyzeToolOpen && iThreadArray.Count() > 0 )
       
   163         {
       
   164         TProcessHandleInfoBuf params;
       
   165         params().iProcessId = iProcessId;
       
   166         TInt error( iAnalyzeTool.GetProcessHandleInfo( params ) );
       
   167         handleLeakCount = params().iThreadHandleCount;
       
   168         }
       
   169 
       
   170     // Close handle for process memory blocks
       
   171     iCodeblocks.Close();
       
   172 
       
   173     // Delete the eventhandler
       
   174     delete iEventHandler;
       
   175 
       
   176     // The count of device driver users
       
   177     TClientCountBuf count;
       
   178 
       
   179     // Check the flag
       
   180     if ( iAnalyzeToolOpen )
       
   181         {
       
   182         TInt error  = iAnalyzeTool.ClientCount( count );
       
   183         LOGSTR2( "ATMH closing analyze tool handle error: %i", error );
       
   184         iAnalyzeTool.Close();
       
   185         }
       
   186 
       
   187     // Check the flag
       
   188     if ( iDeviceDriverLoaded )
       
   189         {
       
   190         LOGSTR2( "ATMH device driver client count: %i", count().iClientCount );
       
   191 
       
   192         // Check if there is another user for device driver
       
   193         if ( count().iClientCount <= 1 )
       
   194             {
       
   195             // There was no other users -> unload the device driver
       
   196             TInt error = User::FreeLogicalDevice( KAnalyzeToolLddName );
       
   197             LOGSTR2( "ATMH Unloading ldd error: %i", error );
       
   198             }
       
   199         }
       
   200     
       
   201     // Close the thread array
       
   202     iThreadArray.Close();
       
   203 
       
   204     if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
   205         {
       
   206         if ( iLogOption == EATLogToTraceFast )
       
   207             {
       
   208             LOGSTR1( "ATMH ATFastLogProcessEnded()" );
       
   209             ATFastLogProcessEnded( iProcessId, handleLeakCount );
       
   210             }
       
   211         else
       
   212             {
       
   213             iStorageServerOpen = EFalse;
       
   214             // Inform that process has ended and close the handle
       
   215             LOGSTR1( "ATMH iStorageServer.LogProcessEnded()" );
       
   216             iStorageServer.LogProcessEnded( iProcessId, handleLeakCount );
       
   217             // Close the handle
       
   218             iStorageServer.Close();
       
   219             }
       
   220         }
       
   221     
       
   222     // Close the mutex
       
   223     iMutex.Close();
       
   224     }
       
   225 
       
   226 // -----------------------------------------------------------------------------
       
   227 // RAnalyzeToolMainAllocator::ShareHeap()
       
   228 // Share heap with other thread
       
   229 // -----------------------------------------------------------------------------
       
   230 //
       
   231 void RAnalyzeToolMainAllocator::ShareHeap()
       
   232     {
       
   233     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ShareHeap()" );
       
   234 
       
   235     // Call the overwrited Open function
       
   236     Open();
       
   237     }
       
   238 
       
   239 // -----------------------------------------------------------------------------
       
   240 // RAnalyzeToolMainAllocator::Uninstall()
       
   241 // Uninstalls the current allocator
       
   242 // -----------------------------------------------------------------------------
       
   243 //
       
   244 void RAnalyzeToolMainAllocator::Uninstall()
       
   245     {
       
   246     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Uninstall()" );
       
   247 
       
   248     // Acquire the mutex
       
   249     iMutex.Wait();
       
   250     
       
   251     TMainThreadParamsBuf params;
       
   252     params().iProcessId = iProcessId;
       
   253     iAnalyzeTool.MainThreadAlloctor( params );
       
   254     
       
   255     // Release the mutex
       
   256     iMutex.Signal();
       
   257     
       
   258     // Check if this is shared allocator between threads
       
   259     if ( iThreadArray.Count() > KThreadCount && !params().iAlone )
       
   260         {
       
   261         // Close the shared allocator
       
   262         Close();
       
   263         LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Uninstall() - Close called" );
       
   264         return;
       
   265         }
       
   266 
       
   267 #if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
       
   268     #ifndef __WINS__ 
       
   269     // Remove dummy Tls handle
       
   270     UserSvr::DllFreeTls( KDummyHandle );
       
   271     #endif
       
   272 #endif
       
   273     
       
   274     // Since this is the last thread using this allocator it can be deleted
       
   275     delete this;
       
   276     }
       
   277 
       
   278 #ifdef __WINS__
       
   279 // -----------------------------------------------------------------------------
       
   280 // RAnalyzeToolMainAllocator::Alloc() WINS version
       
   281 // Allocates a cell of specified size from the heap.
       
   282 // -----------------------------------------------------------------------------
       
   283 //
       
   284 UEXPORT_C TAny* RAnalyzeToolMainAllocator::Alloc( TInt aSize )
       
   285     {
       
   286     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc()" );
       
   287 
       
   288     // Acquire the mutex
       
   289     iMutex.Wait();
       
   290 
       
   291     // Alloc memory from the original allocator
       
   292     TAny* p = iAllocator->Alloc( aSize );
       
   293 
       
   294     LOGSTR3( "ATMH RAnalyzeToolMainAllocator::Alloc() - aSize: %i, address: %x", 
       
   295             aSize,  (TUint32) p );
       
   296 
       
   297     // Don't collect or log data if storage server not open or logging mode fast.
       
   298     if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
   299         {
       
   300         TInt error( KErrNone );
       
   301         
       
   302         // Check if eventhandler is started already
       
   303         if ( !iEventHandler->IsStarted() )
       
   304             {
       
   305             // Install the eventhandler if needed
       
   306             InstallEventHandler();
       
   307             }
       
   308         
       
   309         // Reset the callstack
       
   310         iCallStack.Reset();
       
   311 
       
   312         // If we don't want any call stack to be saved skip the next part
       
   313         if( iAllocMaxCallStack > 0 )
       
   314             {
       
   315             // Find the current thread callstack start address
       
   316             TUint32 stackstart( 0 );
       
   317             TBool found( FindCurrentThreadStack( stackstart ) );
       
   318             LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   319             
       
   320             // Returns the value of the stack pointer at the 
       
   321             // current point in your program.
       
   322             TUint32 _sp;
       
   323             __asm
       
   324                 {
       
   325                 mov [_sp], esp
       
   326                 }
       
   327             
       
   328             // Get process loaded code segments count
       
   329             TInt blocksCount( iCodeblocks.Count() );
       
   330             TUint arrayCounter = 0;
       
   331             
       
   332             // Iterate through callstack to find wanted callstack addresses
       
   333             // - Start: current stack address
       
   334             // - Stop: stack start address(Run-address of user stack)
       
   335             // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)
       
   336             for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   337                 {
       
   338                 TUint32 addr = (TUint32) *( (TUint32*) i );
       
   339                 
       
   340                 // Checks is the given address in loaded code memory area.
       
   341                 if ( !IsAddressLoadedCode( addr ) )
       
   342                     continue;
       
   343                 
       
   344                 // Iterate through array of code blocks to check if address is in code segment area 
       
   345                 for ( TInt j = 0; j < blocksCount; j++ )
       
   346                     {
       
   347                     // Checks if the given address is in this memory block area
       
   348                     if ( iCodeblocks[j].CheckAddress( addr ) )
       
   349                         {
       
   350                         // To avoid recursive call to ReAlloc specifying granularity
       
   351                         // Add address to the callstack
       
   352                         iCallStack[arrayCounter] = ( addr );
       
   353                         arrayCounter++;
       
   354                         break;
       
   355                         }
       
   356                     }
       
   357                 
       
   358                 // Checks if the wanted callstack items are gathered
       
   359                 if ( arrayCounter == KATMaxCallstackLength ||
       
   360                      arrayCounter == iAllocMaxCallStack )
       
   361                     {
       
   362                     LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   363                     break;
       
   364                     }
       
   365                 } 
       
   366             }
       
   367 
       
   368         // Log the memory allocation information
       
   369         if ( iLogOption == EATLogToTraceFast )
       
   370             {
       
   371             // Using fast mode.
       
   372             ATFastLogMemoryAllocated( iProcessId, (TUint32) p , iCallStack, aSize );
       
   373             }
       
   374         else
       
   375             {
       
   376             // Using storage server.
       
   377             error = iStorageServer.LogMemoryAllocated( (TUint32) p,
       
   378                                                        iCallStack,
       
   379                                                        aSize );
       
   380             if ( KErrNone != error )
       
   381                 {
       
   382                 switch ( error )
       
   383                     {
       
   384                     case KErrNoMemory:
       
   385                         {
       
   386                         LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - KErrNoMemory case"  );
       
   387                         // Check if eventhandler is active
       
   388                         if ( iEventHandler->IsActive() )
       
   389                             {
       
   390                             // Cancel iEventHandler because not needed anymore
       
   391                             iEventHandler->Cancel();
       
   392                             }
       
   393                         if ( iStorageServerOpen )
       
   394                             {
       
   395                             // Close storage server
       
   396                             iStorageServerOpen = EFalse;
       
   397                             LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - close iStorageServer"  );
       
   398                             iStorageServer.Close();
       
   399                             }
       
   400                         break;
       
   401                         }
       
   402                     default:
       
   403                         {
       
   404                         LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
       
   405                         break;
       
   406                         }
       
   407                     }
       
   408                 }
       
   409             }
       
   410         }
       
   411     // Release the mutex
       
   412     iMutex.Signal();
       
   413 
       
   414     return p;
       
   415     }
       
   416 #else
       
   417 
       
   418 // -----------------------------------------------------------------------------
       
   419 // RAnalyzeToolMainAllocator::Alloc() ARMV5 version
       
   420 // Allocates a cell of specified size from the heap.
       
   421 // -----------------------------------------------------------------------------
       
   422 //
       
   423 TAny* RAnalyzeToolMainAllocator::Alloc( TInt aSize )
       
   424     {
       
   425     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc()"  );
       
   426 
       
   427     // acquire the mutex
       
   428     iMutex.Wait();
       
   429 
       
   430     // Alloc memory from the original allocator
       
   431     TAny* p = iAllocator->Alloc( aSize );
       
   432 
       
   433     LOGSTR3( "ATMH RAnalyzeToolMainAllocator::Alloc() - aSize: %i, address: %x", 
       
   434             aSize,  (TUint32) p );
       
   435 
       
   436     TInt error( KErrNone );
       
   437     
       
   438     if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
   439         {
       
   440         // Check if eventhandler is active already
       
   441         // IsActive might return false value if a tested software has created many
       
   442         // threads which install own CActiveScheduler.
       
   443         if ( !iEventHandler->IsStarted() )
       
   444             {
       
   445             // Install the eventhandler if needed
       
   446             InstallEventHandler();
       
   447             }
       
   448         
       
   449         // Reset the callstack
       
   450         iCallStack.Reset();
       
   451         
       
   452         // If we don't want any call stack to be saved skip the next part
       
   453         if( iAllocMaxCallStack > 0 )
       
   454             {
       
   455             // Find the current thread callstack start address
       
   456             TUint32 stackstart( 0 );
       
   457             TBool found( FindCurrentThreadStack( stackstart ) );
       
   458             LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   459             
       
   460             // Get process loaded code segments count
       
   461             TInt blocksCount( iCodeblocks.Count() );            
       
   462             TUint arrayCounter = 0;
       
   463             
       
   464             // Iterate through callstack to find wanted callstack addresses
       
   465             // - Start: current stack address(__current_sp(): Returns the value of the 
       
   466             //      stack pointer at the current point in your program.)
       
   467             // - Stop: stack start address(Run-address of user stack)
       
   468             // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)
       
   469             for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   470                 {
       
   471                 TUint32 addr = (TUint32) *( (TUint32*) i );
       
   472                 
       
   473                 // Checks is the given address in loaded code memory area.
       
   474                 if ( !IsAddressLoadedCode( addr ) )
       
   475                     continue;
       
   476                 
       
   477                 // Iterate through array of code blocks to check if address is in code segment area 
       
   478                 for ( TInt j = 0; j < blocksCount; j++ )
       
   479                     {
       
   480                     // Checks if the given address is in this memory block area
       
   481                     if ( iCodeblocks[j].CheckAddress( addr ) )
       
   482                         {
       
   483                         // To avoid recursive call to ReAlloc specifying granularity
       
   484                         // Add address to the callstack
       
   485                         iCallStack[arrayCounter] = ( addr );
       
   486                         arrayCounter++;
       
   487                         break;
       
   488                         }
       
   489                     }
       
   490                 
       
   491                 // Checks if the wanted callstack items are gathered
       
   492                 if ( arrayCounter == KATMaxCallstackLength ||
       
   493                      arrayCounter == iAllocMaxCallStack )
       
   494                     {
       
   495                     LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   496                     break;
       
   497                     }
       
   498                 }
       
   499             }
       
   500         // Log the memory allocation information
       
   501         if ( iLogOption == EATLogToTraceFast )
       
   502             {
       
   503             // Using fast mode.
       
   504             ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize );
       
   505             }
       
   506         else
       
   507             {
       
   508             // Using storage server.
       
   509             error = iStorageServer.LogMemoryAllocated( (TUint32) p,
       
   510                                                        iCallStack,
       
   511                                                        aSize );
       
   512             if ( KErrNone != error )
       
   513                 {
       
   514                 switch ( error )
       
   515                     {
       
   516                     case KErrNoMemory:
       
   517                         {
       
   518                         LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - KErrNoMemory case"  );
       
   519                         // Check if eventhandler is active
       
   520                         if ( iEventHandler->IsActive() )
       
   521                             {
       
   522                             // Cancel ieventhandler because not needed anymore
       
   523                             iEventHandler->Cancel();
       
   524                             }
       
   525                         if ( iStorageServerOpen )
       
   526                             {
       
   527                             // Close storage server
       
   528                             iStorageServerOpen = EFalse;
       
   529                             LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - close iStorageServer"  );
       
   530                             iStorageServer.Close();
       
   531                             }
       
   532                         break;
       
   533                         }
       
   534                     default:
       
   535                         {
       
   536                         LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
       
   537                         break;
       
   538                         }
       
   539                     }
       
   540                 }
       
   541             }
       
   542         }
       
   543     
       
   544     // Release the mutex
       
   545     iMutex.Signal();
       
   546 
       
   547     // Return the allocatated memory
       
   548     return p;
       
   549     }
       
   550 #endif // __WINS__
       
   551 
       
   552 // -----------------------------------------------------------------------------
       
   553 // RAnalyzeToolMainAllocator::Free()
       
   554 // Frees the allocated memory
       
   555 // -----------------------------------------------------------------------------
       
   556 //
       
   557 void RAnalyzeToolMainAllocator::Free( TAny* aPtr )
       
   558     {
       
   559     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Free()" );
       
   560 
       
   561     // Acquire the mutex
       
   562     iMutex.Wait();
       
   563     
       
   564     if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
   565         {
       
   566         // Reset the callstack
       
   567         iFreeCallStack.Reset();
       
   568         
       
   569         // Check if trace logging mode
       
   570         // Also if we don't want any call stack to be stored skip the next part
       
   571         if ( (iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
       
   572                 && iFreeMaxCallStack > 0 )
       
   573             {
       
   574             // Find the current thread callstack start address
       
   575             TUint32 stackstart( 0 );
       
   576             TBool found( FindCurrentThreadStack( stackstart ) );
       
   577             LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   578             TUint32 _sp;
       
   579             
       
   580             // Returns the value of the stack pointer at the 
       
   581             // current point in your program.
       
   582             #ifdef __WINS__
       
   583                 __asm
       
   584                     {
       
   585                     mov [_sp], esp
       
   586                     }
       
   587             #else
       
   588                 _sp = __current_sp();
       
   589             #endif
       
   590             
       
   591             // Get process loaded code segments count
       
   592             TInt blocksCount( iCodeblocks.Count() );
       
   593             TUint arrayCounter = 0;
       
   594             
       
   595             // Iterate through callstack to find wanted callstack addresses
       
   596             // - Start: current stack address
       
   597             // - Stop: stack start address(Run-address of user stack)
       
   598             // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)            
       
   599             for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   600                 {
       
   601                 TUint32 addr = (TUint32) *( (TUint32*) i );
       
   602                 // Checks is the given address in loaded code memory area.
       
   603                 if ( ! IsAddressLoadedCode( addr ) )
       
   604                     continue;
       
   605                 
       
   606                 // Iterate through array of code blocks to check if address is in code segment area 
       
   607                 for ( TInt j = 0; j < blocksCount; j++ )
       
   608                     {
       
   609                     // Checks if the given address is in this memory block area
       
   610                     if ( iCodeblocks[j].CheckAddress( addr ) )
       
   611                         {
       
   612                         // To avoid recursive call to ReAlloc specifying granularity
       
   613                         // Add address to the callstack
       
   614                         iFreeCallStack[arrayCounter] = addr;
       
   615                         arrayCounter++;
       
   616                         break;
       
   617                         }
       
   618                     }
       
   619                 // Checks if the wanted callstack items are gathered
       
   620                 if ( arrayCounter == KATMaxFreeCallstackLength ||
       
   621                      arrayCounter == iFreeMaxCallStack )
       
   622                     {
       
   623                     break;
       
   624                     }
       
   625                 }
       
   626             LOGSTR2( "ATMH > iFreeCallStack count ( %i )", arrayCounter );
       
   627             }
       
   628         // Log the memory free information.
       
   629         if ( iLogOption == EATLogToTraceFast )
       
   630             {
       
   631             // Using fast mode.
       
   632             ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
       
   633             }
       
   634         else
       
   635             {
       
   636             // Using storage server.
       
   637             TInt err( iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack ) );
       
   638             if ( err != KErrNone )
       
   639                 {
       
   640                 LOGSTR2( "ATMH > LogMemoryFreed err( %i )", err );
       
   641                 }
       
   642             }
       
   643         }
       
   644     
       
   645     // Free the memory using original allocator
       
   646     iAllocator->Free( aPtr );
       
   647 
       
   648     LOGSTR2( "ATMH RAnalyzeToolMainAllocator::Free() - aPtr: %x", (TUint32)aPtr );
       
   649 
       
   650     // Release the mutex
       
   651     iMutex.Signal();
       
   652     }
       
   653 
       
   654 // -----------------------------------------------------------------------------
       
   655 // RAnalyzeToolMainAllocator::Open()
       
   656 // Opens this heap for shared access. Opening the heap increases
       
   657 // the heap's access count by one.
       
   658 // -----------------------------------------------------------------------------
       
   659 //
       
   660 TInt RAnalyzeToolMainAllocator::Open()
       
   661     {
       
   662     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Open() " );
       
   663 
       
   664     // Acquire the mutex
       
   665     iMutex.Wait();
       
   666 
       
   667     // Share the memory using original allocator
       
   668     TInt error = iAllocator->Open();
       
   669 
       
   670     // If everything is OK add thread to the array which use this allocator
       
   671     if ( KErrNone == error )
       
   672         {
       
   673         TThreadParamsBuf params;
       
   674         params().iThreadId = RThread().Id().operator TUint();
       
   675         error = iAnalyzeTool.ThreadStack( params );
       
   676 
       
   677         __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
       
   678 
       
   679         if ( KErrNone == error )
       
   680             {
       
   681             LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
       
   682             LOGSTR2( "ATMH Thread stack size:    %x", params().iStackSize );
       
   683             iThreadArray.Append( TThreadStack( RThread().Id(),
       
   684                     params().iStackAddress + params().iStackSize ) );
       
   685             }
       
   686         }
       
   687 
       
   688     // Release the mutex
       
   689     iMutex.Signal();
       
   690 
       
   691     // Return the error code
       
   692     return error;
       
   693     }
       
   694 
       
   695 // -----------------------------------------------------------------------------
       
   696 // RAnalyzeToolMainAllocator::Close()
       
   697 // Closes this shared heap. Closing the heap decreases the heap's
       
   698 // access count by one.
       
   699 // -----------------------------------------------------------------------------
       
   700 //
       
   701 void RAnalyzeToolMainAllocator::Close()
       
   702     {
       
   703     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close()" );
       
   704 
       
   705     // Acquire the mutex
       
   706     iMutex.Wait();
       
   707 
       
   708     // Close the memory using original allocator
       
   709     iAllocator->Close();
       
   710     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close() - allocator closed" );
       
   711     TInt count = iThreadArray.Count();
       
   712 
       
   713     // Iterate through array of threads to remove current thread
       
   714     for ( TInt i = 0; i < count; i++ )
       
   715         {
       
   716         // Check if this is current thread
       
   717         if ( iThreadArray[ i ].Match() )
       
   718             {
       
   719             // Remove the thread
       
   720             iThreadArray.Remove( i );
       
   721             LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close() - thread removed" );
       
   722             break;
       
   723             }
       
   724         }
       
   725     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close() - about to mutex signal" );
       
   726     // Release the mutex
       
   727     iMutex.Signal();
       
   728     }
       
   729 
       
   730 #ifdef __WINS__
       
   731 
       
   732 // -----------------------------------------------------------------------------
       
   733 // RAnalyzeToolMainAllocator::ReAlloc()
       
   734 // Increases or decreases the size of an existing cell.
       
   735 // -----------------------------------------------------------------------------
       
   736 //
       
   737 TAny* RAnalyzeToolMainAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
       
   738     {
       
   739     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc()" );
       
   740 
       
   741     // Acquire the mutex
       
   742     iMutex.Wait();
       
   743 
       
   744     // Realloc the memory using original allocator
       
   745     TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
       
   746     
       
   747     // NULL addresses are not in a process under test
       
   748     if ( ptr && !( aMode & ENeverMove ) )
       
   749         {
       
   750         LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
       
   751                 (TUint32)aPtr, (TUint32)ptr );
       
   752         LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aSize: %i, aMode: %i", 
       
   753                 aSize, aMode );
       
   754       
       
   755         // Don't collect or log data if storage server not open or logging mode is not fast.
       
   756         if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
   757             {
       
   758             TInt error( KErrNone );
       
   759             TUint arrayCounter = 0;
       
   760             
       
   761             // Reset the callstack
       
   762             iReCallStack.Reset();
       
   763             
       
   764             // If we don't want any call stack to be saved skip the next part
       
   765             if( iAllocMaxCallStack > 0 )
       
   766                 {
       
   767                 // Find the current thread callstack start address
       
   768                 TUint32 stackstart( 0 );
       
   769                 TBool found( FindCurrentThreadStack( stackstart ) );
       
   770                 LOGSTR3( "ATMH > stackstart: %x , find = %i", stackstart, found );
       
   771     
       
   772                 // Returns the value of the stack pointer at the 
       
   773                 // current point in your program.
       
   774                 TUint32 _sp( 0 );
       
   775                 __asm
       
   776                     {
       
   777                     mov [_sp], esp
       
   778                     }
       
   779                 
       
   780                 // Get process loaded code segments count
       
   781                 TInt blocksCount( iCodeblocks.Count() );
       
   782                 
       
   783                 // Iterate through callstack to find wanted callstack addresses
       
   784                 // - Start: current stack address
       
   785                 // - Stop: stack start address(Run-address of user stack)
       
   786                 // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)                
       
   787                 for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   788                     {
       
   789                     TUint32 addr = (TUint32) *( (TUint32*) i );
       
   790                     // Checks is the given address in loaded code memory area.
       
   791                     if ( ! IsAddressLoadedCode( addr ) )
       
   792                         continue;
       
   793                     
       
   794                     // Iterate through array of code blocks to check if address is in code segment area 
       
   795                     for ( TInt j = 0; j < blocksCount; j++ )
       
   796                         {
       
   797                         // Checks if the given address is in this memory block area
       
   798                         if ( iCodeblocks[j].CheckAddress( addr ) )
       
   799                             {
       
   800                             // To avoid recursive call to ReAlloc specifying granularity
       
   801                             // Add address to the callstack
       
   802                             iReCallStack[arrayCounter] = addr;
       
   803                             arrayCounter++;
       
   804                             break;
       
   805                             }
       
   806                         }
       
   807                     // Checks if the wanted callstack items are gathered
       
   808                     if ( arrayCounter == KATMaxCallstackLength || 
       
   809                          arrayCounter == iAllocMaxCallStack )
       
   810                         {
       
   811                         LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   812                         break;
       
   813                         }
       
   814                     }
       
   815                 }
       
   816             
       
   817             // No need to report free if the aPtr was NULL
       
   818             if ( aPtr != NULL )
       
   819                 {
       
   820                 // Reset the free callstack
       
   821                 iFreeCallStack.Reset();
       
   822                 
       
   823                 // Check that logging mode is trace/trace fast so we use free call stack 
       
   824                 // and call stack size bigger than zero
       
   825                 if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast ) && iFreeMaxCallStack > 0 )
       
   826                     {
       
   827                     for ( TInt i = 0; i < arrayCounter; i++ )
       
   828                         {
       
   829                         if ( i == KATMaxFreeCallstackLength || i == iFreeMaxCallStack )
       
   830                             {
       
   831                             break;
       
   832                             }
       
   833                         iFreeCallStack[i] = iReCallStack[i];
       
   834                         }
       
   835                     }
       
   836                 // Try to remove old address from the storage server's
       
   837                 // leak array. If found. it's removed from the array because system frees
       
   838                 // old address directly in the RHeap in ReAlloc case.
       
   839                 if ( iLogOption == EATLogToTraceFast )
       
   840                     {
       
   841                     ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
       
   842                     }
       
   843                 else
       
   844                     {
       
   845                     iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
       
   846                     }
       
   847                 }
       
   848             // Log the memory allocation information
       
   849             if ( iLogOption == EATLogToTraceFast )
       
   850                 {
       
   851                 // Using fast logging mode.
       
   852                 ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iReCallStack, aSize );
       
   853                 }
       
   854             else
       
   855                 {
       
   856                 // Using storage server.
       
   857                 error = iStorageServer.LogMemoryAllocated( (TUint32) ptr,
       
   858                                                            iReCallStack,
       
   859                                                            aSize );
       
   860                 if ( KErrNone != error )
       
   861                     {
       
   862                     switch ( error )
       
   863                         {
       
   864                         case KErrNoMemory:
       
   865                             {
       
   866                             LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - KErrNoMemory case"  );
       
   867                             // Check if eventhandler is active
       
   868                             if ( iEventHandler->IsActive() )
       
   869                                 {
       
   870                                 // Cancel iEventHandler because not needed anymore
       
   871                                 iEventHandler->Cancel();
       
   872                                 }
       
   873                             if ( iStorageServerOpen )
       
   874                                 {
       
   875                                 // Close storage server
       
   876                                 iStorageServerOpen = EFalse;
       
   877                                 LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - close iStorageServer"  );
       
   878                                 iStorageServer.Close();
       
   879                                 }
       
   880                             break;
       
   881                             }
       
   882                         default:
       
   883                             {
       
   884                             LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
       
   885                             break;
       
   886                             }
       
   887                         }
       
   888                     }
       
   889                 }
       
   890             }
       
   891         }
       
   892     
       
   893     // Release the mutex
       
   894     iMutex.Signal();
       
   895 
       
   896     // Return pointer to the reallocated cell
       
   897     return ptr;
       
   898     }
       
   899 
       
   900 #else
       
   901 
       
   902 // -----------------------------------------------------------------------------
       
   903 // RAnalyzeToolMainAllocator::ReAlloc()
       
   904 // Increases or decreases the size of an existing cell.
       
   905 // -----------------------------------------------------------------------------
       
   906 //
       
   907 TAny* RAnalyzeToolMainAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
       
   908     {
       
   909     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc()" );
       
   910 
       
   911     // Acquire the mutex
       
   912     iMutex.Wait();
       
   913 
       
   914     // Realloc the memory using original allocator
       
   915     TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
       
   916     
       
   917     TInt error( KErrNone );
       
   918     TUint arrayCounter = 0;
       
   919     
       
   920     // NULL addresses are not in a process under test
       
   921     if ( ptr && !( aMode & ENeverMove ) )
       
   922         {
       
   923         LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
       
   924                 (TUint32)aPtr, (TUint32)ptr );
       
   925         LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aSize: %i, aMode: %i", 
       
   926                 aSize, aMode );
       
   927  
       
   928         // Don't collect or log data if storage server not open or logging mode is not fast.
       
   929         if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
   930             {
       
   931             // Reset the callstack
       
   932             iReCallStack.Reset();
       
   933             
       
   934             // If we don't want any call stack to be saved skip the next part
       
   935             if( iAllocMaxCallStack > 0 )
       
   936                 {
       
   937                 // Find the current thread callstack start address
       
   938                 TUint32 stackstart( 0 );
       
   939                 TBool found( FindCurrentThreadStack( stackstart ) );
       
   940                 LOGSTR3( "ATMH > stackstart: %x , find = %i", stackstart, found );
       
   941                 
       
   942                 // Get process loaded code segments count
       
   943                 TInt blocksCount( iCodeblocks.Count() );
       
   944                 
       
   945                 // Iterate through callstack to find wanted callstack addresses
       
   946                 // - Start: current stack address(__current_sp(): Returns the value of the 
       
   947                 //      stack pointer at the current point in your program.)
       
   948                 // - Stop: stack start address(Run-address of user stack)
       
   949                 // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)
       
   950                 for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   951                     {
       
   952                     TUint32 addr = (TUint32) *( (TUint32*) i );
       
   953                     
       
   954                     // Checks is the given address in loaded code memory area.
       
   955                     if ( !IsAddressLoadedCode( addr ) )
       
   956                         continue;
       
   957                                 
       
   958                     // Iterate through array of code blocks to check if address is in code segment area 
       
   959                     for ( TInt j = 0; j < blocksCount; j++ )
       
   960                         {
       
   961                         // Checks if the given address is in this memory block area
       
   962                         if ( iCodeblocks[j].CheckAddress( addr ) )
       
   963                             {
       
   964                             // To avoid recursive call to ReAlloc specifying granularity
       
   965                             // Add address to the callstack
       
   966                             iReCallStack[arrayCounter] = ( addr );
       
   967                             arrayCounter++;
       
   968                             break;
       
   969                             }
       
   970                         }
       
   971                     // Checks if the wanted callstack items are gathered
       
   972                     if ( arrayCounter == KATMaxCallstackLength || 
       
   973                          arrayCounter == iAllocMaxCallStack )
       
   974                         {
       
   975                         LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   976                         break;
       
   977                         }
       
   978                     }
       
   979                 }
       
   980             
       
   981             // No need to report free if the aPtr was NULL
       
   982             if ( aPtr != NULL )
       
   983                 {
       
   984                 // Reset the free callstack
       
   985                 iFreeCallStack.Reset();
       
   986                 
       
   987                 // Check that logging mode is trace/trace fast so we use free call stack 
       
   988                 // and call stack size bigger than zero
       
   989                 if ( (iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
       
   990                         && iFreeMaxCallStack > 0 )
       
   991                     {
       
   992                     for ( TInt i = 0; i < arrayCounter; i++ )
       
   993                         {
       
   994                         if ( i == KATMaxFreeCallstackLength || i == iFreeMaxCallStack )
       
   995                             {
       
   996                             break;
       
   997                             }
       
   998                         iFreeCallStack[i] = ( iReCallStack[i] );
       
   999                         }
       
  1000                     }
       
  1001                 
       
  1002                 // Try to remove old address from the storage server's
       
  1003                 // leak array. If found. it's removed from the array because system frees
       
  1004                 // old address directly in the RHeap in ReAlloc case.
       
  1005                 if ( iLogOption == EATLogToTraceFast )
       
  1006                     {
       
  1007                     ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
       
  1008                     }
       
  1009                 else
       
  1010                     {
       
  1011                     iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
       
  1012                     }
       
  1013                 }
       
  1014             
       
  1015             // Log the memory allocation information
       
  1016             if ( iLogOption == EATLogToTraceFast )
       
  1017                 {
       
  1018                 // Using fast logging mode.
       
  1019                 ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iReCallStack, aSize );
       
  1020                 }
       
  1021             else
       
  1022                 {
       
  1023                 // Using storage server.
       
  1024                 error = iStorageServer.LogMemoryAllocated( (TUint32) ptr,
       
  1025                                                         iReCallStack,
       
  1026                                                         aSize );
       
  1027                 if ( KErrNone != error )
       
  1028                     {
       
  1029                     switch ( error )
       
  1030                         {
       
  1031                         case KErrNoMemory:
       
  1032                             {
       
  1033                             LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - KErrNoMemory case"  );
       
  1034                             // Check if eventhandler is active
       
  1035                             if ( iEventHandler->IsActive() )
       
  1036                                 {
       
  1037                                 // Cancel iEventHandler because not needed anymore
       
  1038                                 iEventHandler->Cancel();
       
  1039                                 }
       
  1040                             if ( iStorageServerOpen )
       
  1041                                 {
       
  1042                                 // Close storage server
       
  1043                                 iStorageServerOpen = EFalse;
       
  1044                                 LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - close iStorageServer"  );
       
  1045                                 iStorageServer.Close();
       
  1046                                 }
       
  1047                             break;
       
  1048                             }
       
  1049                         default:
       
  1050                             {
       
  1051                             LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
       
  1052                             break;
       
  1053                             }
       
  1054                         }
       
  1055                     }
       
  1056                 }
       
  1057             }
       
  1058         }
       
  1059 
       
  1060     // Release the mutex
       
  1061     iMutex.Signal();
       
  1062 
       
  1063     // Return pointer to the reallocated cell
       
  1064     return ptr;
       
  1065     }
       
  1066 
       
  1067 #endif // __WINS__
       
  1068 
       
  1069 // -----------------------------------------------------------------------------
       
  1070 // RAnalyzeToolMainAllocator::Compress()
       
  1071 // The function frees excess committed space from the top of the heap.
       
  1072 // The size of the heap is never reduced below the minimum size
       
  1073 // specified during creation of the heap.
       
  1074 // -----------------------------------------------------------------------------
       
  1075 //
       
  1076 TInt RAnalyzeToolMainAllocator::Compress()
       
  1077     {
       
  1078     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Compress()" );
       
  1079 
       
  1080     // Acquire the mutex
       
  1081     iMutex.Wait();
       
  1082 
       
  1083     // Compress the memory using original allocator
       
  1084     TInt compress = iAllocator->Compress();
       
  1085 
       
  1086     // Release the mutex
       
  1087     iMutex.Signal();
       
  1088 
       
  1089     // Return the space reclaimed
       
  1090     return compress;
       
  1091     }
       
  1092 
       
  1093 // -----------------------------------------------------------------------------
       
  1094 // RAnalyzeToolMainAllocator::Reset()
       
  1095 // Frees all allocated cells on this heap.
       
  1096 // -----------------------------------------------------------------------------
       
  1097 //
       
  1098 void RAnalyzeToolMainAllocator::Reset()
       
  1099     {
       
  1100     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Reset()" );
       
  1101 
       
  1102     // Acquire the mutex
       
  1103     iMutex.Wait();
       
  1104 
       
  1105     // Reset the memory using original allocator
       
  1106     iAllocator->Reset();
       
  1107 
       
  1108     // Release the mutex
       
  1109     iMutex.Signal();
       
  1110     }
       
  1111 
       
  1112 // -----------------------------------------------------------------------------
       
  1113 // RAnalyzeToolMainAllocator::AllocSize()
       
  1114 // Gets the number of cells allocated on this heap, and
       
  1115 // the total space allocated to them.
       
  1116 // -----------------------------------------------------------------------------
       
  1117 //
       
  1118 TInt RAnalyzeToolMainAllocator::AllocSize( TInt& aTotalAllocSize ) const
       
  1119     {
       
  1120     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::AllocSize()" );
       
  1121     
       
  1122     // Acquire the mutex
       
  1123     iMutex.Wait();
       
  1124     
       
  1125     // Acquire the memory information using original allocator
       
  1126     TInt size = iAllocator->AllocSize( aTotalAllocSize );
       
  1127     
       
  1128     // Release the mutex
       
  1129     iMutex.Signal();
       
  1130     
       
  1131     // Return the number of cells allocated on this heap.
       
  1132     return size;
       
  1133     }
       
  1134 
       
  1135 // -----------------------------------------------------------------------------
       
  1136 // RAnalyzeToolMainAllocator::Available()
       
  1137 // Gets the total free space currently available on the heap and the
       
  1138 // space available in the largest free block. The space available
       
  1139 // represents the total space which can be allocated. Note that
       
  1140 // compressing the heap may reduce the total free space available
       
  1141 // and the space available in the largest free block.
       
  1142 // -----------------------------------------------------------------------------
       
  1143 //
       
  1144 TInt RAnalyzeToolMainAllocator::Available( TInt& aBiggestBlock ) const
       
  1145     {
       
  1146     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Available()" );
       
  1147     
       
  1148     // Acquire the mutex
       
  1149     iMutex.Wait();
       
  1150     
       
  1151     // Acquire the memory information using original allocator
       
  1152     TInt available = iAllocator->Available( aBiggestBlock );
       
  1153     
       
  1154     // Release the mutex
       
  1155     iMutex.Signal();
       
  1156     
       
  1157     // Return the total free space currently available on the heap
       
  1158     return available;
       
  1159     }
       
  1160 
       
  1161 // -----------------------------------------------------------------------------
       
  1162 // RAnalyzeToolMainAllocator::AllocLen()
       
  1163 // Gets the length of the available space in the specified
       
  1164 // allocated cell.
       
  1165 // -----------------------------------------------------------------------------
       
  1166 //
       
  1167 TInt RAnalyzeToolMainAllocator::AllocLen( const TAny* aCell ) const
       
  1168     {
       
  1169     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::AllocLen()" );
       
  1170     
       
  1171     // Acquire the mutex
       
  1172     iMutex.Wait();
       
  1173     
       
  1174     // Acquire the memory information using original allocator
       
  1175     TInt len = iAllocator->AllocLen( aCell );
       
  1176     
       
  1177     // Release the mutex
       
  1178     iMutex.Signal();
       
  1179     
       
  1180     // Return the length of the available space in the allocated cell.
       
  1181     return len;
       
  1182     }
       
  1183 
       
  1184 // -----------------------------------------------------------------------------
       
  1185 // RAnalyzeToolMainAllocator::DebugFunction()
       
  1186 // Invocates specified debug funtionality.
       
  1187 // -----------------------------------------------------------------------------
       
  1188 //
       
  1189 TInt RAnalyzeToolMainAllocator::DebugFunction( TInt aFunc, TAny* a1, TAny* a2 )
       
  1190     {
       
  1191     LOGSTR2( "ATMH RAnalyzeToolMainAllocator::DebugFunction() %i", aFunc );
       
  1192     
       
  1193     // Acquire the mutex
       
  1194     iMutex.Wait();
       
  1195     
       
  1196     // Invocate debug funtion using original allocator
       
  1197     TInt debug = iAllocator->DebugFunction( aFunc, a1, a2 );
       
  1198     
       
  1199     switch( aFunc )
       
  1200         {  
       
  1201         case EMarkEnd:
       
  1202             {
       
  1203             // Disables the __UHEAP_MARKEND macro
       
  1204             LOGSTR1( "ATMH __UHEAP_MARKEND macro called" );
       
  1205             if ( debug > 0 )
       
  1206                 {
       
  1207                 LOGSTR2( "ATMH __UHEAP_MARKEND detects leaks: %d", debug );
       
  1208                 // Because there is leaks the alloc panic will occur but
       
  1209                 // lets return a zero to pretend that everything is OK
       
  1210                 debug = 0;
       
  1211                 }
       
  1212             }
       
  1213         break;
       
  1214         
       
  1215         default:
       
  1216             {
       
  1217             }
       
  1218         break;
       
  1219         }
       
  1220     
       
  1221     // Release the mutex
       
  1222     iMutex.Signal();
       
  1223     
       
  1224     // Return information of the debug function success
       
  1225     return debug;
       
  1226     }
       
  1227 
       
  1228 // -----------------------------------------------------------------------------
       
  1229 // RAnalyzeToolMainAllocator::RemoveKilledThread()
       
  1230 // Remove killed thread from threads array.
       
  1231 // -----------------------------------------------------------------------------
       
  1232 //
       
  1233 void RAnalyzeToolMainAllocator::RemoveKilledThread( const TUint aThreadId  )
       
  1234     {
       
  1235     LOGSTR2( "ATMH RAnalyzeToolMainAllocator::RemoveKilledThread(%i)", 
       
  1236             aThreadId );
       
  1237     
       
  1238     // Acquire the mutex
       
  1239     iMutex.Wait();
       
  1240     
       
  1241     // Iterate through array of threads to remove current thread
       
  1242     TInt count( iThreadArray.Count() );
       
  1243     LOGSTR2( "ATMH > iThreadArray.Count() %i", count );
       
  1244     
       
  1245     for ( TInt i = 0; i < count; i++ )
       
  1246         {
       
  1247         // Check if this is current thread
       
  1248         if ( iThreadArray[ i ].Match( aThreadId ) )
       
  1249             {
       
  1250             // Remove the thread
       
  1251             iThreadArray.Remove( i );
       
  1252             LOGSTR1( "ATMH > thread removed" );
       
  1253             break;
       
  1254             }
       
  1255         }
       
  1256 
       
  1257     // Release the mutex
       
  1258     iMutex.Signal();
       
  1259     }
       
  1260 // -----------------------------------------------------------------------------
       
  1261 // RAnalyzeToolMainAllocator::Extension_()
       
  1262 // Extension function
       
  1263 // -----------------------------------------------------------------------------
       
  1264 //
       
  1265 TInt RAnalyzeToolMainAllocator::Extension_( TUint aExtensionId, TAny*& a0,
       
  1266     TAny* a1)
       
  1267     {
       
  1268     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Extension_()" );
       
  1269     
       
  1270     // Acquire the mutex
       
  1271     iMutex.Wait();
       
  1272     
       
  1273     // Invocate extension funtion using original allocator
       
  1274     TInt ext = RAllocator::Extension_( aExtensionId, a0, a1 );
       
  1275     
       
  1276     // Release the mutex
       
  1277     iMutex.Signal();
       
  1278     
       
  1279     // Return information of the extension function success
       
  1280     return ext;
       
  1281     }
       
  1282 
       
  1283 // -----------------------------------------------------------------------------
       
  1284 // RAnalyzeToolMainAllocator::LogProcessInformation()
       
  1285 // Retrieve and log the process initial information
       
  1286 // -----------------------------------------------------------------------------
       
  1287 //
       
  1288 void RAnalyzeToolMainAllocator::LogProcessInformation( const TFileName aFileName,
       
  1289     TUint32 aLogOption, TUint32 aIsDebug )
       
  1290     {
       
  1291     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation()" );
       
  1292     
       
  1293     // Create local variable and retrieve the process information
       
  1294     TProcessIdentityParamsBuf params;
       
  1295     params().iProcessId = iProcessId;
       
  1296     params().iThreadId = RThread().Id().operator TUint();
       
  1297     TInt error = iAnalyzeTool.GetProcessInfo( params );
       
  1298     
       
  1299     LOGSTR2( "ATMH GetProcessInfo %i error", error );
       
  1300     
       
  1301     if ( KErrNone == error )
       
  1302         {
       
  1303         LOGSTR2( "ATMH Process %i", iProcessId );
       
  1304 
       
  1305         // Store stack start address
       
  1306         LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
       
  1307         LOGSTR2( "ATMH Thread stack size:    %x", params().iStackSize );
       
  1308 
       
  1309         // Append thread to array of the users of this allocator
       
  1310         error = iThreadArray.Append(
       
  1311         TThreadStack( RThread().Id(), params().iStackAddress + params().iStackSize) );
       
  1312 
       
  1313         __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
       
  1314 
       
  1315         // Log process information
       
  1316         if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
  1317             {
       
  1318             if ( iLogOption == EATLogToTraceFast )
       
  1319                 {
       
  1320                 // Using fast logging mode.
       
  1321                 LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - ATFastLogProcessStarted() #1" );
       
  1322                 ATFastLogProcessStarted( params().iProcessName, iProcessId, aIsDebug );                
       
  1323                 }
       
  1324             else
       
  1325                 {
       
  1326                 // Using storage server.
       
  1327                 LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - iStorageServerOpen #1" );
       
  1328                 error = iStorageServer.LogProcessStarted(
       
  1329                         aFileName,
       
  1330                         params().iProcessName,
       
  1331                         iProcessId, 
       
  1332                         aLogOption, 
       
  1333                         aIsDebug );
       
  1334                 }
       
  1335             }
       
  1336 
       
  1337         LOGSTR2( "ATMH LogProcessStarted error %i", error );
       
  1338 
       
  1339         // Iterate through process codesegments
       
  1340         for( TInt i = 0; i < params().iCodesegCount; i++ )
       
  1341             {
       
  1342             // Create local variable and retrieve codesegment info
       
  1343             TCodesegInfoBuf codeinfo;
       
  1344             codeinfo().iProcessId = iProcessId;
       
  1345             codeinfo().iIndex = i;
       
  1346             error = iAnalyzeTool.GetCodesegInfo( codeinfo );
       
  1347 
       
  1348             LOGSTR2( "ATMH GetCodesegInfo error %i", error );
       
  1349             if ( KErrNone == error )
       
  1350                 {
       
  1351                 // Don't log AnalyzeTool libraries
       
  1352                 if ( 0 != codeinfo().iFullName.CompareC( KMemoryHook ) &&
       
  1353                      0 != codeinfo().iFullName.CompareC( KStorageServer ) )
       
  1354                     {
       
  1355                     // Log the loaded codesegment(s)
       
  1356                     if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
  1357                         {
       
  1358                         if ( iLogOption == EATLogToTraceFast )
       
  1359                             {
       
  1360                             // Using fast logging mode.
       
  1361                             LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - ATFastLogDllLoaded() #2" );
       
  1362                             ATFastLogDllLoaded( iProcessId,
       
  1363                                     codeinfo().iFullName,
       
  1364                                     codeinfo().iRunAddress,
       
  1365                                     codeinfo().iRunAddress + codeinfo().iSize );
       
  1366                             }
       
  1367                         else
       
  1368                             {
       
  1369                             // Using storage server.
       
  1370                             LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - iStorageServerOpen #2" );
       
  1371                             error = iStorageServer.LogDllLoaded(
       
  1372                                     codeinfo().iFullName,
       
  1373                                     codeinfo().iRunAddress,
       
  1374                                     codeinfo().iRunAddress + codeinfo().iSize );
       
  1375                             }
       
  1376                         }
       
  1377 
       
  1378                     LOGSTR2( "ATMH LogDllLoaded error %i", error );
       
  1379 
       
  1380                     // Check that everything is OK
       
  1381                     if ( KErrNone == error )
       
  1382                         {
       
  1383                         // Append the codesegment to the array
       
  1384                         error = iCodeblocks.Append(
       
  1385                                         TCodeblock( codeinfo().iRunAddress,
       
  1386                                         codeinfo().iSize,
       
  1387                                         codeinfo().iFullName ) );
       
  1388                         LOGSTR2( "ATMH Append error %i", error );
       
  1389                         }
       
  1390                     }
       
  1391                 }
       
  1392             }
       
  1393 
       
  1394         // Iterate through process dynamic codesegments
       
  1395         for ( TInt i = 0; i < params().iDynamicCount; i++ )
       
  1396             {
       
  1397             // Create local variable and retrieve codesegment info
       
  1398             TLibraryInfoBuf info;
       
  1399             info().iProcessId = iProcessId;
       
  1400             info().iIndex = i;
       
  1401             error = iAnalyzeTool.GetLibraryInfo( info );
       
  1402             LOGSTR2( "ATMH GetLibraryInfo error %i", error );
       
  1403             if ( KErrNone == error )
       
  1404                 {
       
  1405                 // Log the loaded dynamic codesegment(s)
       
  1406                 if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
       
  1407                     {
       
  1408                     if ( iLogOption == EATLogToTraceFast )
       
  1409                         {
       
  1410                         // Using fast logging mode.
       
  1411                         LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - - ATFastLogDllLoaded()#3" );
       
  1412                         ATFastLogDllLoaded( iProcessId,
       
  1413                                 info().iLibraryName,
       
  1414                                 info().iRunAddress,
       
  1415                                 info().iRunAddress + info().iSize );
       
  1416                         }
       
  1417                     else
       
  1418                         {
       
  1419                         // Using storage server.
       
  1420                         LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - iStorageServerOpen #3" );
       
  1421                         error = iStorageServer.LogDllLoaded(
       
  1422                                 info().iLibraryName,
       
  1423                                 info().iRunAddress,
       
  1424                                 info().iRunAddress + info().iSize );
       
  1425                         }
       
  1426                     }
       
  1427 
       
  1428 
       
  1429                 LOGSTR2( "ATMH LogDllLoaded error %i", error );
       
  1430 
       
  1431                 if ( KErrNone == error )
       
  1432                     {
       
  1433                     // Append the codesegment to the array
       
  1434                     error = iCodeblocks.Append(
       
  1435                             TCodeblock( info().iRunAddress, 
       
  1436                                         info().iSize, info().iLibraryName ) );
       
  1437                     LOGSTR2( "ATMH Append error %i", error );
       
  1438                     }
       
  1439                 }
       
  1440             }
       
  1441         }
       
  1442     }
       
  1443 
       
  1444 // -----------------------------------------------------------------------------
       
  1445 // RAnalyzeToolMainAllocator::FindCurrentThreadStack()
       
  1446 // Find the current thread which is using the heap
       
  1447 // -----------------------------------------------------------------------------
       
  1448 //
       
  1449 TBool RAnalyzeToolMainAllocator::FindCurrentThreadStack( TUint32& aStackStart )
       
  1450     {
       
  1451     LOGSTR2( "ATMH RAnalyzeToolMainAllocator::FindCurrentThreadStack(), count( %i )",
       
  1452             iThreadArray.Count() );
       
  1453     
       
  1454     // Flag for indicating that right thread has been found
       
  1455     TBool found( EFalse );
       
  1456     // If threre is only one thread it must be the right thread
       
  1457     if ( iThreadArray.Count() == KThreadCount )
       
  1458         {
       
  1459         if ( !iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
       
  1460             {
       
  1461             // This MUST BE the right thread
       
  1462             //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
       
  1463             }
       
  1464         else if ( iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
       
  1465             {
       
  1466             found = ETrue;
       
  1467             }
       
  1468         }
       
  1469     else
       
  1470         {
       
  1471         // Iterate through array to find right thread
       
  1472         TInt count = iThreadArray.Count();
       
  1473 
       
  1474         for ( TInt i = 0; i < count; i++ )
       
  1475             {
       
  1476             // Check if this is the right thread
       
  1477             if ( iThreadArray[ i ].ThreadStackStart( aStackStart ) )
       
  1478                 {
       
  1479                 // Right thread found. Mark the flag
       
  1480                 found = ETrue;
       
  1481                 break;
       
  1482                 }
       
  1483             }
       
  1484         // If right thread was not found the panic must be raised
       
  1485         if ( !found )
       
  1486             {
       
  1487             //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
       
  1488             }
       
  1489         }
       
  1490     return found;
       
  1491     }
       
  1492 
       
  1493 // -----------------------------------------------------------------------------
       
  1494 // RAnalyzeToolMainAllocator::InstallEventHandler()
       
  1495 // Installs the eventhandler, if possible
       
  1496 // -----------------------------------------------------------------------------
       
  1497 //
       
  1498 void RAnalyzeToolMainAllocator::InstallEventHandler()
       
  1499     {
       
  1500     LOGSTR1( "ATMH RAnalyzeToolMainAllocator::InstallEventHandler()" );
       
  1501     
       
  1502     // Active eventhalder is not active, trying to start it
       
  1503     if ( NULL != CActiveScheduler::Current() )
       
  1504         {
       
  1505         iEventHandler->Start();
       
  1506         }
       
  1507     }
       
  1508 
       
  1509 // End of File