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