--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dbgsrv/coredumpserver/cdssupport/src/threaddata.cpp Tue Mar 02 10:33:16 2010 +0530
@@ -0,0 +1,532 @@
+// Copyright (c) 2007-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:
+// Implemetation of CThreadInfo class
+//
+
+
+
+/**
+ @file
+ @see CThreadInfo
+*/
+
+
+#include <rm_debug_api.h>
+#include <debuglogging.h>
+#include <threaddata.h>
+
+/**
+Allocates and constructs a CThreadInfo object.
+@param aId Kernel thread id
+@param aName Kernel thread name
+@param aProcessId Kernel id of owning process
+@param aPriority Kernel thread priority TThreadPriority
+@param aSvcStackPtr Thread supervisor stack pointer
+@param aSvcStackAddr Thread supervisor mode stack base address
+@param aSvcStackSize Thread supervisor mode stack size in bytes
+@param aUsrStackAddr Thread user mode stack base address
+@param aUsrStackSize Thread user mode stack base size in bytes
+
+@see CThreadInfo::CThreadInfo
+*/
+EXPORT_C CThreadInfo* CThreadInfo::NewL(
+ const TUint64 & aId,
+ const TDesC & aName,
+ const TUint64 & aProcessId,
+ const TUint & aPriority,
+ const TLinAddr & aSvcStackPtr,
+ const TLinAddr & aSvcStackAddr,
+ const TUint & aSvcStackSize,
+ const TLinAddr & aUsrStackAddr,
+ const TUint & aUsrStackSize )
+ {
+
+ // Add up the potential maximum size of the externalized object
+ const TUint size =
+ sizeof( TUint32 ) // iId Low
+ + sizeof( TUint32 ) // iId High
+
+ + sizeof( TUint32 ) // When externalized, we send the name length, so must include this
+ + 2 // When externalized, the << operator writes 2 bytes for the descriptor size
+ + aName.Size() // iName Size, in bytes.
+
+ + sizeof( TUint32 ) // iProcessId Low
+ + sizeof( TUint32 ) // iProcessId High
+ + sizeof( TUint32 ) // iPriority
+ + sizeof( TUint32 ) // iSvcStackPtr
+ + sizeof( TUint32 ) // iSvcStackAddr
+ + sizeof( TUint32 ) // iSvcStackSize
+ + sizeof( TUint32 ) // iUsrStackAddr
+ + sizeof( TUint32 ) // iUsrStackSize
+ + sizeof( TUint32 ) // iObserved
+
+ + sizeof( TUint32 ); // iSize itself
+
+ if( size >= MaxSize() )
+ {
+ LOG_MSG3( "CThreadInfo::NewL() : Descriptorized object = 0x%X bytes would exceed the maximum of 0x%X\n",
+ size, MaxSize() );
+
+ User::Leave( KErrTooBig );
+ }
+
+ CThreadInfo * data = new (ELeave) CThreadInfo( aId,
+ aProcessId,
+ aPriority,
+ aSvcStackPtr,
+ aSvcStackAddr,
+ aSvcStackSize,
+ aUsrStackAddr,
+ aUsrStackSize );
+ CleanupStack::PushL( data );
+
+ data->ConstructL( aName );
+
+ CleanupStack::Pop(data);
+
+ return (data);
+
+ }
+
+
+/**
+Allocates and constructs a CThreadInfo object from a descriptor.
+The descriptor contains an externalised version of a CThreadInfo object.
+This method is typically used to obtain a CThreadInfo object from a
+descriptor returned by the core dump server.
+
+@param aStreamData Descriptor with externalised/streamed object
+@see InternalizeL
+@see ExternalizeL
+*/
+EXPORT_C CThreadInfo* CThreadInfo::NewL( const TDesC8 & aStreamData )
+ {
+
+ CThreadInfo* self = new (ELeave) CThreadInfo();
+
+ CleanupStack::PushL( self );
+
+ // Open a read stream for the descriptor
+ RDesReadStream stream( aStreamData );
+
+ CleanupClosePushL( stream );
+
+ self->InternalizeL( stream );
+
+ CleanupStack::PopAndDestroy( &stream ); // finished with the stream
+
+ CleanupStack::Pop( self );
+
+ return ( self );
+
+ }
+
+
+/**
+Destructor. Deletes name if allocated.
+*/
+EXPORT_C CThreadInfo::~CThreadInfo()
+ {
+
+ if( NULL != iName )
+ {
+ delete iName;
+ }
+ }
+
+/**
+Set the name of the thread by deleting, allocating and then copying the parameter.
+@param aName Name of the thread to set to
+@see ConstructL()
+*/
+EXPORT_C void CThreadInfo::NameL( const TDesC & aName )
+ {
+
+ if( aName.Length() > 0 )
+ {
+ TUint toCopy = aName.Length();
+ iName = HBufC::NewL( toCopy );
+ TPtr nameDes = iName->Des();
+
+ nameDes.Copy( aName.Ptr(), toCopy );
+ nameDes.SetLength( toCopy );
+ }
+ else
+ {
+ iName = NULL;
+ }
+ }
+
+
+/**
+First phase contructor. Sets the size to 0, name to NULL.
+@see CThreadInfo::NewL()
+*/
+CThreadInfo::CThreadInfo( const TUint64 & aId,
+ const TUint64 & aProcessId,
+ const TUint & aPriority,
+ const TLinAddr & aSvcStackPtr,
+ const TLinAddr & aSvcStackAddr,
+ const TUint & aSvcStackSize,
+ const TLinAddr & aUsrStackAddr,
+ const TUint & aUsrStackSize ) :
+ iId ( aId ),
+ iName ( NULL ),
+ iProcessId ( aProcessId ),
+ iPriority ( aPriority ),
+ iSvcStackPtr ( aSvcStackPtr ),
+ iSvcStackAddr( aSvcStackAddr ),
+ iSvcStackSize( aSvcStackSize ),
+ iUsrStackAddr( aUsrStackAddr ),
+ iUsrStackSize( aUsrStackSize ),
+ iObserved ( EFalse ),
+ iSize ( 0 ),
+ iLastCpuId ( -1 )
+ {
+
+ }
+
+
+/**
+Second phase constructor initialises the name of the thread.
+@param aName Thread name
+@see NameL()
+*/
+void CThreadInfo::ConstructL( const TDesC & aName )
+ {
+ NameL( aName );
+ }
+
+
+
+/**
+Initialise this object with the contents of RReadStream aStream.
+The descriptor contains an externalised version of an object.
+This method is typically used to obtain a CThreadInfo object from
+the core dump server.
+Any modifications to this method should be synchronised with ExternalizeL().
+Also note that the methods used from RReadStream (>> or ReadUint32L)
+can behave differently, especially for descriptors.
+@param aStream Stream with streamed object
+@see ExternalizeL
+@see RReadStream
+@pre Call Externalise to obtain the stream containing an externalised
+version of this object.
+*/
+EXPORT_C void CThreadInfo::InternalizeL( RReadStream & aStream )
+ {
+
+ TUint32 idLow = aStream.ReadUint32L();
+
+ TUint32 idHigh = aStream.ReadUint32L();
+ iId = MAKE_TUINT64( idHigh, idLow );
+
+ if( NULL != iName )
+ {
+ //LOG_MSG( " iName != NULL\n" );
+ delete iName;
+ iName = NULL;
+ }
+
+ TUint32 nameLength = aStream.ReadUint32L();
+
+ if ( nameLength > 0 )
+ {
+ iName = HBufC::NewL( aStream, nameLength );
+ }
+ else
+ {
+ iName = NULL;
+ }
+
+ TUint32 pidLow = aStream.ReadUint32L();
+ TUint32 pidHigh = aStream.ReadUint32L();
+ iProcessId = MAKE_TUINT64( pidHigh, pidLow );
+
+ iPriority = aStream.ReadUint32L();
+ iSvcStackPtr = aStream.ReadUint32L() ;
+ iSvcStackAddr = aStream.ReadUint32L() ;
+ iSvcStackSize = aStream.ReadUint32L() ;
+ iUsrStackAddr = aStream.ReadUint32L() ;
+ iUsrStackSize = aStream.ReadUint32L() ;
+ iObserved = static_cast<TBool>(aStream.ReadUint32L());
+ iLastCpuId = aStream.ReadUint32L();
+ iHeapBase = aStream.ReadUint32L();
+ iHeapSize = aStream.ReadUint32L();
+ iSize = aStream.ReadUint32L() ;
+ }
+
+
+
+
+
+/**
+Make a streamed representation of this object to RWriteStream aStream.
+
+This method is typically by the core dump server when contructing a list of
+CThreadInfo for a client.
+Any modifications to this method should be synchronised with InternalizeL().
+Also note that the methods used from RWriteStream (>> or WriteUint32L) can behave differently,
+especially for descriptors.
+@param aStream Stream to stream object onto
+@param buf Buffer onto the same stream, used to obtain correct size of externalised object
+@see InternalizeL
+@see RReadStream
+@see RWriteStream
+@post The stream contains an externalised version of this object.
+*/
+EXPORT_C void CThreadInfo::ExternalizeL( RWriteStream & aStream, CBufFlat* buf )
+ {
+
+ const TUint32 idLow = I64LOW( iId );
+ const TUint32 idHigh = I64HIGH( iId );
+
+ // Take the size of the buffer before we add anything to it.
+ TUint startBufSize = buf->Size();
+
+ aStream.WriteUint32L( idLow );
+ aStream.WriteUint32L( idHigh );
+
+ TUint nameLength = 0;
+
+ if ( NULL != iName )
+ {
+ nameLength = iName->Des().Length();
+ if( nameLength > 0 )
+ {
+ // Write the number of character elements in the name.
+ aStream.WriteUint32L( nameLength );
+ aStream << iName->Des();
+ }
+ }
+
+ if( nameLength == 0 )
+ {
+ aStream.WriteUint32L( 0 );
+ }
+
+ const TUint32 pIdLow = I64LOW( iProcessId );
+ const TUint32 pIdHigh = I64HIGH( iProcessId );
+ aStream.WriteUint32L( pIdLow );
+ aStream.WriteUint32L( pIdHigh );
+
+ aStream.WriteUint32L( iPriority );
+
+ aStream.WriteUint32L( iSvcStackPtr ) ;
+ aStream.WriteUint32L( iSvcStackAddr ) ;
+ aStream.WriteUint32L( iSvcStackSize ) ;
+ aStream.WriteUint32L( iUsrStackAddr );
+ aStream.WriteUint32L( iUsrStackSize );
+ aStream.WriteUint32L( static_cast<TUint32>(iObserved) );
+ aStream.WriteInt32L(iLastCpuId);
+ aStream.WriteUint32L( iHeapBase );
+ aStream.WriteUint32L( iHeapSize );
+
+ // The real exteranlized size is the size of the buffer up to here plus the
+ // 4 bytes for the size itself
+ iSize = buf->Size() - startBufSize + 4;
+ aStream.WriteUint32L( iSize );
+
+ }
+
+/**
+Obtain the kernel thread id.
+*/
+EXPORT_C const TUint64 & CThreadInfo::Id() const
+ {
+ return ( iId );
+ }
+
+/**
+Obtain the kernel thread name.
+*/
+EXPORT_C const TDesC & CThreadInfo::Name() const
+ {
+ return ( *iName );
+ }
+
+/**
+Obtain the kernel owning process id.
+*/
+EXPORT_C const TUint64 & CThreadInfo::ProcessId() const
+ {
+ return ( iProcessId );
+ }
+
+/**
+Obtain the kernel priority.
+*/
+EXPORT_C TUint CThreadInfo::Priority() const
+ {
+ return ( iPriority );
+ }
+
+/**
+Obtain the kernel supervisor mode stack pointer.
+*/
+EXPORT_C TUint CThreadInfo::SvcStackPtr() const
+ {
+ return ( iSvcStackPtr );
+ }
+
+/**
+Obtain the kernel supervisor mode stack base address.
+*/
+EXPORT_C TUint CThreadInfo::SvcStackAddr() const
+ {
+ return ( iSvcStackAddr );
+ }
+
+/**
+Obtain the kernel supervisor mode stack size in bytes.
+*/
+EXPORT_C TUint CThreadInfo::SvcStackSize() const
+ {
+ return ( iSvcStackSize );
+ }
+
+/**
+Obtain the kernel user mode stack base address.
+*/
+EXPORT_C TUint CThreadInfo::UsrStackAddr() const
+ {
+ return ( iUsrStackAddr );
+ }
+
+/**
+Obtain the kernel user mode stack size in bytes.
+*/
+EXPORT_C TUint CThreadInfo::UsrStackSize() const
+ {
+ return ( iUsrStackSize );
+ }
+
+
+/**
+Returns ETrue if the thread is being explicitly observed for crashes by the Core Dump Server.
+If only the owning process is being observed, this method returns EFalse.
+*/
+EXPORT_C TBool CThreadInfo::Observed() const
+ {
+ return ( iObserved );
+ }
+
+/**
+Set whether this thread is being observed for crashes by the Core Dump Server.
+*/
+EXPORT_C void CThreadInfo::Observed(TBool aFlag)
+ {
+ iObserved = aFlag;
+ }
+
+CThreadInfo::CThreadInfo()
+ {
+ }
+
+
+/**
+Get the maximum size allowed for this object. This is needed as the object is passed
+across the Client Server interface.
+*/
+EXPORT_C TInt CThreadInfo::MaxSize()
+ {
+
+ const TInt maxSize = 512;
+ return maxSize;
+ }
+
+
+/**
+Gets the size of the object when externalized. The sizeofs used to calculate this
+must match the operators used in ExternalizeL and InternalizeL.
+Special attention must be paid to the name. If the object has not been
+externalized yet then this method returns the maximum that it could take.
+The name descriptor is compressed when externalized, so it is not its Size().
+Furthermore the << operator adds two bytes to the stream when externalizing
+a descriptor
+*/
+EXPORT_C TInt CThreadInfo::Size() const
+ {
+
+ if( iSize != 0 )
+ {
+ return iSize;
+ }
+
+ // This is the maximum size of the object when externalized.
+ // It is a maximum since externalizing 16 bit descriptors compresses the data,
+ // and thus the real externalized size is only known at the end of the Externalize() call.
+ // The difference is the iName->Size()
+
+
+ TUint extNameSize = 0;
+ if( iName )
+ {
+ extNameSize = 2 // When externalized, the << operator writes 2 bytes for the descriptor size
+ + iName->Size(); // iName itself, in bytes. Worst case
+ }
+
+ const TUint size =
+ sizeof( TUint32 ) // iId Low
+ + sizeof( TUint32 ) // iId High
+ + sizeof( TUint32 ) // When externalized, we send the name length, so must include this
+ + extNameSize
+ + sizeof( TUint32 ) // iProcessId Low
+ + sizeof( TUint32 ) // iProcessId High
+ + sizeof( TUint32 ) // iPriority
+ + sizeof( TUint32 ) // iSvcStackPtr
+ + sizeof( TUint32 ) // iSvcStackAddr
+ + sizeof( TUint32 ) // iSvcStackSize
+ + sizeof( TUint32 ) // iUsrStackAddr
+ + sizeof( TUint32 ) // iUsrStackSize
+ + sizeof( TUint32 ) // iObserved
+ + sizeof( TInt32 ) // iLastCpuId
+ + sizeof( TUint32 ) // iHeapBase
+ + sizeof( TUint32 ) // iHeapSize
+ + sizeof( TUint32 ); // iSize When externalized, we send the real externalized size of the buffer
+
+ return size;
+ }
+
+
+EXPORT_C void CThreadInfo::SetLastCpuId(TInt32 aLastCpuId)
+ {
+ iLastCpuId = aLastCpuId;
+ }
+
+EXPORT_C TInt32 CThreadInfo::LastCpuId() const
+ {
+ return iLastCpuId;
+ }
+
+EXPORT_C void CThreadInfo::SetHeapBase(TUint32 aHeapBase)
+ {
+ iHeapBase = aHeapBase;
+ }
+
+EXPORT_C TUint32 CThreadInfo::HeapBase() const
+ {
+ return iHeapBase;
+ }
+
+EXPORT_C void CThreadInfo::SetHeapSize(TUint32 aHeapSize)
+ {
+ iHeapSize = aHeapSize;
+ }
+
+EXPORT_C TUint32 CThreadInfo::HeapSize() const
+ {
+ return iHeapSize;
+ }
+