diff -r 0ff24a8f6ca2 -r 98307c651589 analyzetool/dynamicmemoryhook/src/customuser.cpp --- a/analyzetool/dynamicmemoryhook/src/customuser.cpp Fri Aug 27 11:37:29 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,518 +0,0 @@ -/* -* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: Definitions for the class CustomUser. -* -*/ - -#include -#include -#include "customuser.h" -#include "analyzetoolmainallocator.h" -#include "analyzetoolallocator.h" -#include "atlog.h" -#include "analyzetoolmemoryallocator.h" -#include "analyzetoolpanics.pan" -#include "atstorageservercommon.h" -#include "atdriveinfo.h" -#include - -#ifdef USE_CLEANER_DLL -// Global variable to detect dll attach & detach in process. -// Note! This is initialized after SetupThreadHeap so its not usable there. -// This is used to store the main thread id and track when the process ends -// to load the cleaner dll with call back feature to cleanup allocator at the -// last possible phase. -#include - -// CONSTANTS -const TInt KAToolCleanerOrdinal = 1; - -class TAnalyzeToolGlobalTracker : public TAnalyzeToolCleanerBase - { -public: - /* Main thread id */ - TThreadId iMainId; - - /* Inform if panic occured */ - TBool iPanic; - - // ----------------------------------------------------------------------------- - // TAnalyzeToolGlobalTracker::TAnalyzeToolGlobalTracker() - // C++ default constructor - // ----------------------------------------------------------------------------- - // - TAnalyzeToolGlobalTracker() - { - LOGSTR1( "ATMH TAnalyzeToolGlobalTracker::TAnalyzeToolGlobalTracker()" ); - - iPanic = EFalse; // no panic occured - iMainId = RThread().Id(); // set main thread id - LOGSTR2( "ATMH TAnalyzeToolGlobalTracker() > Main id set: %d", - iMainId.operator TUint() ); - } - - // ----------------------------------------------------------------------------- - // TAnalyzeToolGlobalTracker::~TAnalyzeToolGlobalTracker() - // Destructor. - // ----------------------------------------------------------------------------- - // - ~TAnalyzeToolGlobalTracker() - { - LOGSTR1( "ATMH TAnalyzeToolGlobalTracker::~TAnalyzeToolGlobalTracker()" ); - - // We dont load dll if panic has happened (uninstallation has been done). - if ( iPanic ) - { - LOGSTR1( "ATMH ~TAnalyzeToolGlobalTracker > Panic set not loading cleaner dll." ); - return; - } - - LOGSTR1( "ATMH ~TAnalyzeToolGlobalTracker > about to load cleaner dll" ); - // Load cleaner library and set a call back to our cleanup - RLibrary lib; - TInt error( lib.Load( KATCleanerDllName ) ); - if ( error == KErrNone ) - { - // Set address to point to ourself - TLibraryFunction func = lib.Lookup( KAToolCleanerOrdinal ); // Ordinal 1 of the dll - ATCLEANERTABLE* cleaner = (ATCLEANERTABLE*) func(); // Use function to get address - cleaner->At( 0 ) = (TUint32) this; // Set address - LOGSTR1( "ATMH ~TAnalyzeToolGlobalTracker() > cleaner dll loaded and call back set" ); - } - else - { - // Error loading cleanup dll - LOGSTR2( "ATMH ~TAnalyzeToolGlobalTracker() > cleaner dll load error(%i) uninstalling allocator now!", - error ); - Cleanup(); - } - } - - // ----------------------------------------------------------------------------- - // TAnalyzeToolGlobalTracker::Cleanup() - // - // ----------------------------------------------------------------------------- - // - void Cleanup() - { - LOGSTR1( "ATMH TAnalyzeToolGlobalTracker::Cleanup() - allocator uninstall" ); - - // Uninstall allocator - ( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall(); - } - - }; - -// Global variable definition. -TAnalyzeToolGlobalTracker gGlobalTracker; -#endif - -// CONSTANTS -// When needed, update the version number directly inside _LIT macro. -// Constant for the atool API(staticlib) version. -_LIT( KAtoolApiVersion, "1.7.5" ); - -// Version number buffer length -const TInt KAtoolVersionNumberLength = 10; - -// Wrong version error code -const TInt KAtoolVersionError = -1999; - -// Version number separator -_LIT( KVersionSeparator, ";" ); - -// Incorrect version error strings -_LIT( KIncorrectText, "ERROR_OCCURED INCORRECT_ATOOL_VERSION [API v.%S][ATOOL v.%S]" ); -_LIT( KIncorrectTextTrace, "PCSS " ); - -// ----------------------------------------------------------------------------- -// CustomUser::Panic() -// Overloaded User::Panic() function -// ----------------------------------------------------------------------------- -// -EXPORT_C void CustomUser::Panic( const TDesC& aCategory, TInt aReason ) - { - LOGSTR3( "ATMH CustomUser::Panic() %S %i", &aCategory, aReason ); - -#ifdef USE_CLEANER_DLL - // Set global tracker that panic has happened. - gGlobalTracker.iPanic = ETrue; -#endif - - // Uninstall thread's RAllocator - ( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall(); - - // Call the "real" User::Panic() - User::Panic( aCategory, aReason ); - } - -// ----------------------------------------------------------------------------- -// CustomUser::Exit() -// Overloaded User::Exit() function -// ----------------------------------------------------------------------------- -// -EXPORT_C void CustomUser::Exit( TInt aReason ) - { - LOGSTR3( "ATMH CustomUser::Exit() %i %i", aReason, RThread().Id().Id() ); - - if ( aReason != KAtoolVersionError ) - { -#ifdef USE_CLEANER_DLL - // Only uninstall allocator if its not the process main/first thread. - LOGSTR3( "ATMH CustomUser::Exit() - Thread id: %d - Main Id: %d", - RThread().Id().operator TUint(), gGlobalTracker.iMainId.operator TUint() ); - - if ( RThread().Id() != gGlobalTracker.iMainId ) - { - LOGSTR2("ATMH CustomUser::Exit() - Calling allocator uninstall in thread: %d" , RThread().Id().operator TUint() ); - ( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall(); - } -#else - // Uninstall thread's RAllocator - ( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall(); - LOGSTR1( "ATMH CustomUser::Exit() - about to User::Exit" ); -#endif - } - - // Call the "real" User::Exit() - User::Exit( aReason ); - } - -// ----------------------------------------------------------------------------- -// CustomUser::SetCritical() -// Overloaded User::SetCritical() function which returns -// KErrNone, if successful; KErrArgument, if EAllThreadsCritical is -// passed - this is a state associated with a process, and you use -// User::SetProcessCritical() to set it. -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt CustomUser::SetCritical( User::TCritical aCritical ) - { - LOGSTR1( "ATMH CustomUser::SetCritical()" ); - // Check the given User::TCritical type - if ( aCritical == User::EAllThreadsCritical ) - { - return KErrArgument; - } - else - { - return KErrNone; - } - } - -// ----------------------------------------------------------------------------- -// CustomUser::SetProcessCritical() -// Overloaded User::SetProcessCritical() function -// KErrNone, if successful; KErrArgument, if either EProcessCritical or -// EProcessPermanent is passed - these are states associated with a -// thread, and you use User::SetCritical() to set them. -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt CustomUser::SetProcessCritical( User::TCritical aCritical ) - { - LOGSTR1( "ATMH CustomUser::SetProcessCritical()" ); - // Check the given User::TCritical type - if ( aCritical == User::EProcessCritical || - User::EProcessPermanent == aCritical ) - { - return KErrArgument; - } - else - { - return KErrNone; - } - } - -// ----------------------------------------------------------------------------- -// CustomUser::SetupThreadHeap() -// Overloaded UserHeap::SetupThreadHeap function -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt CustomUser::SetupThreadHeap( TBool aNotFirst, - SStdEpocThreadCreateInfo& aInfo, const TFileName& aFileName, - TUint32 aLogOption, TUint32 aIsDebug, const TATVersion& aVersion, - TUint32 aAllocCallStackSize, TUint32 aFreeCallStackSize, - TRefByValue aFmt, ... ) - { - LOGSTR1( "ATMH CustomUser::SetupThreadHeap()" ); - LOGSTR2( "ATMH > Thread id(%d)", RThread().Id().operator TUint() ); - - // Add handling of the argument list here. - - TInt ret( KErrNone ); - // Check version number - TBuf atoolVer; - if ( CheckVersion( aVersion, atoolVer ) != KErrNone ) - { - LOGSTR1( "ATMH > Wrong API version > Inform user and Exit." ); - ReportIncorrectVersion( aLogOption, aFileName, atoolVer ); - return KAtoolVersionError; - } - - // Check is this shared heap - if ( aInfo.iAllocator == NULL ) - { - LOGSTR1( "ATMH creating a new heap" ); - // RAllocator is NULL so heap is not shared, creating a new heap - ret = UserHeap::SetupThreadHeap( aNotFirst, aInfo ); - __ASSERT_ALWAYS( KErrNone == ret, AssertPanic( EFailedToCreateHeap ) ); - -#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 ) - #ifndef __WINS__ - // Set dummy Tls value - TAny* dummyPtr( NULL ); - TInt setErr( UserSvr::DllSetTls( KDummyHandle, dummyPtr ) ); - LOGSTR2( "ATMH > Set Tls err(%i)", setErr ); - #endif -#endif - // Install the RAllocator - aInfo.iAllocator = &InstallAllocator( aNotFirst, aFileName, aLogOption, aIsDebug, - aAllocCallStackSize, aFreeCallStackSize ); - } - else - { - LOGSTR1( "ATMH sharing the heap" ); - // The heap is shared. Acquire pointer to the original heap - RAnalyzeToolMemoryAllocator* allocator = - (RAnalyzeToolMemoryAllocator*) aInfo.iAllocator; - // Share the heap - allocator->ShareHeap(); - // Switch thread heap - User::SwitchAllocator( allocator ); - } - return ret; - } - -// ----------------------------------------------------------------------------- -// CustomUser::InstallAllocator -// Installs the RAllocator -// ----------------------------------------------------------------------------- -// -//lint -e{429} suppress "Custodial pointer 'allocator' has not been freed or returned" -EXPORT_C RAllocator& CustomUser::InstallAllocator( TBool aNotFirst, - const TFileName& aFileName, TUint32 aLogOption, TUint32 aIsDebug, - TUint32 aAllocCallStackSize, TUint32 aFreeCallStackSize ) - { - LOGSTR1( "ATMH CustomUser::InstallAllocator()" ); - - // Open handle to the device driver - RAnalyzeTool analyzetool; - TInt error = analyzetool.Open(); - - // Check if the device driver has already loaded - if ( KErrNone == error ) - { - LOGSTR1( "ATMH CustomUser::InstallAllocator() - analyzetool.Open() returned KErrNone" ); - // The device driver has already loaded - // Get pointer to the main thread allocator - TMainThreadParamsBuf params; - params().iProcessId = RProcess().Id().operator TUint(); - error = analyzetool.MainThreadAlloctor( params ); - - __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantOpenHandle ) ); - - // Close handle to the device driver - analyzetool.Close(); - - // Is this the first thread of the program - if ( params().iAlone ) - { - LOGSTR1( "ATMH CustomUser::InstallAllocator() - first thread of the program" ); - // Only one thread in the program. Must be main thread - RAnalyzeToolMainAllocator* allocator = - new RAnalyzeToolMainAllocator( aNotFirst, aFileName, aLogOption, - aIsDebug, aAllocCallStackSize, aFreeCallStackSize ); - - __ASSERT_ALWAYS( allocator != NULL, AssertPanic( ENoMemory ) ); - - // Change threads allocator - User::SwitchAllocator( allocator ); - - // Return reference to the RAllocator - return *allocator; - } - // This is not the first thread. A new thread with a new heap created - else - { - LOGSTR1( "ATMH CustomUser::InstallAllocator() - create a new allocator for the new thread" ); - // Create new RAllocator with handles from the main thread - RAnalyzeToolAllocator* allocator = new RAnalyzeToolAllocator( - aNotFirst, - ((RAnalyzeToolMainAllocator*)params().iAllocator)->StorageServer(), - ((RAnalyzeToolMainAllocator*)params().iAllocator)->Codeblocks(), - ((RAnalyzeToolMainAllocator*)params().iAllocator)->Mutex(), - ((RAnalyzeToolMainAllocator*)params().iAllocator)->ProcessId(), - ((RAnalyzeToolMainAllocator*)params().iAllocator)->AnalyzeTool(), - ((RAnalyzeToolMainAllocator*)params().iAllocator)->StorageServerOpen(), - ((RAnalyzeToolMainAllocator*)params().iAllocator)->LogOption(), - ((RAnalyzeToolMainAllocator*)params().iAllocator)->AllocMaxCallStack(), - ((RAnalyzeToolMainAllocator*)params().iAllocator)->FreeMaxCallStack() ); - - __ASSERT_ALWAYS( allocator != NULL, AssertPanic( ENoMemory ) ); - - // Change threads allocator - User::SwitchAllocator( allocator ); - - // Return reference to the RAllocator - return *allocator; - } - } - // The device driver does not exists so this must be the first thread - else - { - LOGSTR1( "ATMH CustomUser::InstallAllocator() - analyzetool.Open() returned error, creating DD" ); - RAnalyzeToolMainAllocator* allocator = - new RAnalyzeToolMainAllocator( aNotFirst, aFileName, aLogOption, aIsDebug, - aAllocCallStackSize, aFreeCallStackSize ); - - __ASSERT_ALWAYS( allocator != NULL, AssertPanic( ENoMemory ) ); - - // Change threads allocator - User::SwitchAllocator( allocator ); - - // Return reference to the RAllocator - return *allocator; - } - } - -// ----------------------------------------------------------------------------- -// CustomUser::CheckVersion -// Check atool version -// ----------------------------------------------------------------------------- -// -TInt CustomUser::CheckVersion( const TATVersion& aVersion, TDes& aToolVersion ) - { - LOGSTR2( "ATMH CustomUser::CheckVersion(), aVersion( %S )", &aVersion ); - - TFileName version; - version.Copy( aVersion ); - TBuf apiVer; - - // Find separator place - TInt findplace( version.Find( KVersionSeparator() ) ); - // Parse API version first [x.x.x;x.x.x] - if ( findplace >= 0 && findplace <= apiVer.MaxLength() ) - { - apiVer.Copy( version.Mid( 0, findplace ) ); - version.Delete( 0, findplace + KVersionSeparator().Length() ); - } - - if ( version.Length() <= aToolVersion.MaxLength() ) - { - aToolVersion.Copy( version ); - if ( aToolVersion.Compare( KAtoolApiVersion ) == KErrNone && - apiVer.Length() == 0 ) - { - // Support 1.5.0 version (Version info: [1.5.0]) - apiVer.Copy( version ); - } - } - - LOGSTR3( "ATMH > API version( %S ), ATOOL version( %S )", - &apiVer, &aToolVersion ); - - // Check version numbers - if ( apiVer.Compare( KAtoolApiVersion ) == KErrNone ) - { - return KErrNone; - } - return KErrCancel; - } - -// ----------------------------------------------------------------------------- -// CustomUser::ReportIncorrectVersion -// Function for showing incorrect version information -// ----------------------------------------------------------------------------- -// -void CustomUser::ReportIncorrectVersion( const TUint32 aLogOption, - const TFileName& aFileName, const TDes& aToolVersion ) - { - LOGSTR2( "ATMH CustomUser::ReportIncorrectVersion(), aFileName( %S )", - &aFileName ); - - switch ( aLogOption ) - { - case EATLogToFile: - { - LOGSTR1( "ATMH ReportIncorrectVersion > EATLogToFile" ); - - // A handle to a file server session. - RFs fs; - // Creates and opens a file, - // and performs all operations on a single open file. - RFile file; - // Create full path buffer - TBuf logFileBuf; - // Connects a client to the file server. - TInt err( fs.Connect() ); - - if ( !err ) - { - err = TATDriveInfo::CreatePath( logFileBuf, aFileName, fs ); - - // Replace file if exists - if ( err && err != KErrAlreadyExists ) - { - LOGSTR2( "ATMH > TATDriveInfo::CreatePath() err( %i )", err ); - return; - } - - // Replace file if exists (drive C) - err = file.Replace( fs, logFileBuf, EFileWrite ); - - // Write to file - if ( !err ) - { - err = file.Write( KDataFileVersion ); - // Error msg buffer - TBuf8 msg; - // Write the error code to the buffer - logFileBuf.Format( KIncorrectText, &KAtoolApiVersion, &aToolVersion ); - CnvUtfConverter::ConvertFromUnicodeToUtf8( msg, logFileBuf ); - err = file.Write( msg ); - } - // Closes the file. - file.Close(); - } - - LOGSTR2( "ATMH > File err( %i )", err ); - // Closes the handle. - fs.Close(); - } - break; - - case EATUseDefault: - case EATLogToTrace: - { - LOGSTR1( "ATMH > ReportIncorrectVersion > EATLogToTrace" ); - // Error msg buffer - TBuf msg; - msg.Copy( KIncorrectTextTrace ); - msg.Append( KIncorrectText ); - TBuf traceMsg; - // Write the error code to the buffer - traceMsg.Format( msg, &KAtoolApiVersion, &aToolVersion ); - RDebug::Print( traceMsg ); - } - break; - - default: - { - LOGSTR1( "ATMH > ReportIncorrectVersion > default" ); - } - break; - } - } - -// End of File