perfsrv/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapWalkUser.cpp
author hgs
Mon, 20 Sep 2010 12:20:18 +0300
changeset 52 c2f44e33b468
permissions -rw-r--r--
201037
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
hgs
parents:
diff changeset
     3
* All rights reserved.
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
*
hgs
parents:
diff changeset
     9
* Initial Contributors:
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    11
*
hgs
parents:
diff changeset
    12
* Contributors:
hgs
parents:
diff changeset
    13
*
hgs
parents:
diff changeset
    14
* Description:
hgs
parents:
diff changeset
    15
*
hgs
parents:
diff changeset
    16
*/
hgs
parents:
diff changeset
    17
hgs
parents:
diff changeset
    18
#include "MemSpyDriverLogChanHeapWalkUser.h"
hgs
parents:
diff changeset
    19
hgs
parents:
diff changeset
    20
// System includes
hgs
parents:
diff changeset
    21
#include <u32hal.h>
hgs
parents:
diff changeset
    22
#include <e32rom.h>
hgs
parents:
diff changeset
    23
#include <memspy/driver/memspydriverconstants.h>
hgs
parents:
diff changeset
    24
#include <memspy/driver/memspydriverobjectsshared.h>
hgs
parents:
diff changeset
    25
hgs
parents:
diff changeset
    26
// Shared includes
hgs
parents:
diff changeset
    27
#include "MemSpyDriverOpCodes.h"
hgs
parents:
diff changeset
    28
#include "MemSpyDriverObjectsInternal.h"
hgs
parents:
diff changeset
    29
hgs
parents:
diff changeset
    30
// User includes
hgs
parents:
diff changeset
    31
#include "MemSpyDriverHeap.h"
hgs
parents:
diff changeset
    32
#include "MemSpyDriverUtils.h"
hgs
parents:
diff changeset
    33
#include "MemSpyDriverDevice.h"
hgs
parents:
diff changeset
    34
#include "MemSpyDriverOSAdaption.h"
hgs
parents:
diff changeset
    35
#include "MemSpyDriverSuspensionManager.h"
hgs
parents:
diff changeset
    36
hgs
parents:
diff changeset
    37
hgs
parents:
diff changeset
    38
hgs
parents:
diff changeset
    39
DMemSpyDriverLogChanHeapWalkUser::DMemSpyDriverLogChanHeapWalkUser( DMemSpyDriverDevice& aDevice, DThread& aThread )
hgs
parents:
diff changeset
    40
:	DMemSpyDriverLogChanHeapBase( aDevice, aThread ), iWalkHeap( aDevice.OSAdaption() )
hgs
parents:
diff changeset
    41
    {
hgs
parents:
diff changeset
    42
    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::DMemSpyDriverLogChanHeapWalk() - this: 0x%08x", this ));
hgs
parents:
diff changeset
    43
    }
hgs
parents:
diff changeset
    44
hgs
parents:
diff changeset
    45
hgs
parents:
diff changeset
    46
DMemSpyDriverLogChanHeapWalkUser::~DMemSpyDriverLogChanHeapWalkUser()
hgs
parents:
diff changeset
    47
	{
hgs
parents:
diff changeset
    48
	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::~DMemSpyDriverLogChanHeapWalk() - START - this: 0x%08x", this ));
hgs
parents:
diff changeset
    49
hgs
parents:
diff changeset
    50
    NKern::ThreadEnterCS();
hgs
parents:
diff changeset
    51
hgs
parents:
diff changeset
    52
    WalkHeapClose();
hgs
parents:
diff changeset
    53
hgs
parents:
diff changeset
    54
    NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
    55
hgs
parents:
diff changeset
    56
	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::~DMemSpyDriverLogChanHeapWalk() - END - this: 0x%08x", this ));
hgs
parents:
diff changeset
    57
	}
hgs
parents:
diff changeset
    58
hgs
parents:
diff changeset
    59
hgs
parents:
diff changeset
    60
hgs
parents:
diff changeset
    61
hgs
parents:
diff changeset
    62
hgs
parents:
diff changeset
    63
hgs
parents:
diff changeset
    64
hgs
parents:
diff changeset
    65
TInt DMemSpyDriverLogChanHeapWalkUser::Request( TInt aFunction, TAny* a1, TAny* a2 )
hgs
parents:
diff changeset
    66
	{
hgs
parents:
diff changeset
    67
	TInt r = DMemSpyDriverLogChanBase::Request( aFunction, a1, a2 );
hgs
parents:
diff changeset
    68
    if  ( r == KErrNone )
hgs
parents:
diff changeset
    69
        {
hgs
parents:
diff changeset
    70
	    switch( aFunction )
hgs
parents:
diff changeset
    71
		    {
hgs
parents:
diff changeset
    72
	    case EMemSpyDriverOpCodeHeapUserWalkInit:
hgs
parents:
diff changeset
    73
            r = WalkHeapInit( (TMemSpyDriverInternalWalkHeapParamsInit*) a1 );
hgs
parents:
diff changeset
    74
            break;
hgs
parents:
diff changeset
    75
        case EMemSpyDriverOpCodeHeapUserWalkGetCellInfo:
hgs
parents:
diff changeset
    76
            r = WalkHeapGetCellInfo( (TAny*) a1, (TMemSpyDriverInternalWalkHeapParamsCell*) a2 );
hgs
parents:
diff changeset
    77
            break;
hgs
parents:
diff changeset
    78
	    case EMemSpyDriverOpCodeHeapUserWalkReadCellData:
hgs
parents:
diff changeset
    79
            r = WalkHeapReadCellData( (TMemSpyDriverInternalWalkHeapCellDataReadParams*) a1 );
hgs
parents:
diff changeset
    80
            break;
hgs
parents:
diff changeset
    81
	    case EMemSpyDriverOpCodeHeapUserWalkNextCell:
hgs
parents:
diff changeset
    82
            r = WalkHeapNextCell( (TUint) a1, (TMemSpyDriverInternalWalkHeapParamsCell*) a2 );
hgs
parents:
diff changeset
    83
            break;
hgs
parents:
diff changeset
    84
	    case EMemSpyDriverOpCodeHeapUserWalkClose:
hgs
parents:
diff changeset
    85
            r = WalkHeapClose();
hgs
parents:
diff changeset
    86
            break;
hgs
parents:
diff changeset
    87
hgs
parents:
diff changeset
    88
        default:
hgs
parents:
diff changeset
    89
            r = KErrNotSupported;
hgs
parents:
diff changeset
    90
		    break;
hgs
parents:
diff changeset
    91
		    }
hgs
parents:
diff changeset
    92
        }
hgs
parents:
diff changeset
    93
    //
hgs
parents:
diff changeset
    94
    return r;
hgs
parents:
diff changeset
    95
	}
hgs
parents:
diff changeset
    96
hgs
parents:
diff changeset
    97
hgs
parents:
diff changeset
    98
TBool DMemSpyDriverLogChanHeapWalkUser::IsHandler( TInt aFunction ) const
hgs
parents:
diff changeset
    99
    {
hgs
parents:
diff changeset
   100
    return ( aFunction > EMemSpyDriverOpCodeHeapUserWalkBase && aFunction < EMemSpyDriverOpCodeHeapUserWalkEnd );
hgs
parents:
diff changeset
   101
    }
hgs
parents:
diff changeset
   102
hgs
parents:
diff changeset
   103
hgs
parents:
diff changeset
   104
hgs
parents:
diff changeset
   105
hgs
parents:
diff changeset
   106
hgs
parents:
diff changeset
   107
hgs
parents:
diff changeset
   108
hgs
parents:
diff changeset
   109
hgs
parents:
diff changeset
   110
hgs
parents:
diff changeset
   111
hgs
parents:
diff changeset
   112
hgs
parents:
diff changeset
   113
hgs
parents:
diff changeset
   114
hgs
parents:
diff changeset
   115
hgs
parents:
diff changeset
   116
hgs
parents:
diff changeset
   117
hgs
parents:
diff changeset
   118
hgs
parents:
diff changeset
   119
hgs
parents:
diff changeset
   120
hgs
parents:
diff changeset
   121
hgs
parents:
diff changeset
   122
hgs
parents:
diff changeset
   123
hgs
parents:
diff changeset
   124
TInt DMemSpyDriverLogChanHeapWalkUser::WalkHeapInit( TMemSpyDriverInternalWalkHeapParamsInit* aParams )
hgs
parents:
diff changeset
   125
    {
hgs
parents:
diff changeset
   126
	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit() - START"));
hgs
parents:
diff changeset
   127
    __ASSERT_ALWAYS( !iHeapWalkInitialised && iWalkHeap.Helper() == NULL, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkPending ) );
hgs
parents:
diff changeset
   128
hgs
parents:
diff changeset
   129
    TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &iHeapWalkInitialParameters, sizeof(TMemSpyDriverInternalWalkHeapParamsInit) );
hgs
parents:
diff changeset
   130
    if  ( r == KErrNone )
hgs
parents:
diff changeset
   131
        {
hgs
parents:
diff changeset
   132
	    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, iHeapWalkInitialParameters.iDebugAllocator));
hgs
parents:
diff changeset
   133
hgs
parents:
diff changeset
   134
	    r = OpenTempObject( iHeapWalkInitialParameters.iTid, EThread );
hgs
parents:
diff changeset
   135
	    if  ( r == KErrNone )
hgs
parents:
diff changeset
   136
		    {
hgs
parents:
diff changeset
   137
            // Find the chunk with the correct handle
hgs
parents:
diff changeset
   138
            DThread* thread = (DThread*) TempObject();
hgs
parents:
diff changeset
   139
            if  ( SuspensionManager().IsSuspended( *thread ) )
hgs
parents:
diff changeset
   140
                {
hgs
parents:
diff changeset
   141
                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - thread: %O", thread));
hgs
parents:
diff changeset
   142
hgs
parents:
diff changeset
   143
                // Open client's heap
hgs
parents:
diff changeset
   144
                r = iWalkHeap.OpenUserHeap(*thread, iHeapWalkInitialParameters.iDebugAllocator);
hgs
parents:
diff changeset
   145
hgs
parents:
diff changeset
   146
                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - opening client heap returned: %d", r) );
hgs
parents:
diff changeset
   147
hgs
parents:
diff changeset
   148
                if  ( r == KErrNone )
hgs
parents:
diff changeset
   149
                    {
hgs
parents:
diff changeset
   150
                    // Indicates that we've initiated a walk - so we can tell whether to close
hgs
parents:
diff changeset
   151
                    // the chunk later on.
hgs
parents:
diff changeset
   152
                    iHeapWalkInitialised = ETrue;
hgs
parents:
diff changeset
   153
                    iWalkHeapCellIndex = 0;
hgs
parents:
diff changeset
   154
hgs
parents:
diff changeset
   155
                    // Walk the client's heap
hgs
parents:
diff changeset
   156
                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - calling heap walker constructor..."));
hgs
parents:
diff changeset
   157
                    RMemSpyDriverHeapWalker heapWalker(iWalkHeap);
hgs
parents:
diff changeset
   158
                    
hgs
parents:
diff changeset
   159
                    TMemSpyDriverLogChanHeapWalkObserver observer( *this );
hgs
parents:
diff changeset
   160
                    heapWalker.SetObserver( &observer );
hgs
parents:
diff changeset
   161
hgs
parents:
diff changeset
   162
                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - starting traversal..."));
hgs
parents:
diff changeset
   163
                    r = heapWalker.Traverse();
hgs
parents:
diff changeset
   164
                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - finished traversal - err: %d", r));
hgs
parents:
diff changeset
   165
                    }
hgs
parents:
diff changeset
   166
hgs
parents:
diff changeset
   167
                // If the initialise process didn't complete successfully, then we must be sure
hgs
parents:
diff changeset
   168
                // to release the associated heap chunk
hgs
parents:
diff changeset
   169
                if  ( r < KErrNone )
hgs
parents:
diff changeset
   170
                    {
hgs
parents:
diff changeset
   171
                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - error scenario - releasing kernel heap chunk copy" ));
hgs
parents:
diff changeset
   172
                    iWalkHeap.Close();
hgs
parents:
diff changeset
   173
                    }
hgs
parents:
diff changeset
   174
                }
hgs
parents:
diff changeset
   175
            else
hgs
parents:
diff changeset
   176
                {
hgs
parents:
diff changeset
   177
                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - parent process not suspended => KErrAccessDenied"));
hgs
parents:
diff changeset
   178
                r = KErrAccessDenied;
hgs
parents:
diff changeset
   179
                }
hgs
parents:
diff changeset
   180
            
hgs
parents:
diff changeset
   181
	        CloseTempObject();
hgs
parents:
diff changeset
   182
            }
hgs
parents:
diff changeset
   183
        else
hgs
parents:
diff changeset
   184
            {
hgs
parents:
diff changeset
   185
    	    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - thread not found"));
hgs
parents:
diff changeset
   186
		    }
hgs
parents:
diff changeset
   187
        }
hgs
parents:
diff changeset
   188
    else
hgs
parents:
diff changeset
   189
        {
hgs
parents:
diff changeset
   190
    	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - params read error: %d", r));
hgs
parents:
diff changeset
   191
        }
hgs
parents:
diff changeset
   192
hgs
parents:
diff changeset
   193
	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit() - END - ret: %d", r));
hgs
parents:
diff changeset
   194
    return r;
hgs
parents:
diff changeset
   195
    }
hgs
parents:
diff changeset
   196
hgs
parents:
diff changeset
   197
hgs
parents:
diff changeset
   198
TInt DMemSpyDriverLogChanHeapWalkUser::WalkHeapNextCell( TUint aTid, TMemSpyDriverInternalWalkHeapParamsCell* aParams )
hgs
parents:
diff changeset
   199
    {
hgs
parents:
diff changeset
   200
    const TInt walkedHeapCellCount = iWalkHeapCells.Count();
hgs
parents:
diff changeset
   201
	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell() - START - current cell count: %d", walkedHeapCellCount));
hgs
parents:
diff changeset
   202
    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
hgs
parents:
diff changeset
   203
hgs
parents:
diff changeset
   204
    // Open the original thread
hgs
parents:
diff changeset
   205
	TInt r = OpenTempObject( aTid, EThread );
hgs
parents:
diff changeset
   206
	if  ( r == KErrNone )
hgs
parents:
diff changeset
   207
		{
hgs
parents:
diff changeset
   208
        // Get the thread handle and that we have suspended the process' threads
hgs
parents:
diff changeset
   209
        DThread* thread = (DThread*) TempObject();
hgs
parents:
diff changeset
   210
        if  ( SuspensionManager().IsSuspended( *thread ) )
hgs
parents:
diff changeset
   211
            {
hgs
parents:
diff changeset
   212
            NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   213
hgs
parents:
diff changeset
   214
            if  ( walkedHeapCellCount > 0 && iWalkHeapCellIndex >= 0 && iWalkHeapCellIndex < walkedHeapCellCount )
hgs
parents:
diff changeset
   215
                {
hgs
parents:
diff changeset
   216
                // Write back head cell to user-space
hgs
parents:
diff changeset
   217
                TMemSpyDriverInternalWalkHeapParamsCell cell( iWalkHeapCells[ iWalkHeapCellIndex++ ] );
hgs
parents:
diff changeset
   218
                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell - returning... cellType: %1d, addr: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", cell.iCellType, cell.iCellAddress, cell.iLength, cell.iNestingLevel, cell.iAllocNumber ));
hgs
parents:
diff changeset
   219
 
hgs
parents:
diff changeset
   220
                r = Kern::ThreadRawWrite( &ClientThread(), aParams, &cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) );
hgs
parents:
diff changeset
   221
                if  ( r != KErrNone )
hgs
parents:
diff changeset
   222
                    {
hgs
parents:
diff changeset
   223
    	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell - params read error: %d", r));
hgs
parents:
diff changeset
   224
                    }
hgs
parents:
diff changeset
   225
                }
hgs
parents:
diff changeset
   226
            else
hgs
parents:
diff changeset
   227
                {
hgs
parents:
diff changeset
   228
                r = KErrEof;
hgs
parents:
diff changeset
   229
                }
hgs
parents:
diff changeset
   230
hgs
parents:
diff changeset
   231
            NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   232
            }
hgs
parents:
diff changeset
   233
        else
hgs
parents:
diff changeset
   234
            {
hgs
parents:
diff changeset
   235
            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell - parent process not suspended => KErrAccessDenied"));
hgs
parents:
diff changeset
   236
            r = KErrAccessDenied;
hgs
parents:
diff changeset
   237
            }
hgs
parents:
diff changeset
   238
    
hgs
parents:
diff changeset
   239
        CloseTempObject();
hgs
parents:
diff changeset
   240
        }
hgs
parents:
diff changeset
   241
    else
hgs
parents:
diff changeset
   242
        {
hgs
parents:
diff changeset
   243
    	Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell - thread not found");
hgs
parents:
diff changeset
   244
		}
hgs
parents:
diff changeset
   245
    //    
hgs
parents:
diff changeset
   246
	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell() - END - ret: %d", r));
hgs
parents:
diff changeset
   247
    return r;
hgs
parents:
diff changeset
   248
    }
hgs
parents:
diff changeset
   249
hgs
parents:
diff changeset
   250
hgs
parents:
diff changeset
   251
TInt DMemSpyDriverLogChanHeapWalkUser::WalkHeapClose()
hgs
parents:
diff changeset
   252
    {
hgs
parents:
diff changeset
   253
    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose() - START"));
hgs
parents:
diff changeset
   254
    //
hgs
parents:
diff changeset
   255
    if  ( iHeapWalkInitialised )
hgs
parents:
diff changeset
   256
        {
hgs
parents:
diff changeset
   257
        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose - heap walk was still open..."));
hgs
parents:
diff changeset
   258
      	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   259
hgs
parents:
diff changeset
   260
		iWalkHeap.Close();
hgs
parents:
diff changeset
   261
hgs
parents:
diff changeset
   262
        // Discard handled cells
hgs
parents:
diff changeset
   263
        iWalkHeapCells.Reset();
hgs
parents:
diff changeset
   264
hgs
parents:
diff changeset
   265
        iHeapWalkInitialised = EFalse;
hgs
parents:
diff changeset
   266
hgs
parents:
diff changeset
   267
    	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   268
        }
hgs
parents:
diff changeset
   269
    //
hgs
parents:
diff changeset
   270
    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose() - END"));
hgs
parents:
diff changeset
   271
    return KErrNone;
hgs
parents:
diff changeset
   272
    }
hgs
parents:
diff changeset
   273
hgs
parents:
diff changeset
   274
hgs
parents:
diff changeset
   275
TInt DMemSpyDriverLogChanHeapWalkUser::WalkHeapReadCellData(TMemSpyDriverInternalWalkHeapCellDataReadParams* aParams)
hgs
parents:
diff changeset
   276
    {
hgs
parents:
diff changeset
   277
    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
hgs
parents:
diff changeset
   278
    //
hgs
parents:
diff changeset
   279
	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable));
hgs
parents:
diff changeset
   280
    //
hgs
parents:
diff changeset
   281
	TMemSpyDriverInternalWalkHeapCellDataReadParams params;
hgs
parents:
diff changeset
   282
    TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverInternalWalkHeapCellDataReadParams) );
hgs
parents:
diff changeset
   283
    if  ( r != KErrNone )
hgs
parents:
diff changeset
   284
        {
hgs
parents:
diff changeset
   285
    	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END - params read error: %d", r));
hgs
parents:
diff changeset
   286
        return r;
hgs
parents:
diff changeset
   287
        }
hgs
parents:
diff changeset
   288
    
hgs
parents:
diff changeset
   289
    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cell: 0x%08x, readLen: %8d, writeAddr: 0x%08x", params.iCellAddress, params.iReadLen, params.iDes));
hgs
parents:
diff changeset
   290
hgs
parents:
diff changeset
   291
    // Open the original thread
hgs
parents:
diff changeset
   292
	r = OpenTempObject( iHeapWalkInitialParameters.iTid, EThread );
hgs
parents:
diff changeset
   293
	if  ( r == KErrNone )
hgs
parents:
diff changeset
   294
		{
hgs
parents:
diff changeset
   295
        // Get the thread handle
hgs
parents:
diff changeset
   296
        DThread* thread = (DThread*) TempObject();
hgs
parents:
diff changeset
   297
hgs
parents:
diff changeset
   298
        // Check the threads in the process are suspended
hgs
parents:
diff changeset
   299
        if  ( SuspensionManager().IsSuspended( *thread ) )
hgs
parents:
diff changeset
   300
            {
hgs
parents:
diff changeset
   301
            // Check we can find the cell in the cell list...
hgs
parents:
diff changeset
   302
            const TMemSpyDriverInternalWalkHeapParamsCell* cell = CellInfoForSpecificAddress( params.iCellAddress );
hgs
parents:
diff changeset
   303
hgs
parents:
diff changeset
   304
            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cell: 0x%08x for address: 0x%08x", cell, params.iCellAddress ));
hgs
parents:
diff changeset
   305
hgs
parents:
diff changeset
   306
            if  ( cell )
hgs
parents:
diff changeset
   307
                {
hgs
parents:
diff changeset
   308
                const TInt cellLen = cell->iLength;
hgs
parents:
diff changeset
   309
                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellLen: %d", cellLen ));
hgs
parents:
diff changeset
   310
hgs
parents:
diff changeset
   311
                if  ( params.iReadLen <= cellLen )
hgs
parents:
diff changeset
   312
                    {
hgs
parents:
diff changeset
   313
hgs
parents:
diff changeset
   314
                    // Get user side descriptor length info
hgs
parents:
diff changeset
   315
         	        TInt destLen = 0;
hgs
parents:
diff changeset
   316
        	        TInt destMax = 0;
hgs
parents:
diff changeset
   317
                    TUint8* destPtr = NULL;
hgs
parents:
diff changeset
   318
hgs
parents:
diff changeset
   319
                    r = Kern::ThreadGetDesInfo( &ClientThread(), params.iDes, destLen, destMax, destPtr, ETrue );
hgs
parents:
diff changeset
   320
        	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", params.iDes, destPtr, destLen, destMax, r ));
hgs
parents:
diff changeset
   321
hgs
parents:
diff changeset
   322
                    // Work out the start offset for the data...
hgs
parents:
diff changeset
   323
                    if  ( r == KErrNone && destMax >= params.iReadLen )
hgs
parents:
diff changeset
   324
                        {
hgs
parents:
diff changeset
   325
                        const TAny* srcPos = ((TUint8*) cell->iCellAddress);
hgs
parents:
diff changeset
   326
        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - srcPos: 0x%08x", srcPos ));
hgs
parents:
diff changeset
   327
hgs
parents:
diff changeset
   328
                        // Read some data 
hgs
parents:
diff changeset
   329
                        r = Kern::ThreadRawRead( thread, srcPos, destPtr, params.iReadLen );
hgs
parents:
diff changeset
   330
    	                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - read from thread returned: %d", r));
hgs
parents:
diff changeset
   331
hgs
parents:
diff changeset
   332
                        if  ( r == KErrNone )
hgs
parents:
diff changeset
   333
                            {
hgs
parents:
diff changeset
   334
                            // Client will update descriptor length in this situation.
hgs
parents:
diff changeset
   335
                            r = params.iReadLen;
hgs
parents:
diff changeset
   336
                            }
hgs
parents:
diff changeset
   337
                        }
hgs
parents:
diff changeset
   338
                    else
hgs
parents:
diff changeset
   339
                        {
hgs
parents:
diff changeset
   340
                        if  ( r != KErrBadDescriptor )
hgs
parents:
diff changeset
   341
                            {
hgs
parents:
diff changeset
   342
                            r = KErrArgument;                
hgs
parents:
diff changeset
   343
            	            Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - user-descriptor isnt big enough for requested data" );
hgs
parents:
diff changeset
   344
                            }
hgs
parents:
diff changeset
   345
                        else
hgs
parents:
diff changeset
   346
                            {
hgs
parents:
diff changeset
   347
            	            Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - bad or non-writable user-side descriptor" );
hgs
parents:
diff changeset
   348
                            }
hgs
parents:
diff changeset
   349
                        }
hgs
parents:
diff changeset
   350
                    }
hgs
parents:
diff changeset
   351
                else
hgs
parents:
diff changeset
   352
                    {
hgs
parents:
diff changeset
   353
                    r = KErrArgument;
hgs
parents:
diff changeset
   354
        	        Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - read length is bigger than cell length");
hgs
parents:
diff changeset
   355
                    }
hgs
parents:
diff changeset
   356
                }
hgs
parents:
diff changeset
   357
            else
hgs
parents:
diff changeset
   358
                {
hgs
parents:
diff changeset
   359
                r = KErrArgument;
hgs
parents:
diff changeset
   360
                Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - no cell at user supplied address!");
hgs
parents:
diff changeset
   361
                }
hgs
parents:
diff changeset
   362
            }
hgs
parents:
diff changeset
   363
        else
hgs
parents:
diff changeset
   364
            {
hgs
parents:
diff changeset
   365
            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - parent process not suspended => KErrAccessDenied"));
hgs
parents:
diff changeset
   366
            r = KErrAccessDenied;
hgs
parents:
diff changeset
   367
            }
hgs
parents:
diff changeset
   368
hgs
parents:
diff changeset
   369
        CloseTempObject();
hgs
parents:
diff changeset
   370
        }
hgs
parents:
diff changeset
   371
    else
hgs
parents:
diff changeset
   372
        {
hgs
parents:
diff changeset
   373
    	Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - thread not found");
hgs
parents:
diff changeset
   374
		}
hgs
parents:
diff changeset
   375
    //
hgs
parents:
diff changeset
   376
    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END result=%d", r));
hgs
parents:
diff changeset
   377
    return r;
hgs
parents:
diff changeset
   378
    }
hgs
parents:
diff changeset
   379
hgs
parents:
diff changeset
   380
hgs
parents:
diff changeset
   381
TInt DMemSpyDriverLogChanHeapWalkUser::WalkHeapGetCellInfo( TAny* aCellAddress, TMemSpyDriverInternalWalkHeapParamsCell* aParams )
hgs
parents:
diff changeset
   382
    {
hgs
parents:
diff changeset
   383
    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
hgs
parents:
diff changeset
   384
    //
hgs
parents:
diff changeset
   385
    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable));
hgs
parents:
diff changeset
   386
    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - cell: 0x%08x", aCellAddress));
hgs
parents:
diff changeset
   387
hgs
parents:
diff changeset
   388
    // Open the original thread
hgs
parents:
diff changeset
   389
	TInt r = OpenTempObject( iHeapWalkInitialParameters.iTid, EThread );
hgs
parents:
diff changeset
   390
	if (r != KErrNone)
hgs
parents:
diff changeset
   391
		{
hgs
parents:
diff changeset
   392
    	Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END - thread not found");
hgs
parents:
diff changeset
   393
		return r;
hgs
parents:
diff changeset
   394
		}
hgs
parents:
diff changeset
   395
hgs
parents:
diff changeset
   396
    // Get the thread handle
hgs
parents:
diff changeset
   397
    DThread* thread = (DThread*) TempObject();
hgs
parents:
diff changeset
   398
hgs
parents:
diff changeset
   399
    // Check the threads in the process are suspended
hgs
parents:
diff changeset
   400
    if  ( !SuspensionManager().IsSuspended( *thread ) )
hgs
parents:
diff changeset
   401
        {
hgs
parents:
diff changeset
   402
        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - END - parent process not suspended => KErrAccessDenied"));
hgs
parents:
diff changeset
   403
        CloseTempObject();
hgs
parents:
diff changeset
   404
        return KErrAccessDenied;
hgs
parents:
diff changeset
   405
        }
hgs
parents:
diff changeset
   406
hgs
parents:
diff changeset
   407
    // Check we can find the cell in the cell list...
hgs
parents:
diff changeset
   408
    const TMemSpyDriverInternalWalkHeapParamsCell* cell = CellInfoForSpecificAddress( aCellAddress );
hgs
parents:
diff changeset
   409
    if  ( cell == NULL )
hgs
parents:
diff changeset
   410
        {
hgs
parents:
diff changeset
   411
        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - no exact match for address: 0x%08x...", aCellAddress));
hgs
parents:
diff changeset
   412
        
hgs
parents:
diff changeset
   413
        // If the cell still wasn't found, then let's look for any heap cell that contains
hgs
parents:
diff changeset
   414
        // the client-specified address (i.e. find the heap cell that contains the specified
hgs
parents:
diff changeset
   415
        // address).
hgs
parents:
diff changeset
   416
        if  ( cell == NULL )
hgs
parents:
diff changeset
   417
            {
hgs
parents:
diff changeset
   418
            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - still couldnt find cell by exact address. Searching for the cell that contains the specified address..."));
hgs
parents:
diff changeset
   419
            cell = CellInfoForAddressWithinCellRange( aCellAddress );
hgs
parents:
diff changeset
   420
            }
hgs
parents:
diff changeset
   421
        }
hgs
parents:
diff changeset
   422
hgs
parents:
diff changeset
   423
    if  ( cell )
hgs
parents:
diff changeset
   424
        {
hgs
parents:
diff changeset
   425
        // Have enough info to write back to client now
hgs
parents:
diff changeset
   426
        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 ));
hgs
parents:
diff changeset
   427
        r = Kern::ThreadRawWrite( &ClientThread(), aParams, cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) );
hgs
parents:
diff changeset
   428
        }
hgs
parents:
diff changeset
   429
    else
hgs
parents:
diff changeset
   430
        {
hgs
parents:
diff changeset
   431
        r = KErrArgument;
hgs
parents:
diff changeset
   432
        Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - no cell at user supplied address!");
hgs
parents:
diff changeset
   433
        }
hgs
parents:
diff changeset
   434
    
hgs
parents:
diff changeset
   435
    CloseTempObject();
hgs
parents:
diff changeset
   436
    //
hgs
parents:
diff changeset
   437
    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END result=%d", r));
hgs
parents:
diff changeset
   438
    return r;
hgs
parents:
diff changeset
   439
    }
hgs
parents:
diff changeset
   440
hgs
parents:
diff changeset
   441
hgs
parents:
diff changeset
   442
hgs
parents:
diff changeset
   443
hgs
parents:
diff changeset
   444
hgs
parents:
diff changeset
   445
hgs
parents:
diff changeset
   446
hgs
parents:
diff changeset
   447
hgs
parents:
diff changeset
   448
hgs
parents:
diff changeset
   449
hgs
parents:
diff changeset
   450
hgs
parents:
diff changeset
   451
hgs
parents:
diff changeset
   452
hgs
parents:
diff changeset
   453
hgs
parents:
diff changeset
   454
hgs
parents:
diff changeset
   455
hgs
parents:
diff changeset
   456
hgs
parents:
diff changeset
   457
hgs
parents:
diff changeset
   458
hgs
parents:
diff changeset
   459
hgs
parents:
diff changeset
   460
hgs
parents:
diff changeset
   461
hgs
parents:
diff changeset
   462
hgs
parents:
diff changeset
   463
hgs
parents:
diff changeset
   464
hgs
parents:
diff changeset
   465
hgs
parents:
diff changeset
   466
hgs
parents:
diff changeset
   467
const TMemSpyDriverInternalWalkHeapParamsCell* DMemSpyDriverLogChanHeapWalkUser::CellInfoForAddressWithinCellRange( TAny* aAddress ) const
hgs
parents:
diff changeset
   468
    {
hgs
parents:
diff changeset
   469
    const TMemSpyDriverInternalWalkHeapParamsCell* ret = NULL;
hgs
parents:
diff changeset
   470
    //
hgs
parents:
diff changeset
   471
    const TInt count = iWalkHeapCells.Count();
hgs
parents:
diff changeset
   472
    for(TInt i=0; i<count; i++)
hgs
parents:
diff changeset
   473
        {
hgs
parents:
diff changeset
   474
        const TMemSpyDriverInternalWalkHeapParamsCell& item = iWalkHeapCells[i];
hgs
parents:
diff changeset
   475
        const TAny* cellExtent = (TAny*) (TUint32( item.iCellAddress ) + item.iLength);
hgs
parents:
diff changeset
   476
        //
hgs
parents:
diff changeset
   477
        if  ( aAddress >= item.iCellAddress && aAddress < cellExtent )
hgs
parents:
diff changeset
   478
            {
hgs
parents:
diff changeset
   479
            ret = &item;
hgs
parents:
diff changeset
   480
            }
hgs
parents:
diff changeset
   481
        }
hgs
parents:
diff changeset
   482
    //
hgs
parents:
diff changeset
   483
    return ret;
hgs
parents:
diff changeset
   484
    }
hgs
parents:
diff changeset
   485
hgs
parents:
diff changeset
   486
hgs
parents:
diff changeset
   487
const TMemSpyDriverInternalWalkHeapParamsCell* DMemSpyDriverLogChanHeapWalkUser::CellInfoForSpecificAddress( TAny* aAddress ) const
hgs
parents:
diff changeset
   488
    {
hgs
parents:
diff changeset
   489
    const TMemSpyDriverInternalWalkHeapParamsCell* ret = NULL;
hgs
parents:
diff changeset
   490
    //
hgs
parents:
diff changeset
   491
    const TInt count = iWalkHeapCells.Count();
hgs
parents:
diff changeset
   492
    for(TInt i=0; i<count; i++)
hgs
parents:
diff changeset
   493
        {
hgs
parents:
diff changeset
   494
        const TMemSpyDriverInternalWalkHeapParamsCell& item = iWalkHeapCells[i];
hgs
parents:
diff changeset
   495
        if  ( item.iCellAddress == aAddress )
hgs
parents:
diff changeset
   496
            {
hgs
parents:
diff changeset
   497
            ret = &item;
hgs
parents:
diff changeset
   498
            }
hgs
parents:
diff changeset
   499
        }
hgs
parents:
diff changeset
   500
    //
hgs
parents:
diff changeset
   501
    return ret;
hgs
parents:
diff changeset
   502
    }
hgs
parents:
diff changeset
   503
hgs
parents:
diff changeset
   504
hgs
parents:
diff changeset
   505
hgs
parents:
diff changeset
   506
hgs
parents:
diff changeset
   507
hgs
parents:
diff changeset
   508
hgs
parents:
diff changeset
   509
hgs
parents:
diff changeset
   510
hgs
parents:
diff changeset
   511
hgs
parents:
diff changeset
   512
hgs
parents:
diff changeset
   513
hgs
parents:
diff changeset
   514
hgs
parents:
diff changeset
   515
hgs
parents:
diff changeset
   516
hgs
parents:
diff changeset
   517
hgs
parents:
diff changeset
   518
hgs
parents:
diff changeset
   519
TBool DMemSpyDriverLogChanHeapWalkUser::WalkerHandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
hgs
parents:
diff changeset
   520
    {
hgs
parents:
diff changeset
   521
    TInt error = KErrNone;
hgs
parents:
diff changeset
   522
    //
hgs
parents:
diff changeset
   523
    if  ( iHeapWalkInitialised )
hgs
parents:
diff changeset
   524
        {
hgs
parents:
diff changeset
   525
        TMemSpyDriverInternalWalkHeapParamsCell cell;
hgs
parents:
diff changeset
   526
        cell.iCellType = aCellType;
hgs
parents:
diff changeset
   527
	    cell.iCellAddress = aCellAddress;
hgs
parents:
diff changeset
   528
	    cell.iLength = aLength;
hgs
parents:
diff changeset
   529
	    cell.iNestingLevel = aNestingLevel;
hgs
parents:
diff changeset
   530
	    cell.iAllocNumber = aAllocNumber;
hgs
parents:
diff changeset
   531
        //
hgs
parents:
diff changeset
   532
  	    NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   533
        error = iWalkHeapCells.Append( cell );
hgs
parents:
diff changeset
   534
  	    NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   535
        }
hgs
parents:
diff changeset
   536
    //
hgs
parents:
diff changeset
   537
    return ( error == KErrNone );
hgs
parents:
diff changeset
   538
    }