memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapWalk.cpp
branchRCL_3
changeset 59 8ad140f3dd41
parent 49 7fdc9a71d314
--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapWalk.cpp	Wed Sep 15 13:53:27 2010 +0300
+++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapWalk.cpp	Wed Oct 13 16:17:58 2010 +0300
@@ -124,7 +124,7 @@
 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapInit( TMemSpyDriverInternalWalkHeapParamsInit* aParams )
     {
 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit() - START"));
-    __ASSERT_ALWAYS( !iHeapWalkInitialised && iWalkHeap.Helper() == NULL, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkPending ) );
+    __ASSERT_ALWAYS( !iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised() == EFalse, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkPending ) );
 
     TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &iHeapWalkInitialParameters, sizeof(TMemSpyDriverInternalWalkHeapParamsInit) );
     if  ( r == KErrNone )
@@ -141,8 +141,8 @@
                 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - thread: %O", thread));
 
                 // Open client's heap
-                r = iWalkHeap.OpenUserHeap(*thread, iHeapWalkInitialParameters.iDebugAllocator);
-
+                DChunk* userHeapChunk = NULL;
+                r = OpenUserHeap( *thread, iHeapWalkInitialParameters.iRHeapVTable, iWalkHeap, userHeapChunk );
                 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - opening client heap returned: %d", r) );
 
                 if  ( r == KErrNone )
@@ -154,7 +154,7 @@
 
                     // Walk the client's heap
                     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - calling heap walker constructor..."));
-                    RMemSpyDriverHeapWalker heapWalker(iWalkHeap);
+                    RMemSpyDriverHeapWalker heapWalker( iWalkHeap, iHeapWalkInitialParameters.iDebugAllocator );
                     
                     TMemSpyDriverLogChanHeapWalkObserver observer( *this );
                     heapWalker.SetObserver( &observer );
@@ -169,7 +169,7 @@
                 if  ( r < KErrNone )
                     {
                     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - error scenario - releasing kernel heap chunk copy" ));
-                    iWalkHeap.Close();
+                    iWalkHeap.DisassociateWithKernelChunk();
                     }
                 }
             else
@@ -199,7 +199,7 @@
     {
     const TInt walkedHeapCellCount = iWalkHeapCells.Count();
 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell() - START - current cell count: %d", walkedHeapCellCount));
-    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
+    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
 
     // Open the original thread
 	TInt r = OpenTempObject( aTid, EThread );
@@ -257,7 +257,12 @@
         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose - heap walk was still open..."));
       	NKern::ThreadEnterCS();
 
-		iWalkHeap.Close();
+        if  ( iWalkHeap.ChunkIsInitialised() )
+            {
+            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose - removing chunk (%O) from process", &iWalkHeap.Chunk() ) );
+            iWalkHeap.DisassociateWithKernelChunk();
+            iWalkHeap.Reset();
+            }
 
         // Discard handled cells
         iWalkHeapCells.Reset();
@@ -274,9 +279,10 @@
 
 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData(TMemSpyDriverInternalWalkHeapCellDataReadParams* aParams)
     {
-    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
+    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
     //
-	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable));
+    const TBool debugEUser = iHeapWalkInitialParameters.iDebugAllocator;
+	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - START - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, debugEUser));
     //
 	TMemSpyDriverInternalWalkHeapCellDataReadParams params;
     TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverInternalWalkHeapCellDataReadParams) );
@@ -300,58 +306,92 @@
             {
             // Check we can find the cell in the cell list...
             const TMemSpyDriverInternalWalkHeapParamsCell* cell = CellInfoForSpecificAddress( params.iCellAddress );
+            if  ( cell == NULL )
+                {
+                // Maybe the client tried the base address of the cell data.
+                // try to take the header into account and retry.
+                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - didnt find matching cell for address: 0x%08x... trying address minus allocatedCellHeaderSize", params.iCellAddress ));
+
+                const TUint32 cellHeaderSize = (TUint32) RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( debugEUser );
+        
+                TUint32 addr = (TUint32) params.iCellAddress;
+                addr -= cellHeaderSize;
+                params.iCellAddress = (TAny*) addr;
+                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - new address: 0x%08x", params.iCellAddress ));
+        
+                // Last try
+                cell = CellInfoForSpecificAddress( params.iCellAddress );
+                }
 
             TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cell: 0x%08x for address: 0x%08x", cell, params.iCellAddress ));
 
             if  ( cell )
                 {
-                const TInt cellLen = cell->iLength;
-                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellLen: %d", cellLen ));
-
-                if  ( params.iReadLen <= cellLen )
+                const TBool isValidCell = iWalkHeap.CheckCell( cell->iCellAddress, cell->iLength );
+                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - isValidCell: %d", isValidCell ));
+        
+                if  ( isValidCell )
                     {
+                    // Check the length request is valid
+                    const TInt cellLen = cell->iLength;
+                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellLen: %d", cellLen ));
 
-                    // Get user side descriptor length info
-         	        TInt destLen = 0;
-        	        TInt destMax = 0;
-                    TUint8* destPtr = NULL;
+                    if  ( params.iReadLen <= cellLen )
+                        {
+                        const TInt cellHeaderSize = RMemSpyDriverRHeapBase::CellHeaderSize( *cell, debugEUser );
+        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellHeaderSize: %8d", cellHeaderSize ));
 
-                    r = Kern::ThreadGetDesInfo( &ClientThread(), params.iDes, destLen, destMax, destPtr, ETrue );
-        	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", params.iDes, destPtr, destLen, destMax, r ));
+                        // Get user side descriptor length info
+         	            TInt destLen = 0;
+        	            TInt destMax = 0;
+                        TUint8* destPtr = NULL;
+
+                        r = Kern::ThreadGetDesInfo( &ClientThread(), params.iDes, destLen, destMax, destPtr, ETrue );
+        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", params.iDes, destPtr, destLen, destMax, r ));
 
-                    // Work out the start offset for the data...
-                    if  ( r == KErrNone && destMax >= params.iReadLen )
-                        {
-                        const TAny* srcPos = ((TUint8*) cell->iCellAddress);
-        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - srcPos: 0x%08x", srcPos ));
+                        // Work out the start offset for the data...
+                        if  ( r == KErrNone && destMax >= params.iReadLen )
+                            {
+                            const TAny* srcPos = ((TUint8*) cell->iCellAddress) + cellHeaderSize;
+        	                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - srcPos: 0x%08x", srcPos ));
+
+                            // Read some data 
+                            r = Kern::ThreadRawRead( thread, srcPos, destPtr, params.iReadLen );
+    	                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - read from thread returned: %d", r));
 
-                        // Read some data 
-                        r = Kern::ThreadRawRead( thread, srcPos, destPtr, params.iReadLen );
-    	                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - read from thread returned: %d", r));
-
-                        if  ( r == KErrNone )
+                            if  ( r == KErrNone )
+                                {
+                                // Client will update descriptor length in this situation.
+                                r = params.iReadLen;
+                                }
+                            else if ( r == KErrBadDescriptor )
+                                {
+                                MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor );
+                                }
+                            }
+                        else
                             {
-                            // Client will update descriptor length in this situation.
-                            r = params.iReadLen;
+                            if  ( r != KErrBadDescriptor )
+                                {
+                                r = KErrArgument;                
+            	                Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - user-descriptor isnt big enough for requested data" );
+                                }
+                            else
+                                {
+            	                Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - bad or non-writable user-side descriptor" );
+                                }
                             }
                         }
                     else
                         {
-                        if  ( r != KErrBadDescriptor )
-                            {
-                            r = KErrArgument;                
-            	            Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - user-descriptor isnt big enough for requested data" );
-                            }
-                        else
-                            {
-            	            Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - bad or non-writable user-side descriptor" );
-                            }
+                        r = KErrArgument;
+        	            Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - read length is bigger than cell length");
                         }
                     }
                 else
                     {
                     r = KErrArgument;
-        	        Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - read length is bigger than cell length");
+                    Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - invalid cell address: 0x%08x", cell);
                     }
                 }
             else
@@ -373,16 +413,17 @@
     	Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - thread not found");
 		}
     //
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END result=%d", r));
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END"));
     return r;
     }
 
 
 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo( TAny* aCellAddress, TMemSpyDriverInternalWalkHeapParamsCell* aParams )
     {
-    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
+    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
     //
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable));
+    const TBool debugEUser = iHeapWalkInitialParameters.iDebugAllocator;
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - START - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, debugEUser));
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - cell: 0x%08x", aCellAddress));
 
     // Open the original thread
@@ -409,6 +450,16 @@
     if  ( cell == NULL )
         {
         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - no exact match for address: 0x%08x...", aCellAddress));
+
+        // Maybe the client tried the base address of the cell data.
+        // try to take the header into account and retry.
+        const TUint32 cellHeaderSize = (TUint32) RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( debugEUser );
+        TUint32 addr = (TUint32) aCellAddress;
+        addr -= cellHeaderSize;
+        
+        TAny* cellByRawStartingAddress = (TAny*) addr;
+        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - trying to search by start of cell address: 0x%08x (cellHeaderSize: %d)", cellByRawStartingAddress, cellHeaderSize));
+        cell = CellInfoForSpecificAddress( cellByRawStartingAddress );
         
         // If the cell still wasn't found, then let's look for any heap cell that contains
         // the client-specified address (i.e. find the heap cell that contains the specified
@@ -422,9 +473,18 @@
 
     if  ( cell )
         {
-        // Have enough info to write back to client now
-        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - returning... cellType: %1d, addr: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", cell->iCellType, cell->iCellAddress, cell->iLength, cell->iNestingLevel, cell->iAllocNumber ));
-        r = Kern::ThreadRawWrite( &ClientThread(), aParams, cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) );
+        const TBool isValidCell = iWalkHeap.CheckCell( cell->iCellAddress, cell->iLength );
+        if  ( isValidCell )
+            {
+            // Have enough info to write back to client now
+            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - returning... cellType: %1d, addr: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", cell->iCellType, cell->iCellAddress, cell->iLength, cell->iNestingLevel, cell->iAllocNumber ));
+            r = Kern::ThreadRawWrite( &ClientThread(), aParams, cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) );
+            }
+        else
+            {
+            r = KErrArgument;
+            Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - invalid cell address: 0x%08x", cell);
+            }
         }
     else
         {
@@ -434,7 +494,7 @@
     
     CloseTempObject();
     //
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END result=%d", r));
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END"));
     return r;
     }
 
@@ -516,7 +576,7 @@
 
 
 
-TBool DMemSpyDriverLogChanHeapWalk::WalkerHandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
+TBool DMemSpyDriverLogChanHeapWalk::WalkerHandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
     {
     TInt error = KErrNone;
     //