perfsrv/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanChunks.cpp
author hgs
Tue, 26 Oct 2010 16:20:32 +0300
changeset 62 1c2bb2fc7c87
parent 51 98307c651589
permissions -rw-r--r--
201043
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
51
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 "MemSpyDriverLogChanChunks.h"
hgs
parents:
diff changeset
    19
hgs
parents:
diff changeset
    20
// System includes
hgs
parents:
diff changeset
    21
#include <memspy/driver/memspydriverobjectsshared.h>
hgs
parents:
diff changeset
    22
hgs
parents:
diff changeset
    23
// Shared includes
hgs
parents:
diff changeset
    24
#include "MemSpyDriverOpCodes.h"
hgs
parents:
diff changeset
    25
#include "MemSpyDriverObjectsInternal.h"
hgs
parents:
diff changeset
    26
hgs
parents:
diff changeset
    27
// User includes
hgs
parents:
diff changeset
    28
#include "MemSpyDriverUtils.h"
hgs
parents:
diff changeset
    29
#include "MemSpyDriverDevice.h"
hgs
parents:
diff changeset
    30
#include "MemSpyDriverOSAdaption.h"
hgs
parents:
diff changeset
    31
hgs
parents:
diff changeset
    32
// Constants
hgs
parents:
diff changeset
    33
_LIT8( KMemSpyLitDllDollarData, "DLL$DATA" );
hgs
parents:
diff changeset
    34
_LIT8( KMemSpyLitDollarDat, "$DAT" );
hgs
parents:
diff changeset
    35
_LIT8( KMemSpyLitDollarCode, "$CODE" );
hgs
parents:
diff changeset
    36
_LIT8( KMemSpyLitDollarGlobalCode, "GLOBAL$CODE" );
hgs
parents:
diff changeset
    37
_LIT8( KMemSpyLitLocalObject, "Local-" );
hgs
parents:
diff changeset
    38
hgs
parents:
diff changeset
    39
hgs
parents:
diff changeset
    40
DMemSpyDriverLogChanChunks::DMemSpyDriverLogChanChunks( DMemSpyDriverDevice& aDevice, DThread& aThread )
hgs
parents:
diff changeset
    41
:   DMemSpyDriverLogChanBase( aDevice, aThread )
hgs
parents:
diff changeset
    42
    {
hgs
parents:
diff changeset
    43
	TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::DMemSpyDriverLogChanChunks() - this: 0x%08x", this ));
hgs
parents:
diff changeset
    44
    }
hgs
parents:
diff changeset
    45
hgs
parents:
diff changeset
    46
hgs
parents:
diff changeset
    47
DMemSpyDriverLogChanChunks::~DMemSpyDriverLogChanChunks()
hgs
parents:
diff changeset
    48
	{
hgs
parents:
diff changeset
    49
	TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::~DMemSpyDriverLogChanChunks() - START - this: 0x%08x", this ));
hgs
parents:
diff changeset
    50
hgs
parents:
diff changeset
    51
	TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::~DMemSpyDriverLogChanChunks() - END - this: 0x%08x", this ));
hgs
parents:
diff changeset
    52
	}
hgs
parents:
diff changeset
    53
hgs
parents:
diff changeset
    54
hgs
parents:
diff changeset
    55
hgs
parents:
diff changeset
    56
TInt DMemSpyDriverLogChanChunks::Request( TInt aFunction, TAny* a1, TAny* a2 )
hgs
parents:
diff changeset
    57
	{
hgs
parents:
diff changeset
    58
	TInt r = DMemSpyDriverLogChanBase::Request( aFunction, a1, a2 );
hgs
parents:
diff changeset
    59
    if  ( r == KErrNone )
hgs
parents:
diff changeset
    60
        {
hgs
parents:
diff changeset
    61
	    switch( aFunction )
hgs
parents:
diff changeset
    62
		    {
hgs
parents:
diff changeset
    63
        case EMemSpyDriverOpCodeChunkGetHandles:
hgs
parents:
diff changeset
    64
            r = GetChunkHandles( (TMemSpyDriverInternalChunkHandleParams*) a1 );
hgs
parents:
diff changeset
    65
            break;
hgs
parents:
diff changeset
    66
        case EMemSpyDriverOpCodeChunkGetInfo:
hgs
parents:
diff changeset
    67
            r = GetChunkInfo( (TMemSpyDriverInternalChunkInfoParams*) a1 );
hgs
parents:
diff changeset
    68
            break;
hgs
parents:
diff changeset
    69
hgs
parents:
diff changeset
    70
        default:
hgs
parents:
diff changeset
    71
            r = KErrNotSupported;
hgs
parents:
diff changeset
    72
		    break;
hgs
parents:
diff changeset
    73
    		}
hgs
parents:
diff changeset
    74
        }
hgs
parents:
diff changeset
    75
    //
hgs
parents:
diff changeset
    76
    return r;
hgs
parents:
diff changeset
    77
	}
hgs
parents:
diff changeset
    78
hgs
parents:
diff changeset
    79
hgs
parents:
diff changeset
    80
TBool DMemSpyDriverLogChanChunks::IsHandler( TInt aFunction ) const
hgs
parents:
diff changeset
    81
    {
hgs
parents:
diff changeset
    82
    return ( aFunction > EMemSpyDriverOpCodeChunkBase && aFunction < EMemSpyDriverOpCodeChunkEnd );
hgs
parents:
diff changeset
    83
    }
hgs
parents:
diff changeset
    84
hgs
parents:
diff changeset
    85
hgs
parents:
diff changeset
    86
hgs
parents:
diff changeset
    87
hgs
parents:
diff changeset
    88
hgs
parents:
diff changeset
    89
hgs
parents:
diff changeset
    90
hgs
parents:
diff changeset
    91
hgs
parents:
diff changeset
    92
hgs
parents:
diff changeset
    93
hgs
parents:
diff changeset
    94
hgs
parents:
diff changeset
    95
hgs
parents:
diff changeset
    96
hgs
parents:
diff changeset
    97
hgs
parents:
diff changeset
    98
hgs
parents:
diff changeset
    99
hgs
parents:
diff changeset
   100
hgs
parents:
diff changeset
   101
hgs
parents:
diff changeset
   102
hgs
parents:
diff changeset
   103
hgs
parents:
diff changeset
   104
TInt DMemSpyDriverLogChanChunks::GetChunkHandles( TMemSpyDriverInternalChunkHandleParams* aParams )
hgs
parents:
diff changeset
   105
    {
hgs
parents:
diff changeset
   106
	TMemSpyDriverInternalChunkHandleParams params;
hgs
parents:
diff changeset
   107
    TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverInternalChunkHandleParams) );
hgs
parents:
diff changeset
   108
    if  ( r != KErrNone )
hgs
parents:
diff changeset
   109
        {
hgs
parents:
diff changeset
   110
    	TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - END - params read error: %d", r));
hgs
parents:
diff changeset
   111
        return r;
hgs
parents:
diff changeset
   112
        }
hgs
parents:
diff changeset
   113
hgs
parents:
diff changeset
   114
	const TInt maxCount = params.iMaxCount;
hgs
parents:
diff changeset
   115
	TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - START - id: %d,  maxCount: %d, type: %d", params.iId, maxCount, params.iType));
62
hgs
parents: 51
diff changeset
   116
    
51
hgs
parents:
diff changeset
   117
    DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread();
hgs
parents:
diff changeset
   118
    DMemSpyDriverOSAdaptionDProcess& processAdaption = OSAdaption().DProcess();
hgs
parents:
diff changeset
   119
hgs
parents:
diff changeset
   120
hgs
parents:
diff changeset
   121
    // This variable holds the number of handles that we have already
hgs
parents:
diff changeset
   122
    // written to the client-side.
hgs
parents:
diff changeset
   123
    TInt currentWriteIndex = 0;
hgs
parents:
diff changeset
   124
	
hgs
parents:
diff changeset
   125
    if  ( params.iType == EMemSpyDriverPrivateObjectTypeProcess || params.iType == EMemSpyDriverPrivateObjectTypeThread )
hgs
parents:
diff changeset
   126
        {
hgs
parents:
diff changeset
   127
        if  ( params.iType == EMemSpyDriverPrivateObjectTypeThread )
hgs
parents:
diff changeset
   128
    	    {
hgs
parents:
diff changeset
   129
	        r = OpenTempObject( params.iId, EThread );
hgs
parents:
diff changeset
   130
            if  ( r == KErrNone )
hgs
parents:
diff changeset
   131
                {
hgs
parents:
diff changeset
   132
                // Open the owning process instead, so that we can see which chunks are mapped
hgs
parents:
diff changeset
   133
                // into the thread.
hgs
parents:
diff changeset
   134
                DThread* thread = (DThread*) TempObject();
hgs
parents:
diff changeset
   135
                DProcess* process = threadAdaption.GetOwningProcess( *thread );
hgs
parents:
diff changeset
   136
                if  ( process )
hgs
parents:
diff changeset
   137
                    {
hgs
parents:
diff changeset
   138
                    const TUint parentProcessId = processAdaption.GetId( *process );
hgs
parents:
diff changeset
   139
                    CloseTempObject();
hgs
parents:
diff changeset
   140
                    r = OpenTempObject( parentProcessId, EProcess );
hgs
parents:
diff changeset
   141
                    }
hgs
parents:
diff changeset
   142
                else
hgs
parents:
diff changeset
   143
                    {
hgs
parents:
diff changeset
   144
                    CloseTempObject();
hgs
parents:
diff changeset
   145
                    r = KErrNotFound;
hgs
parents:
diff changeset
   146
                    }
hgs
parents:
diff changeset
   147
                }
hgs
parents:
diff changeset
   148
       	    }
hgs
parents:
diff changeset
   149
        else
hgs
parents:
diff changeset
   150
            {
hgs
parents:
diff changeset
   151
	        r = OpenTempObject( params.iId, EProcess );
hgs
parents:
diff changeset
   152
            }
hgs
parents:
diff changeset
   153
hgs
parents:
diff changeset
   154
        // Handle error opening correct process
hgs
parents:
diff changeset
   155
        if (r != KErrNone)
hgs
parents:
diff changeset
   156
    	    {
hgs
parents:
diff changeset
   157
    	    Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - END - parent process not found");
hgs
parents:
diff changeset
   158
    	    return r;
hgs
parents:
diff changeset
   159
    	    }
hgs
parents:
diff changeset
   160
   
hgs
parents:
diff changeset
   161
        DProcess* process = (DProcess*) TempObject();
hgs
parents:
diff changeset
   162
	    NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   163
hgs
parents:
diff changeset
   164
	    // Iterate through each handle in the process
hgs
parents:
diff changeset
   165
	    MemSpyObjectIx* processHandles = processAdaption.GetHandles( *process );
hgs
parents:
diff changeset
   166
		MemSpyObjectIx_HandleLookupLock();
hgs
parents:
diff changeset
   167
        const TInt processHandleCount = processHandles->Count();
hgs
parents:
diff changeset
   168
		MemSpyObjectIx_HandleLookupUnlock();
hgs
parents:
diff changeset
   169
hgs
parents:
diff changeset
   170
	    for( TInt processHandleIndex = 0; processHandleIndex<processHandleCount && r == KErrNone && currentWriteIndex < maxCount; processHandleIndex++ )
hgs
parents:
diff changeset
   171
    	    {
hgs
parents:
diff changeset
   172
    	    // Get a handle from the process container...
hgs
parents:
diff changeset
   173
            MemSpyObjectIx_HandleLookupLock();
hgs
parents:
diff changeset
   174
			if (processHandleIndex >= processHandles->Count()) break; // Count may have changed in the meantime
hgs
parents:
diff changeset
   175
    	    DObject* object = (*processHandles)[ processHandleIndex ];
hgs
parents:
diff changeset
   176
			if (object && object->Open() != KErrNone) object = NULL;
hgs
parents:
diff changeset
   177
			MemSpyObjectIx_HandleLookupUnlock();
hgs
parents:
diff changeset
   178
            
hgs
parents:
diff changeset
   179
            if  ( object )
hgs
parents:
diff changeset
   180
                {
hgs
parents:
diff changeset
   181
                const TObjectType objectType = processAdaption.GetObjectType( *object );
hgs
parents:
diff changeset
   182
                if ( objectType == EChunk )
hgs
parents:
diff changeset
   183
                    {
hgs
parents:
diff changeset
   184
                    DChunk* chunk = (DChunk*) object;
hgs
parents:
diff changeset
   185
                    TAny* handle = (TAny*) chunk;
hgs
parents:
diff changeset
   186
                    r = Kern::ThreadRawWrite( &ClientThread(), params.iHandles + currentWriteIndex, &handle, sizeof(TAny*) );
hgs
parents:
diff changeset
   187
                    if  ( r == KErrNone )
hgs
parents:
diff changeset
   188
                        {
hgs
parents:
diff changeset
   189
                        ++currentWriteIndex;
hgs
parents:
diff changeset
   190
                        }
hgs
parents:
diff changeset
   191
                    }
hgs
parents:
diff changeset
   192
				object->Close(NULL);
hgs
parents:
diff changeset
   193
                }
hgs
parents:
diff changeset
   194
    	    }
hgs
parents:
diff changeset
   195
hgs
parents:
diff changeset
   196
        // If we were asked for process-related chunks, also check the chunk container
hgs
parents:
diff changeset
   197
        // for entries which we don't have handles to, but do refer to our process
hgs
parents:
diff changeset
   198
        // Need a listing of all chunks in the system. Let client filter duplicates.
hgs
parents:
diff changeset
   199
        DObjectCon* container = Kern::Containers()[ EChunk ];
hgs
parents:
diff changeset
   200
        container->Wait();
hgs
parents:
diff changeset
   201
        //
hgs
parents:
diff changeset
   202
        const TInt count = container->Count();
hgs
parents:
diff changeset
   203
        for( TInt i=0; i<count && r == KErrNone && currentWriteIndex < maxCount; i++ )
hgs
parents:
diff changeset
   204
            {
hgs
parents:
diff changeset
   205
            DChunk* chunk= (DChunk*) (*container)[ i ];
hgs
parents:
diff changeset
   206
            //
hgs
parents:
diff changeset
   207
            const TBool isRelated = DoesChunkRelateToProcess( *chunk, TempObjectAsProcess() );
hgs
parents:
diff changeset
   208
            if  ( isRelated )
hgs
parents:
diff changeset
   209
                {
hgs
parents:
diff changeset
   210
                r = Kern::ThreadRawWrite( &ClientThread(), params.iHandles + currentWriteIndex, &chunk, sizeof(TAny*) );
hgs
parents:
diff changeset
   211
                if  ( r == KErrNone )
hgs
parents:
diff changeset
   212
                    {
hgs
parents:
diff changeset
   213
                    ++currentWriteIndex;
hgs
parents:
diff changeset
   214
                    }
hgs
parents:
diff changeset
   215
                }
hgs
parents:
diff changeset
   216
            }
hgs
parents:
diff changeset
   217
        //
hgs
parents:
diff changeset
   218
        container->Signal();
hgs
parents:
diff changeset
   219
        NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   220
hgs
parents:
diff changeset
   221
        CloseTempObject();
hgs
parents:
diff changeset
   222
        }
hgs
parents:
diff changeset
   223
    else
hgs
parents:
diff changeset
   224
        {
hgs
parents:
diff changeset
   225
        // Need a listing of all chunks in the system. Let client filter duplicates.
hgs
parents:
diff changeset
   226
        DObjectCon* container = Kern::Containers()[ EChunk ];
hgs
parents:
diff changeset
   227
        NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   228
        container->Wait();
hgs
parents:
diff changeset
   229
        //
hgs
parents:
diff changeset
   230
        const TInt count = container->Count();
hgs
parents:
diff changeset
   231
        for( TInt i=0; i<count && r == KErrNone && currentWriteIndex < maxCount; i++ )
hgs
parents:
diff changeset
   232
            {
hgs
parents:
diff changeset
   233
            DChunk* chunk= (DChunk*) (*container)[ i ];
hgs
parents:
diff changeset
   234
            //
hgs
parents:
diff changeset
   235
            r = Kern::ThreadRawWrite( &ClientThread(), params.iHandles + currentWriteIndex, &chunk, sizeof(TAny*) );
hgs
parents:
diff changeset
   236
            if  (r == KErrNone)
hgs
parents:
diff changeset
   237
                {
hgs
parents:
diff changeset
   238
                ++currentWriteIndex;
hgs
parents:
diff changeset
   239
                }
hgs
parents:
diff changeset
   240
            }
hgs
parents:
diff changeset
   241
        //
hgs
parents:
diff changeset
   242
        container->Signal();
hgs
parents:
diff changeset
   243
        NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   244
        }
hgs
parents:
diff changeset
   245
	
hgs
parents:
diff changeset
   246
	if  ( r == KErrBadDescriptor )
hgs
parents:
diff changeset
   247
        {
hgs
parents:
diff changeset
   248
        MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor );
hgs
parents:
diff changeset
   249
        }
hgs
parents:
diff changeset
   250
    else
hgs
parents:
diff changeset
   251
        {
hgs
parents:
diff changeset
   252
        const TInt finalWrite = Kern::ThreadRawWrite( &ClientThread(), params.iCountPtr, &currentWriteIndex, sizeof(TInt) );
hgs
parents:
diff changeset
   253
        if  ( r == KErrNone )
hgs
parents:
diff changeset
   254
            {
hgs
parents:
diff changeset
   255
            r = finalWrite;
hgs
parents:
diff changeset
   256
            }
hgs
parents:
diff changeset
   257
        }
hgs
parents:
diff changeset
   258
hgs
parents:
diff changeset
   259
	TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - END - number of handles written to client: %d, ret: %d", currentWriteIndex, r));
hgs
parents:
diff changeset
   260
	return r;
hgs
parents:
diff changeset
   261
    }
hgs
parents:
diff changeset
   262
hgs
parents:
diff changeset
   263
hgs
parents:
diff changeset
   264
TInt DMemSpyDriverLogChanChunks::GetChunkInfo( TMemSpyDriverInternalChunkInfoParams* aParams )
hgs
parents:
diff changeset
   265
    {
hgs
parents:
diff changeset
   266
	TMemSpyDriverInternalChunkInfoParams params;
hgs
parents:
diff changeset
   267
    TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverInternalChunkInfoParams) );
hgs
parents:
diff changeset
   268
    if  ( r != KErrNone )
hgs
parents:
diff changeset
   269
        {
hgs
parents:
diff changeset
   270
    	TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - END - params read error: %d", r));
hgs
parents:
diff changeset
   271
        return r;
hgs
parents:
diff changeset
   272
        }
hgs
parents:
diff changeset
   273
hgs
parents:
diff changeset
   274
    TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - START - handle: 0x%08x", params.iHandle));
hgs
parents:
diff changeset
   275
		
hgs
parents:
diff changeset
   276
	DObjectCon* container = Kern::Containers()[EChunk];
hgs
parents:
diff changeset
   277
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   278
hgs
parents:
diff changeset
   279
    container->Wait();
hgs
parents:
diff changeset
   280
    const TInt count = container->Count();
hgs
parents:
diff changeset
   281
hgs
parents:
diff changeset
   282
    DChunk* foundChunk = NULL;
hgs
parents:
diff changeset
   283
    
hgs
parents:
diff changeset
   284
    for(TInt i=0; i<count; i++)
hgs
parents:
diff changeset
   285
        {
hgs
parents:
diff changeset
   286
        DChunk* chunk = (DChunk*) (*container)[i];
hgs
parents:
diff changeset
   287
        if  ( chunk == params.iHandle )
hgs
parents:
diff changeset
   288
            {
hgs
parents:
diff changeset
   289
            foundChunk = chunk;
hgs
parents:
diff changeset
   290
            TRACE( PrintChunkInfo( *chunk ) );
hgs
parents:
diff changeset
   291
			r = foundChunk->Open();
hgs
parents:
diff changeset
   292
            break;
hgs
parents:
diff changeset
   293
            }
hgs
parents:
diff changeset
   294
        }
hgs
parents:
diff changeset
   295
hgs
parents:
diff changeset
   296
    container->Signal();
hgs
parents:
diff changeset
   297
hgs
parents:
diff changeset
   298
    if  ( foundChunk == NULL )
hgs
parents:
diff changeset
   299
        {
hgs
parents:
diff changeset
   300
    	Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - END - KErrNotFound - couldnt find chunk");
hgs
parents:
diff changeset
   301
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   302
        return KErrNotFound;
hgs
parents:
diff changeset
   303
        }
hgs
parents:
diff changeset
   304
	if (r)
hgs
parents:
diff changeset
   305
		{
hgs
parents:
diff changeset
   306
		Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - END - %d - Failed to open chunk", r);
hgs
parents:
diff changeset
   307
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   308
		return r;
hgs
parents:
diff changeset
   309
		}
hgs
parents:
diff changeset
   310
hgs
parents:
diff changeset
   311
    // Prepare return data
hgs
parents:
diff changeset
   312
    DMemSpyDriverOSAdaptionDChunk& chunkAdaption = OSAdaption().DChunk();
hgs
parents:
diff changeset
   313
    //
hgs
parents:
diff changeset
   314
    params.iBaseAddress = chunkAdaption.GetBase( *foundChunk );
hgs
parents:
diff changeset
   315
    params.iSize = chunkAdaption.GetSize( *foundChunk );
hgs
parents:
diff changeset
   316
    params.iMaxSize = chunkAdaption.GetMaxSize( *foundChunk );
hgs
parents:
diff changeset
   317
    foundChunk->FullName( params.iName );
hgs
parents:
diff changeset
   318
hgs
parents:
diff changeset
   319
    // Mirror the process memory tracker
hgs
parents:
diff changeset
   320
    DProcess* owner = chunkAdaption.GetOwningProcess( *foundChunk );
hgs
parents:
diff changeset
   321
    if  ( owner )
hgs
parents:
diff changeset
   322
        {
hgs
parents:
diff changeset
   323
        params.iOwnerId = OSAdaption().DProcess().GetId( *owner );
hgs
parents:
diff changeset
   324
        }
hgs
parents:
diff changeset
   325
    else
hgs
parents:
diff changeset
   326
        {
hgs
parents:
diff changeset
   327
        owner = static_cast< DProcess* >( chunkAdaption.GetOwner( *foundChunk, EProcess ) );
hgs
parents:
diff changeset
   328
        if  ( owner )
hgs
parents:
diff changeset
   329
            {
hgs
parents:
diff changeset
   330
            params.iOwnerId = OSAdaption().DProcess().GetId( *owner );
hgs
parents:
diff changeset
   331
            }
hgs
parents:
diff changeset
   332
        else
hgs
parents:
diff changeset
   333
            {
hgs
parents:
diff changeset
   334
            params.iOwnerId = chunkAdaption.GetControllingOwnerId( *foundChunk );
hgs
parents:
diff changeset
   335
            }
hgs
parents:
diff changeset
   336
        }
hgs
parents:
diff changeset
   337
hgs
parents:
diff changeset
   338
    // Get type & attribs
hgs
parents:
diff changeset
   339
    params.iType = IdentifyChunkType( *foundChunk );
hgs
parents:
diff changeset
   340
    params.iAttributes = chunkAdaption.GetAttributes( *foundChunk );
hgs
parents:
diff changeset
   341
hgs
parents:
diff changeset
   342
	// Finished with foundChunk
hgs
parents:
diff changeset
   343
	foundChunk->Close(NULL);
hgs
parents:
diff changeset
   344
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   345
    
hgs
parents:
diff changeset
   346
    // Write back to client
hgs
parents:
diff changeset
   347
    r = Kern::ThreadRawWrite( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverInternalChunkInfoParams) );
hgs
parents:
diff changeset
   348
	if  ( r == KErrBadDescriptor )
hgs
parents:
diff changeset
   349
        {
hgs
parents:
diff changeset
   350
        MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor );
hgs
parents:
diff changeset
   351
        }
hgs
parents:
diff changeset
   352
hgs
parents:
diff changeset
   353
	TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - END - handle: 0x%08x, params.iOwnerId: %d, r: %d", params.iHandle, params.iOwnerId, r ));
hgs
parents:
diff changeset
   354
    return r;
hgs
parents:
diff changeset
   355
    }
hgs
parents:
diff changeset
   356
hgs
parents:
diff changeset
   357
hgs
parents:
diff changeset
   358
void DMemSpyDriverLogChanChunks::PrintChunkInfo( DChunk& aChunk )
hgs
parents:
diff changeset
   359
    {
hgs
parents:
diff changeset
   360
    MemSpyDriverUtils::PrintChunkInfo( aChunk, OSAdaption() );
hgs
parents:
diff changeset
   361
    }
hgs
parents:
diff changeset
   362
hgs
parents:
diff changeset
   363
hgs
parents:
diff changeset
   364
TMemSpyDriverChunkType DMemSpyDriverLogChanChunks::IdentifyChunkType( DChunk& aChunk )
hgs
parents:
diff changeset
   365
    {
hgs
parents:
diff changeset
   366
    TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - START" ) );
hgs
parents:
diff changeset
   367
hgs
parents:
diff changeset
   368
    TMemSpyDriverChunkType ret = EMemSpyDriverChunkTypeUnknown;
hgs
parents:
diff changeset
   369
hgs
parents:
diff changeset
   370
    TName name;
hgs
parents:
diff changeset
   371
    aChunk.Name( name );
hgs
parents:
diff changeset
   372
    TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - name: %S", &name ) );
hgs
parents:
diff changeset
   373
hgs
parents:
diff changeset
   374
    DMemSpyDriverOSAdaptionDChunk& chunkAdaption = OSAdaption().DChunk();
hgs
parents:
diff changeset
   375
    const TChunkType type = chunkAdaption.GetType( aChunk );
hgs
parents:
diff changeset
   376
hgs
parents:
diff changeset
   377
    if  ( name == KMemSpyLitDllDollarData )
hgs
parents:
diff changeset
   378
        {
hgs
parents:
diff changeset
   379
        // This chunk contains Dll Global Data for the process
hgs
parents:
diff changeset
   380
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeGlobalData" ) );
hgs
parents:
diff changeset
   381
        ret = EMemSpyDriverChunkTypeGlobalData;
hgs
parents:
diff changeset
   382
        }
hgs
parents:
diff changeset
   383
    else if ( type == ERamDrive )
hgs
parents:
diff changeset
   384
        {
hgs
parents:
diff changeset
   385
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeRamDrive" ) );
hgs
parents:
diff changeset
   386
        ret = EMemSpyDriverChunkTypeRamDrive;
hgs
parents:
diff changeset
   387
        }
hgs
parents:
diff changeset
   388
    else if ( type == EKernelStack )
hgs
parents:
diff changeset
   389
        {
hgs
parents:
diff changeset
   390
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeStackKernel" ) );
hgs
parents:
diff changeset
   391
        ret = EMemSpyDriverChunkTypeStackKernel;
hgs
parents:
diff changeset
   392
        }
hgs
parents:
diff changeset
   393
    else if ( name == KMemSpyLitDollarDat )
hgs
parents:
diff changeset
   394
        {
hgs
parents:
diff changeset
   395
        // This chunk contains process global data as well as user-side stacks for
hgs
parents:
diff changeset
   396
        // the process. 
hgs
parents:
diff changeset
   397
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeStackAndProcessGlobalData" ) );
hgs
parents:
diff changeset
   398
        ret = EMemSpyDriverChunkTypeStackAndProcessGlobalData;
hgs
parents:
diff changeset
   399
        }
hgs
parents:
diff changeset
   400
    else if ( name == KMemSpyLitDollarGlobalCode && type == EDll )
hgs
parents:
diff changeset
   401
        {
hgs
parents:
diff changeset
   402
        // GLOBAL$CODE is used for RAM loaded code which is globally visible. This
hgs
parents:
diff changeset
   403
        // basically means locale DLLs - these must be visible to every process, even
hgs
parents:
diff changeset
   404
        // those which haven't loaded them.        
hgs
parents:
diff changeset
   405
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeCodeGlobal" ) );
hgs
parents:
diff changeset
   406
        ret = EMemSpyDriverChunkTypeCodeGlobal;
hgs
parents:
diff changeset
   407
        }
hgs
parents:
diff changeset
   408
    else if ( name == KMemSpyLitDollarCode || type == EKernelCode || type == EDll || type == EUserCode )
hgs
parents:
diff changeset
   409
        {
hgs
parents:
diff changeset
   410
        // RAM-loaded code, which on the multiple memory model at least means that the code chunk is eseentially just a mapping
hgs
parents:
diff changeset
   411
        // artifact. The RAM itself is owned by the code segment, therefore counting the size of these CODE elements may result
hgs
parents:
diff changeset
   412
        // in inaccurate results if the code is shared amongst multiple processes.
hgs
parents:
diff changeset
   413
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeCode" ) );
hgs
parents:
diff changeset
   414
        ret = EMemSpyDriverChunkTypeCode;
hgs
parents:
diff changeset
   415
        }
hgs
parents:
diff changeset
   416
    else if ( type == EUserSelfModCode )
hgs
parents:
diff changeset
   417
        {
hgs
parents:
diff changeset
   418
        // Dynamically create code chunk
hgs
parents:
diff changeset
   419
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeCodeSelfModifiable" ) );
hgs
parents:
diff changeset
   420
        ret = EMemSpyDriverChunkTypeCodeSelfModifiable;
hgs
parents:
diff changeset
   421
        }
hgs
parents:
diff changeset
   422
    else if ( IsHeapChunk( aChunk, name ) )
hgs
parents:
diff changeset
   423
        {
hgs
parents:
diff changeset
   424
        // Catch kernel heap too
hgs
parents:
diff changeset
   425
        if  ( type == EKernelData )
hgs
parents:
diff changeset
   426
            {
hgs
parents:
diff changeset
   427
            TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeHeapKernel" ) );
hgs
parents:
diff changeset
   428
            ret = EMemSpyDriverChunkTypeHeapKernel;
hgs
parents:
diff changeset
   429
            }
hgs
parents:
diff changeset
   430
        else
hgs
parents:
diff changeset
   431
            {
hgs
parents:
diff changeset
   432
            TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeHeap" ) );
hgs
parents:
diff changeset
   433
            ret = EMemSpyDriverChunkTypeHeap;
hgs
parents:
diff changeset
   434
            }
hgs
parents:
diff changeset
   435
        }
hgs
parents:
diff changeset
   436
    else if ( type == EUserData && chunkAdaption.GetOwningProcess( aChunk ) == NULL )
hgs
parents:
diff changeset
   437
        {
hgs
parents:
diff changeset
   438
        // Global shared chunks match this pattern. Of course, we could check the memory model mapping attributes
hgs
parents:
diff changeset
   439
        // as that would give us the info in a heartbeat, but it's too specific.
hgs
parents:
diff changeset
   440
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeGlobal" ) );
hgs
parents:
diff changeset
   441
        ret = EMemSpyDriverChunkTypeGlobal;
hgs
parents:
diff changeset
   442
        }
hgs
parents:
diff changeset
   443
    else if ( type == EUserData && chunkAdaption.GetOwner( aChunk ) != NULL && name.Length() > KMemSpyLitLocalObject().Length() && name.Left( KMemSpyLitLocalObject().Length() ) == KMemSpyLitLocalObject )
hgs
parents:
diff changeset
   444
        {
hgs
parents:
diff changeset
   445
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeLocal" ) );
hgs
parents:
diff changeset
   446
        ret = EMemSpyDriverChunkTypeLocal;
hgs
parents:
diff changeset
   447
        }
hgs
parents:
diff changeset
   448
    else
hgs
parents:
diff changeset
   449
        {
hgs
parents:
diff changeset
   450
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IdentifyChunkType() - EMemSpyDriverChunkTypeUnknown" ) );
hgs
parents:
diff changeset
   451
        TRACE( PrintChunkInfo( aChunk ) );
hgs
parents:
diff changeset
   452
        ret = EMemSpyDriverChunkTypeUnknown;
hgs
parents:
diff changeset
   453
        }
hgs
parents:
diff changeset
   454
hgs
parents:
diff changeset
   455
    return ret;
hgs
parents:
diff changeset
   456
    }
hgs
parents:
diff changeset
   457
hgs
parents:
diff changeset
   458
hgs
parents:
diff changeset
   459
TBool DMemSpyDriverLogChanChunks::IsHeapChunk( DChunk& aChunk, const TName& aName )
hgs
parents:
diff changeset
   460
    {
hgs
parents:
diff changeset
   461
    (void) aName; // UREL warning
hgs
parents:
diff changeset
   462
    const TUint rHeapVTable = MemSpyDevice().RHeapVTable();
hgs
parents:
diff changeset
   463
    TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - START - this: 0x%08x, aChunk: 0x%08x, RHeapVTable: 0x%08x, aName: %S, [%O]", this, &aChunk, rHeapVTable, &aName, &aChunk ) );
hgs
parents:
diff changeset
   464
hgs
parents:
diff changeset
   465
    DMemSpyDriverOSAdaptionDChunk& chunkAdaption = OSAdaption().DChunk();
hgs
parents:
diff changeset
   466
    DMemSpyDriverOSAdaptionDProcess& processAdaption = OSAdaption().DProcess();
hgs
parents:
diff changeset
   467
    
hgs
parents:
diff changeset
   468
    // The first 4 bytes of every chunk correspond to the allocator VTable (For heap chunks).
hgs
parents:
diff changeset
   469
    // If it matches RHeap's vtable, we'll treat it as a heap.
hgs
parents:
diff changeset
   470
    TBool isHeap = EFalse;
hgs
parents:
diff changeset
   471
hgs
parents:
diff changeset
   472
    // There must be an owning process or else it's definitely not a heap chunk.
hgs
parents:
diff changeset
   473
    DProcess* process = chunkAdaption.GetOwningProcess( aChunk );
hgs
parents:
diff changeset
   474
    TUint8* base = chunkAdaption.GetBase( aChunk );
hgs
parents:
diff changeset
   475
    const TInt size = chunkAdaption.GetSize( aChunk );
hgs
parents:
diff changeset
   476
    TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - base: 0x%08x, size: %d, process: 0x%08x (%O)", base, size, process, process ) );
hgs
parents:
diff changeset
   477
hgs
parents:
diff changeset
   478
    if  ( process && size >= 4 )
hgs
parents:
diff changeset
   479
        {
hgs
parents:
diff changeset
   480
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   481
        // Chunks are mapped into entire process so any thread within the process is enough...
hgs
parents:
diff changeset
   482
        DThread* firstThread = processAdaption.OpenFirstThread( *process );
hgs
parents:
diff changeset
   483
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - firstThread: 0x%08x (%O)", firstThread, firstThread ) );
hgs
parents:
diff changeset
   484
        if  ( firstThread != NULL )
hgs
parents:
diff changeset
   485
            {
hgs
parents:
diff changeset
   486
            TBuf8<4> allocatorVTableBuffer;
hgs
parents:
diff changeset
   487
            TInt err = Kern::ThreadRawRead( firstThread, base, (TUint8*) allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength() );
hgs
parents:
diff changeset
   488
            TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - read result of vtable data from requested thread is: %d", err ));
hgs
parents:
diff changeset
   489
            //
hgs
parents:
diff changeset
   490
            if  ( err == KErrNone )
hgs
parents:
diff changeset
   491
                {
hgs
parents:
diff changeset
   492
                TRACE( MemSpyDriverUtils::DataDump("possible chunk vtable data - %lS", allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength(), allocatorVTableBuffer.MaxLength() ) );
hgs
parents:
diff changeset
   493
                allocatorVTableBuffer.SetLength( allocatorVTableBuffer.MaxLength() );
hgs
parents:
diff changeset
   494
                
hgs
parents:
diff changeset
   495
                const TUint32 vtable =   allocatorVTableBuffer[0] +
hgs
parents:
diff changeset
   496
                                        (allocatorVTableBuffer[1] << 8) + 
hgs
parents:
diff changeset
   497
                                        (allocatorVTableBuffer[2] << 16) + 
hgs
parents:
diff changeset
   498
                                        (allocatorVTableBuffer[3] << 24);
hgs
parents:
diff changeset
   499
                TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - [possible] vTable within chunk is: 0x%08x", vtable) );
hgs
parents:
diff changeset
   500
hgs
parents:
diff changeset
   501
                // Check the v-table to work out if it really is an RHeap
hgs
parents:
diff changeset
   502
                isHeap = ( vtable == rHeapVTable );
hgs
parents:
diff changeset
   503
                TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - isHeap: %d", isHeap ) );
hgs
parents:
diff changeset
   504
                }
hgs
parents:
diff changeset
   505
hgs
parents:
diff changeset
   506
            TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - closing first thread..." ) );
hgs
parents:
diff changeset
   507
            Kern::SafeClose( (DObject*&) firstThread, NULL );
hgs
parents:
diff changeset
   508
            }
hgs
parents:
diff changeset
   509
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   510
        }
hgs
parents:
diff changeset
   511
hgs
parents:
diff changeset
   512
    /* We only want RHeap's at the moment
hgs
parents:
diff changeset
   513
    if  ( !isHeap && aName == KMemSpyLitDollarHeap )
hgs
parents:
diff changeset
   514
        {
hgs
parents:
diff changeset
   515
        TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - its called $HEAP, but its not an RHeap... we\'ll let it through though..." ) );
hgs
parents:
diff changeset
   516
        isHeap = ETrue;
hgs
parents:
diff changeset
   517
        }
hgs
parents:
diff changeset
   518
    */
hgs
parents:
diff changeset
   519
hgs
parents:
diff changeset
   520
    TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - END - this: 0x%08x, isHeap: %d", this, isHeap ) );
hgs
parents:
diff changeset
   521
    return isHeap;
hgs
parents:
diff changeset
   522
    }
hgs
parents:
diff changeset
   523
hgs
parents:
diff changeset
   524
hgs
parents:
diff changeset
   525
TBool DMemSpyDriverLogChanChunks::DoesChunkRelateToProcess( DChunk& aChunk, DProcess& aProcess )
hgs
parents:
diff changeset
   526
    {
hgs
parents:
diff changeset
   527
    TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::DoesChunkRelateToProcess() - START - this: 0x%08x, chunk: 0x%08x (%O), process: 0x%08x (%O)", this, &aChunk, &aChunk, &aProcess, &aProcess ) );
hgs
parents:
diff changeset
   528
    TBool ret = EFalse;
hgs
parents:
diff changeset
   529
    //
hgs
parents:
diff changeset
   530
    DMemSpyDriverOSAdaptionDChunk& chunkAdaption = OSAdaption().DChunk();
hgs
parents:
diff changeset
   531
    DMemSpyDriverOSAdaptionDProcess& processAdaption = OSAdaption().DProcess();
hgs
parents:
diff changeset
   532
    //
hgs
parents:
diff changeset
   533
    const TUint pid = processAdaption.GetId( aProcess );
hgs
parents:
diff changeset
   534
    DProcess* process = chunkAdaption.GetOwningProcess( aChunk );
hgs
parents:
diff changeset
   535
    if  ( process )
hgs
parents:
diff changeset
   536
        {
hgs
parents:
diff changeset
   537
        ret = ( pid == processAdaption.GetId( *process ) );
hgs
parents:
diff changeset
   538
        }
hgs
parents:
diff changeset
   539
    else
hgs
parents:
diff changeset
   540
        {
hgs
parents:
diff changeset
   541
        DObject* owner = chunkAdaption.GetOwner( aChunk, EProcess );
hgs
parents:
diff changeset
   542
        if  ( owner )
hgs
parents:
diff changeset
   543
            {
hgs
parents:
diff changeset
   544
            process = (DProcess*) owner;
hgs
parents:
diff changeset
   545
            ret = ( pid == processAdaption.GetId( *process ) );
hgs
parents:
diff changeset
   546
            }
hgs
parents:
diff changeset
   547
        else
hgs
parents:
diff changeset
   548
            {
hgs
parents:
diff changeset
   549
            ret = ( pid == chunkAdaption.GetControllingOwnerId( aChunk ) );
hgs
parents:
diff changeset
   550
            }
hgs
parents:
diff changeset
   551
        }
hgs
parents:
diff changeset
   552
    //
hgs
parents:
diff changeset
   553
    TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::DoesChunkRelateToProcess() - END - this: 0x%08x, chunk: 0x%08x (%O), process: 0x%08x (%O), ret: %d", this, &aChunk, &aChunk, &aProcess, &aProcess, ret ) );
hgs
parents:
diff changeset
   554
    return ret;
hgs
parents:
diff changeset
   555
    }
hgs
parents:
diff changeset
   556