--- /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 <e32cmn.h>
+#include <fshell/clogger.h>
+#include <fshell/heaputils.h>
+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<SDeferredFreeCell> 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