diff -r 000000000000 -r 7f656887cf89 libraries/qr3/inc/LoggingAllocator.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libraries/qr3/inc/LoggingAllocator.h Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,135 @@ +// LoggingAllocator.h +// +// Copyright (c) 2010 Accenture. All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the "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: +// Accenture - Initial contribution +// +#ifndef LOGGING_ALLOCATOR_H +#define LOGGING_ALLOCATOR_H + +#include +#include +#include +using LtkUtils::RAllocatorHelper; + +NONSHARABLE_CLASS(RLoggingAllocator) : public RAllocator + { +public: + IMPORT_C static TInt Install(); + IMPORT_C static TInt Install(TUint aFlags); + IMPORT_C static TInt Uninstall(); + + // These don't require you to actually link against RLoggingAllocator + inline static TInt Install_WeakLink(TUint aFlags=0); + inline static TInt Uninstall_WeakLink(); + + // Doesn't require the allocator to be installed, just dumps a stacktrace frame for the given cell + static IMPORT_C void StaticTraceAlloc(RAllocator* aAllocator, TAny* aCellPtr, TInt aRequestedSize); + static IMPORT_C void StaticTraceFree(RAllocator* aAllocator, TAny* aCellPtr); + + // Create a new logging allocator without changing the current User::Allocator + IMPORT_C static TInt New(TUint aFlags, RAllocator* aOrigAllocator, RLoggingAllocator*& aResult); + + enum TFlags + { + EScribbleFrees = 1, + EDeferFree = 2, + EDeferFreeAndCheckScribbles = EDeferFree | EScribbleFrees, + EOldFormatLogging = 4, // Use Symbian-defined BTrace::EAlloc and BTrace::ETest1 rather than the new range atrace defines extending THeap + }; + + static const TInt KTempDisableLogging = 0x10286F5E; + + static TAny* DisableLogging() + { + TAny* result = NULL; + User::Allocator().DebugFunction(KTempDisableLogging, &result); + return result; + } + + static void RestoreLogging(TAny* aAllocator) + { + if (aAllocator) + { + User::SwitchAllocator((RAllocator*)aAllocator); + } + } + +protected: + TAny* Alloc(TInt aSize); + void Free(TAny* aPtr); + TAny* ReAlloc(TAny* aPtr, TInt aSize, TInt aMode=0); + TInt AllocLen(const TAny* aCell) const; + TInt Compress(); + void Reset(); + TInt AllocSize(TInt& aTotalAllocSize) const; + TInt Available(TInt& aBiggestBlock) const; + TInt DebugFunction(TInt aFunc, TAny* a1=NULL, TAny* a2=NULL); + +private: + RLoggingAllocator(TUint aFlags); + static TBool HeavenWalk(LtkUtils::RAllocatorHelper& aHelper, TAny* aPtr, RAllocatorHelper::TCellType aType, TLinAddr aCell, TInt aLen); + + static TBool TraceExistingAllocs(TAny* aContext, RAllocatorHelper::TCellType aType, TLinAddr aCell, TInt aLen); + inline void TraceAlloc(RAllocator* aAllocator, TAny* aCellPtr, TInt aRequestedSize); + inline void TraceFree(RAllocator* aAllocator, TAny* aCellPtr, TBool aCellIsAlreadyFreed=EFalse); + inline void TraceRealloc(TAny *aNewPtr, TAny* aOldPtr, TInt aNewRequestedSize); + void DoTraceAllocEvent(RAllocator* aAllocator, TAny* aCellPtr, TInt aEvent, TInt aRequestedSize, TAny* aOldPtr=NULL); // RequestedSize only relevant for aEvent==EHeapAlloc or EHeapReAlloc, aOldPtr only for realloc + void CheckDeferredFrees(); + void Destroy(); + virtual ~RLoggingAllocator(); // Made this virtual to shut up GCCE (even GCC 4 complains about this) + +public: + RAllocator* iA; // The original allocator + +private: + TInt iBreakOnAllocCount; // Useful when running in a debugger +#ifndef __KERNEL_MODE__ + RLibrary iLib; // Needed to keep the plugin DLL loaded past the time when ecom is cleaned up +#endif + TUint iFlags; + RFastLock iLock; // For locking around iFlags and iDeferredFrees + struct SDeferredFreeCell { void* iPtr; TInt iLen; }; + RArray iDeferredFrees; + TUint iPid; + RAllocatorHelper iHelper; + }; + +inline TInt RLoggingAllocator::Install_WeakLink(TUint aFlags) + { + const TInt KInstallOrdinal = 5; // Happily this is the same on bwins and eabi (and probably bmarm if I get round to rebuilding it) + RLibrary lib; + TInt err = lib.Load(_L("loggingallocator")); + if (err) return err; + + typedef TInt (*InstallFn)(TUint); + InstallFn InstallLoggingAllocator = (InstallFn)lib.Lookup(KInstallOrdinal); + if (!InstallLoggingAllocator) err = KErrBadLibraryEntryPoint; + + if (!err) err = InstallLoggingAllocator(aFlags); + lib.Close(); // If the allocator installed itself, it makes sure to keep itself loaded via an RLibrary of its own + return err; + } + +inline TInt RLoggingAllocator::Uninstall_WeakLink() + { + const TInt KUninstallOrdinal = 2; // Happily this is the same on bwins and eabi (and probably bmarm if I get round to rebuilding it) + RLibrary lib; + TInt err = lib.Load(_L("loggingallocator")); + if (err) return err; + + typedef TInt (*UninstallFn)(); + UninstallFn UninstallLoggingAllocator = (UninstallFn)lib.Lookup(KUninstallOrdinal); + if (!UninstallLoggingAllocator) err = KErrBadLibraryEntryPoint; + + if (!err) err = UninstallLoggingAllocator(); + lib.Close(); // If the allocator installed itself, it makes sure to keep itself loaded via an RLibrary of its own + return err; + } + +#endif