--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanStack.cpp Thu Sep 02 22:05:40 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,519 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-#include "MemSpyDriverLogChanStack.h"
-
-// System includes
-#include <u32hal.h>
-#include <e32rom.h>
-#include <memspy/driver/memspydriverobjectsshared.h>
-
-// Shared includes
-#include "MemSpyDriverOpCodes.h"
-#include "MemSpyDriverObjectsInternal.h"
-
-// User includes
-#include "MemSpyDriverUtils.h"
-#include "MemSpyDriverOSAdaption.h"
-#include "MemSpyDriverSuspensionManager.h"
-
-// Constants
-const TUint32 KMemSpyStackFillPatternUser = 0x29292929;
-const TUint32 KMemSpyStackFillPatternSupervisor = 0xeeeeeeee;
-
-
-DMemSpyDriverLogChanStack::DMemSpyDriverLogChanStack( DMemSpyDriverDevice& aDevice, DThread& aThread )
-: DMemSpyDriverLogChanBase( aDevice, aThread )
- {
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::DMemSpyDriverLogChanStack() - this: 0x%08x", this ));
- }
-
-
-DMemSpyDriverLogChanStack::~DMemSpyDriverLogChanStack()
- {
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::~DMemSpyDriverLogChanStack() - START - this: 0x%08x", this ));
-
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::~DMemSpyDriverLogChanStack() - END - this: 0x%08x", this ));
- }
-
-
-
-
-
-
-TInt DMemSpyDriverLogChanStack::Request( TInt aFunction, TAny* a1, TAny* a2 )
- {
- TInt r = DMemSpyDriverLogChanBase::Request( aFunction, a1, a2 );
- if ( r == KErrNone )
- {
- switch( aFunction )
- {
- case EMemSpyDriverOpCodeStackGetInfo:
- r = GetStackInfo( (TUint) a1, (TMemSpyDriverStackInfo*) a2 );
- break;
- case EMemSpyDriverOpCodeStackGetData:
- r = GetStackData( (TMemSpyDriverInternalStackDataParams*) a1 );
- break;
-
- default:
- r = KErrNotSupported;
- break;
- }
- }
- //
- return r;
- }
-
-
-TBool DMemSpyDriverLogChanStack::IsHandler( TInt aFunction ) const
- {
- return ( aFunction > EMemSpyDriverOpCodeStackBase && aFunction < EMemSpyDriverOpCodeStackEnd );
- }
-
-
-
-
-
-
-
-
-
-TInt DMemSpyDriverLogChanStack::GetStackInfo( TUint aTid, TMemSpyDriverStackInfo* aParams )
- {
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackInfo() - START - thread id: %d", aTid));
-
- TMemSpyDriverStackInfo params;
- TInt r = OpenTempObject( aTid, EThread );
- if ( r == KErrNone )
- {
- DThread* thread = (DThread*) TempObject();
-
- // Check the threads in the process are suspended
- if ( SuspensionManager().IsSuspended( *thread ) )
- {
- DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread();
- //
- GetStackPointers( thread, params.iSupervisorStackPointer, params.iUserStackPointer );
- //
- params.iUserStackBase = threadAdaption.GetUserStackBase( *thread );
- params.iUserStackSize = threadAdaption.GetUserStackSize( *thread );
- params.iSupervisorStackBase = threadAdaption.GetSupervisorStackBase( *thread );
- params.iSupervisorStackSize = threadAdaption.GetSupervisorStackSize( *thread );
-
- // Try to get watermarks
- GetStackHighWatermark( *thread, params.iUserStackHighWatermark, EMemSpyDriverDomainUser, KMemSpyStackFillPatternUser );
- GetStackHighWatermark( *thread, params.iSupervisorStackHighWatermark, EMemSpyDriverDomainKernel, KMemSpyStackFillPatternSupervisor ) ;
-
- #ifdef __WINS__
- params.iUserStackPointer = params.iUserStackBase;
- params.iUserStackHighWatermark = params.iUserStackBase;
- params.iSupervisorStackPointer = params.iSupervisorStackBase;
- params.iSupervisorStackHighWatermark = params.iSupervisorStackBase;
- #endif
-
- // Write data to user-side
- r = Kern::ThreadRawWrite( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverStackInfo) );
- }
- else
- {
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackInfo - parent process not suspended => KErrAccessDenied"));
- r = KErrAccessDenied;
- }
-
- CloseTempObject();
- }
-
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackInfo() - END - ret: %d", r));
- return r;
- }
-
-
-TInt DMemSpyDriverLogChanStack::GetStackData( TMemSpyDriverInternalStackDataParams* aParams )
- {
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData() - START"));
- TMemSpyDriverInternalStackDataParams params;
- TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalStackDataParams) );
- if ( r != KErrNone )
- {
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData() - END - params read error: %d", r));
- return r;
- }
-
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData - thread id: %d, remaining: %8d", params.iTid, params.iRemaining));
-
- DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread();
-
- r = OpenTempObject( params.iTid, EThread );
- if ( r == KErrNone )
- {
- // Find the correct thread...
- DThread* thread = (DThread*) TempObject();
- DProcess* process = threadAdaption.GetOwningProcess( *thread );
- TFullName fullName;
- thread->FullName( fullName );
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData - thread: %lS", &fullName));
-
- // Check the threads in the process are suspended
- const TBool isSuspended = SuspensionManager().IsSuspended( *process );
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData() - isSuspended: %d", isSuspended ));
- if ( isSuspended )
- {
- TInt stackSize = 0;
- TUint32 stackBase = 0;
- TBool stackAvailable = EFalse;
- //
- if ( params.iDomain == EMemSpyDriverDomainUser )
- {
- stackSize = threadAdaption.GetUserStackSize( *thread );
- stackBase = threadAdaption.GetUserStackBase( *thread );
- }
- else if ( params.iDomain == EMemSpyDriverDomainKernel )
- {
- stackSize = threadAdaption.GetSupervisorStackSize( *thread );
- stackBase = threadAdaption.GetSupervisorStackBase( *thread );
- }
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData() - stackAvailable: %d", stackAvailable ));
- //
- if ( stackAvailable )
- {
- // 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("DMemSpyDriverLogChanStack::GetStackData - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", params.iDes, destPtr, destLen, destMax, r ));
-
- if ( r == KErrNone )
- {
- // Calculate stack starting address. If we want to get the entire stack data
- // then we use the information from DThread. If we only want the data from
- // the current SP onwards, then we use GetStackPointerByDomain to return
- // the current SP value. If we are only fetching a portion of the stack, then
- // the amount of data we will have to read is obviously reduced.
- TUint32 stackStartingAddress = 0;
- if ( params.iEntireStack )
- {
- stackStartingAddress = stackBase;
- }
- else
- {
- stackStartingAddress = GetStackPointerByDomain( thread, params.iDomain );
- }
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData - stackStartingAddress: 0x%08x", stackStartingAddress));
- __ASSERT_ALWAYS( stackStartingAddress != 0, MemSpyDriverUtils::Fault( __LINE__ ) );
-
- // Calculate how much data (maximum) there is to read, depending on whether the
- // client asked for all or just the active part of the stack.
- TUint stackDataSize = 0;
- if ( params.iEntireStack )
- {
- stackDataSize = stackSize;
- }
- else
- {
- stackDataSize = stackBase + stackSize - stackStartingAddress;
- }
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData - stackDataSize: %8d", stackDataSize ));
-
- // Deal with the initial case - i.e. whereby the client is requesting stack
- // data for the first time. In this situation, the magic rune for "first
- // request" is a remaining value of -1.
- if ( params.iRemaining < 0 )
- {
- params.iRemaining = stackDataSize;
- }
-
- // The remaining number of bytes should allow us to calculate the position
- // to read from.
- const TInt amountToRead = Min( params.iRemaining, destMax );
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData - amountToRead: %8d", amountToRead));
- const TInt readOffset = ( stackDataSize - params.iRemaining );
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData - readOffset: %8d", readOffset));
- const TAny* readAddress = (const TAny*) ( stackStartingAddress + readOffset );
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData - readAddress: 0x%08x", readAddress));
-
- // Do the read into user-space
- #ifndef __WINS__
- if ( params.iDomain == EMemSpyDriverDomainKernel )
- {
- const TPtrC8 pData( (TUint8*) readAddress, amountToRead );
- r = Kern::ThreadDesWrite( &Kern::CurrentThread(), params.iDes, pData, 0 );
- }
- else
- {
- r = Kern::ThreadRawRead( thread, readAddress, destPtr, amountToRead );
- }
-
- // Update user-side
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData - mem. operation result: %d", r));
- if ( r == KErrNone )
- {
- // Update remaining bytes and write back to user address space
- params.iRemaining -= amountToRead;
- r = Kern::ThreadRawWrite( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalStackDataParams) );
-
- if ( r == KErrNone )
- {
- // Client takes care of updating descriptor length.
- r = amountToRead;
- }
- }
- else if ( r == KErrBadDescriptor )
- {
- MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor );
- }
- #else
- (void) destPtr;
- params.iRemaining -= amountToRead;
- r = amountToRead;
- Kern::Printf( "DMemSpyDriverLogChanStack::GetStackData - not reading data on WINS" );
- #endif
- }
- else
- {
- Kern::Printf( "DMemSpyDriverLogChanStack::GetStackData - error getting client descriptor info" );
- }
- }
- else
- {
- Kern::Printf("DMemSpyDriverLogChanStack::GetStackData - stack address or stack length is invalid");
- r = KErrArgument;
- }
- }
- else
- {
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData - parent process not suspended => KErrAccessDenied"));
- r = KErrAccessDenied;
- }
-
- CloseTempObject();
- }
- else
- {
- Kern::Printf("DMemSpyDriverLogChanStack::GetStackData - thread not found");
- }
-
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackData() - END - ret: %d", r));
- return r;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#ifdef __MARM__
-
-#define __INCLUDE_REG_OFFSETS__ // for SP_R13U in nk_plat.h
-#include "nk_plat.h"
-#include "arm.h"
-
-void DMemSpyDriverLogChanStack::GetStackPointers( DThread* aThread, TUint& aSupSP, TUint& aUsrSP )
- {
- __ASSERT_ALWAYS( aThread != &Kern::CurrentThread(), MemSpyDriverUtils::Fault( __LINE__ ) );
-
- // Get NThread associated with DThread
- NThread* nThread = OSAdaption().DThread().GetNThread( *aThread );
-
- TMemSpyDriverRegSet regs;
- MemSpyDriverUtils::GetThreadRegisters( nThread, regs );
- //
- aSupSP = aThread->iNThread.iSavedSP;
- aUsrSP = regs.iRn[13];
- //
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackPointers() - usr: 0x%08x [0x%08x-0x%08x], svc: 0x%08x [0x%08x-0x%08x]", aUsrSP, aThread->iUserStackRunAddress, (TUint) aThread->iUserStackRunAddress + (TUint) aThread->iUserStackSize, aSupSP, aThread->iSupervisorStack, (TUint) aThread->iSupervisorStack + (TUint) aThread->iSupervisorStackSize ));
- }
-
-
-TLinAddr DMemSpyDriverLogChanStack::GetStackPointerByDomain( DThread* aThread, TMemSpyDriverDomainType aDomainType )
- {
- TUint stackPointer = 0;
- //
- if ( aDomainType == EMemSpyDriverDomainUser )
- {
- // Get NThread associated with DThread
- NThread* nThread = OSAdaption().DThread().GetNThread( *aThread );
-
- TMemSpyDriverRegSet regSet;
- MemSpyDriverUtils::GetThreadRegisters( nThread, regSet );
- stackPointer = regSet.iRn[13];
- }
- else if ( aDomainType == EMemSpyDriverDomainKernel )
- {
- TUint userSPNotUsed = 0;
- GetStackPointers( aThread, stackPointer, userSPNotUsed );
- }
- //
- return TLinAddr( stackPointer );
- }
-
-#else
-
-void DMemSpyDriverLogChanStack::GetStackPointers( DThread* /*aThread*/, TUint& aSupSP, TUint& aUsrSP )
- {
- aSupSP = 0;
- aUsrSP = 0;
- }
-
-
-TLinAddr DMemSpyDriverLogChanStack::GetStackPointerByDomain( DThread* aThread, TMemSpyDriverDomainType aDomainType )
- {
- // Just return the base address in WINS
- DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread();
- TUint32 stackPointer = 0;
- //
- if ( aDomainType == EMemSpyDriverDomainUser )
- {
- stackPointer = threadAdaption.GetUserStackBase( *aThread );
- }
- else if ( aDomainType == EMemSpyDriverDomainKernel )
- {
- stackPointer = threadAdaption.GetSupervisorStackBase( *aThread );
- }
- //
- return TLinAddr( stackPointer );
- }
-
-#endif
-
-
-TInt DMemSpyDriverLogChanStack::GetStackHighWatermark( DThread& aThread, TLinAddr& aHighWatermark, TMemSpyDriverDomainType aDomain, TUint aRune )
- {
- aHighWatermark = 0;
- const TInt KStackPageSize = 512;
-
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackHighWatermark() - START - domain: %d, rune: 0x%08x", aDomain, aRune ));
-
- DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread();
-
- const TUint32 baseAddress = aDomain == EMemSpyDriverDomainUser ? threadAdaption.GetUserStackBase( aThread ) : threadAdaption.GetSupervisorStackBase( aThread );
- const TInt size = aDomain == EMemSpyDriverDomainUser ? threadAdaption.GetUserStackSize( aThread ) : threadAdaption.GetSupervisorStackSize( aThread );
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackHighWatermark - baseAddress: 0x%08x, size: %8d", baseAddress, size));
-
- TInt r = KErrNone;
- //
- if ( baseAddress && size )
- {
- aHighWatermark = baseAddress;
- TBuf8<KStackPageSize> stackBuf;
- TUint8* readAddress = NULL;
- //
- while( r == KErrNone )
- {
- // Read a chunk of data
- r = ReadStackData( aThread, stackBuf, readAddress, aDomain );
-
- // Process the data, looking for the first bytes that aren't 0x29292929
- if ( r == KErrNone )
- {
- const TInt readLength = stackBuf.Length();
- TRACE_DATA( MemSpyDriverUtils::DataDump("stackdata - %lS", stackBuf.Ptr(), readLength, readLength ) );
-
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackHighWatermark - readLength: %d", readLength));
-
- for( TInt readPos = 0; readPos < readLength && ((readLength - readPos) >= 4); readPos += 4, aHighWatermark += 4 )
- {
- const TUint dword = stackBuf[ readPos ] +
- (stackBuf[ readPos + 1 ] << 8) +
- (stackBuf[ readPos + 2 ] << 16) +
- (stackBuf[ readPos + 3 ] << 24);
- //
- if ( dword != aRune )
- {
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackHighWatermark - found end of uninit. stack!"));
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackHighWatermark - dword: 0x%08x", dword));
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackHighWatermark - readPos: %8d", readPos));
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackHighWatermark - aHighWatermark: 0x%08x", aHighWatermark));
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::GetStackHighWatermark() - END"));
- return KErrNone;
- }
- }
- }
- }
- }
- //
- aHighWatermark = 0;
- Kern::Printf("DMemSpyDriverLogChanStack::GetStackHighWatermark() - END - error: %d", r);
- return r;
- }
-
-
-TInt DMemSpyDriverLogChanStack::ReadStackData( DThread& aThread, TDes8& aDestination, TUint8*& aReadAddress, TMemSpyDriverDomainType aDomain )
- {
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::ReadStackData() - START - domain: %d", aDomain ));
-
- DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread();
-
- const TUint32 baseAddress = aDomain == EMemSpyDriverDomainUser ? threadAdaption.GetUserStackBase( aThread ) : threadAdaption.GetSupervisorStackBase( aThread );
- const TInt size = aDomain == EMemSpyDriverDomainUser ? threadAdaption.GetUserStackSize( aThread ) : threadAdaption.GetSupervisorStackSize( aThread );
- const TUint32 topAddress = ( baseAddress + size );
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::ReadStackData - baseAddress: 0x%08x", baseAddress));
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::ReadStackData - size: 0x%08x", size));
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::ReadStackData - topAddress: 0x%08x", topAddress));
- //
- if ( aReadAddress == NULL )
- {
- aReadAddress = (TUint8*) baseAddress;
- }
-
- // Work out how much we should read
- TInt readLen = Min( aDestination.MaxLength(), topAddress - (TLinAddr) aReadAddress );
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::ReadStackData - aReadAddress: 0x%08x", aReadAddress));
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::ReadStackData - readLen: %8d", readLen));
-
- TInt r = KErrNotSupported;
- aDestination.Zero();
-
-#ifndef __WINS__
- if ( aDomain == EMemSpyDriverDomainKernel )
- {
- const TPtrC8 pData( (TUint8*) aReadAddress, readLen );
- aDestination.Copy( pData );
- r = KErrNone;
- readLen = aDestination.Length();
- }
- else
- {
- r = Kern::ThreadRawRead( &aThread, aReadAddress, (TAny*) aDestination.Ptr(), readLen );
- }
-
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::ReadStackData - read result: %d", r));
- if (r == KErrNone)
- {
- aDestination.SetLength( readLen );
- aReadAddress += aDestination.Length();
- }
-#else
- Kern::Printf("DMemSpyDriverLogChanStack::ReadStackData - not reading data on WINS");
-#endif
-
- TRACE( Kern::Printf("DMemSpyDriverLogChanStack::ReadStackData() - END - ret: %d", r));
- return r;
- }
-
-
-
-