dbgsrv/coredumpserver/cdssupport/src/threaddata.cpp
changeset 0 c6b0df440bee
equal deleted inserted replaced
-1:000000000000 0:c6b0df440bee
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implemetation of CThreadInfo class 
       
    15 //
       
    16 
       
    17 
       
    18 
       
    19 /**
       
    20  @file
       
    21  @see CThreadInfo
       
    22 */
       
    23 
       
    24 
       
    25 #include <rm_debug_api.h>
       
    26 #include <debuglogging.h> 
       
    27 #include <threaddata.h>
       
    28 
       
    29 /**
       
    30 Allocates and constructs a CThreadInfo object.
       
    31 @param aId Kernel thread id
       
    32 @param aName Kernel thread name
       
    33 @param aProcessId Kernel id of owning process
       
    34 @param aPriority Kernel thread priority TThreadPriority
       
    35 @param aSvcStackPtr Thread supervisor stack pointer
       
    36 @param aSvcStackAddr Thread supervisor mode stack base address
       
    37 @param aSvcStackSize Thread supervisor mode stack size in bytes
       
    38 @param aUsrStackAddr Thread user mode stack base address
       
    39 @param aUsrStackSize Thread user mode stack base size in bytes
       
    40 
       
    41 @see CThreadInfo::CThreadInfo
       
    42 */
       
    43 EXPORT_C CThreadInfo* CThreadInfo::NewL( 
       
    44 										const TUint64	& aId,
       
    45 										const TDesC		& aName, 
       
    46 										const TUint64	& aProcessId,
       
    47 										const TUint		& aPriority,
       
    48 										const TLinAddr	& aSvcStackPtr,
       
    49 										const TLinAddr	& aSvcStackAddr,
       
    50 										const TUint		& aSvcStackSize,
       
    51 										const TLinAddr	& aUsrStackAddr,
       
    52 										const TUint		& aUsrStackSize )
       
    53 	{
       
    54 
       
    55 	// Add up the potential maximum size of the externalized object
       
    56 	const TUint size = 
       
    57 		  sizeof( TUint32 )		// iId Low
       
    58 		+ sizeof( TUint32 )		// iId High
       
    59 
       
    60 		+ sizeof( TUint32 )		// When externalized, we send the name length, so must include this
       
    61 		+ 2						// When externalized, the << operator writes 2 bytes for the descriptor size
       
    62 		+ aName.Size()			// iName Size, in bytes.
       
    63 
       
    64 		+ sizeof( TUint32 )		// iProcessId Low
       
    65 		+ sizeof( TUint32 )		// iProcessId High
       
    66 		+ sizeof( TUint32 )		// iPriority
       
    67 		+ sizeof( TUint32 )		// iSvcStackPtr
       
    68 		+ sizeof( TUint32 )		// iSvcStackAddr
       
    69 		+ sizeof( TUint32 )		// iSvcStackSize
       
    70 		+ sizeof( TUint32 )		// iUsrStackAddr
       
    71 		+ sizeof( TUint32 )		// iUsrStackSize
       
    72 		+ sizeof( TUint32 )		// iObserved
       
    73 
       
    74 		+ sizeof( TUint32 );	// iSize itself
       
    75 
       
    76 	if( size >= MaxSize() )
       
    77 		{
       
    78 		LOG_MSG3( "CThreadInfo::NewL() : Descriptorized object = 0x%X bytes would exceed the maximum of 0x%X\n", 
       
    79 			size, MaxSize() );
       
    80 
       
    81 		User::Leave( KErrTooBig );
       
    82 		}
       
    83 
       
    84 	CThreadInfo * data = new (ELeave) CThreadInfo(	aId, 
       
    85 													aProcessId, 
       
    86 													aPriority, 
       
    87 													aSvcStackPtr,
       
    88 													aSvcStackAddr,
       
    89 													aSvcStackSize,
       
    90 													aUsrStackAddr,
       
    91 													aUsrStackSize );
       
    92 	CleanupStack::PushL( data );
       
    93 	
       
    94 	data->ConstructL( aName );
       
    95 
       
    96 	CleanupStack::Pop(data);
       
    97 
       
    98 	return (data);
       
    99 
       
   100 	}
       
   101 
       
   102 
       
   103 /**
       
   104 Allocates and constructs a CThreadInfo object from a descriptor. 
       
   105 The descriptor contains an externalised version of a CThreadInfo object.
       
   106 This method is typically used to obtain a CThreadInfo object from a 
       
   107 descriptor returned by the core dump server.
       
   108 
       
   109 @param aStreamData Descriptor with externalised/streamed object
       
   110 @see InternalizeL
       
   111 @see ExternalizeL
       
   112 */
       
   113 EXPORT_C CThreadInfo* CThreadInfo::NewL( const TDesC8 & aStreamData )
       
   114 	{
       
   115 
       
   116 	CThreadInfo* self = new (ELeave) CThreadInfo();
       
   117 	
       
   118 	CleanupStack::PushL( self );
       
   119 	
       
   120 	// Open a read stream for the descriptor
       
   121 	RDesReadStream stream( aStreamData );
       
   122 
       
   123 	CleanupClosePushL( stream );
       
   124 
       
   125 	self->InternalizeL( stream );
       
   126 
       
   127 	CleanupStack::PopAndDestroy( &stream ); // finished with the stream
       
   128 
       
   129 	CleanupStack::Pop( self );
       
   130 
       
   131 	return ( self );
       
   132 
       
   133 	}
       
   134 
       
   135 
       
   136 /**
       
   137 Destructor. Deletes name if allocated.
       
   138 */
       
   139 EXPORT_C CThreadInfo::~CThreadInfo()
       
   140 	{
       
   141 
       
   142 	if( NULL != iName )
       
   143 		{
       
   144 		delete iName;
       
   145 		}
       
   146 	}
       
   147 
       
   148 /**
       
   149 Set the name of the thread by deleting, allocating and then copying the parameter.
       
   150 @param aName Name of the thread to set to 
       
   151 @see ConstructL()
       
   152 */
       
   153 EXPORT_C void CThreadInfo::NameL( const TDesC & aName )
       
   154 	{
       
   155 
       
   156 	if( aName.Length() > 0 )
       
   157 		{
       
   158 		TUint toCopy = aName.Length();
       
   159 		iName = HBufC::NewL( toCopy );
       
   160 		TPtr nameDes = iName->Des();
       
   161 
       
   162 		nameDes.Copy( aName.Ptr(), toCopy );
       
   163 		nameDes.SetLength( toCopy );
       
   164 		}
       
   165 	else
       
   166 		{
       
   167 		iName = NULL;
       
   168 		}
       
   169 	}
       
   170 
       
   171 
       
   172 /**
       
   173 First phase contructor. Sets the size to 0, name to NULL.
       
   174 @see CThreadInfo::NewL()
       
   175 */
       
   176 CThreadInfo::CThreadInfo(	const TUint64	& aId,
       
   177 							const TUint64	& aProcessId,
       
   178 							const TUint		& aPriority,
       
   179 							const TLinAddr	& aSvcStackPtr,
       
   180 							const TLinAddr	& aSvcStackAddr,
       
   181 							const TUint		& aSvcStackSize,
       
   182 							const TLinAddr	& aUsrStackAddr,
       
   183 							const TUint		& aUsrStackSize ) :
       
   184 	iId			 ( aId ),
       
   185 	iName		 ( NULL ),
       
   186 	iProcessId	 ( aProcessId ),
       
   187 	iPriority	 ( aPriority ), 
       
   188 	iSvcStackPtr ( aSvcStackPtr ),
       
   189 	iSvcStackAddr( aSvcStackAddr ),
       
   190 	iSvcStackSize( aSvcStackSize ),
       
   191 	iUsrStackAddr( aUsrStackAddr ),
       
   192 	iUsrStackSize( aUsrStackSize ),
       
   193 	iObserved    ( EFalse ),
       
   194 	iSize        ( 0 ), 
       
   195 	iLastCpuId	 ( -1 )
       
   196 	{
       
   197 	
       
   198 	}
       
   199 
       
   200 
       
   201 /**
       
   202 Second phase constructor initialises the name of the thread.
       
   203 @param aName Thread name
       
   204 @see NameL()
       
   205 */
       
   206 void CThreadInfo::ConstructL(  const TDesC & aName )
       
   207 	{
       
   208 	NameL( aName );
       
   209 	}
       
   210 
       
   211 
       
   212 
       
   213 /**
       
   214 Initialise this object with the contents of RReadStream aStream.
       
   215 The descriptor contains an externalised version of an object.
       
   216 This method is typically used to obtain a CThreadInfo object from 
       
   217 the core dump server.
       
   218 Any modifications to this method should be synchronised with ExternalizeL().
       
   219 Also note that the methods used from RReadStream (>> or ReadUint32L) 
       
   220 can behave differently, especially for descriptors.
       
   221 @param aStream Stream with streamed object
       
   222 @see ExternalizeL
       
   223 @see RReadStream
       
   224 @pre Call Externalise to obtain the stream containing an externalised 
       
   225 version of this object.
       
   226 */
       
   227 EXPORT_C void CThreadInfo::InternalizeL( RReadStream & aStream )
       
   228 	{
       
   229 
       
   230 	TUint32 idLow = aStream.ReadUint32L(); 
       
   231 
       
   232 	TUint32 idHigh = aStream.ReadUint32L(); 
       
   233 	iId = MAKE_TUINT64( idHigh, idLow );
       
   234 
       
   235 	if( NULL != iName )
       
   236 		{
       
   237 		//LOG_MSG( " iName != NULL\n" );
       
   238 		delete iName;
       
   239 		iName = NULL;
       
   240 		}	
       
   241 
       
   242 	TUint32 nameLength = aStream.ReadUint32L(); 
       
   243 
       
   244 	if ( nameLength > 0 )
       
   245 		{
       
   246 		iName = HBufC::NewL( aStream, nameLength ); 
       
   247 		}
       
   248 	else
       
   249 		{
       
   250 		iName  = NULL;
       
   251 		}
       
   252 
       
   253 	TUint32 pidLow = aStream.ReadUint32L(); 
       
   254 	TUint32 pidHigh = aStream.ReadUint32L(); 
       
   255 	iProcessId = MAKE_TUINT64( pidHigh, pidLow );
       
   256 
       
   257 	iPriority     = aStream.ReadUint32L(); 
       
   258 	iSvcStackPtr  = aStream.ReadUint32L() ;
       
   259 	iSvcStackAddr = aStream.ReadUint32L() ;
       
   260 	iSvcStackSize = aStream.ReadUint32L() ;
       
   261 	iUsrStackAddr = aStream.ReadUint32L() ;
       
   262 	iUsrStackSize = aStream.ReadUint32L() ;
       
   263 	iObserved     = static_cast<TBool>(aStream.ReadUint32L());
       
   264 	iLastCpuId = aStream.ReadUint32L();
       
   265 	iHeapBase = aStream.ReadUint32L();
       
   266 	iHeapSize = aStream.ReadUint32L();
       
   267 	iSize = aStream.ReadUint32L() ;
       
   268 	}
       
   269 
       
   270 
       
   271 
       
   272 
       
   273 
       
   274 /**
       
   275 Make a streamed representation of this object to RWriteStream aStream.
       
   276 
       
   277 This method is typically by the core dump server when contructing a list of 
       
   278 CThreadInfo for a client.
       
   279 Any modifications to this method should be synchronised with InternalizeL(). 
       
   280 Also note that the methods used from RWriteStream (>> or WriteUint32L) can behave differently,
       
   281 especially for descriptors.
       
   282 @param aStream Stream to stream object onto
       
   283 @param buf Buffer onto the same stream, used to obtain correct size of externalised object
       
   284 @see InternalizeL
       
   285 @see RReadStream
       
   286 @see RWriteStream
       
   287 @post The stream contains an externalised version of this object.
       
   288 */
       
   289 EXPORT_C void CThreadInfo::ExternalizeL( RWriteStream & aStream, CBufFlat* buf )
       
   290 	{
       
   291 
       
   292 	const TUint32 idLow = I64LOW( iId ); 
       
   293 	const TUint32 idHigh = I64HIGH( iId ); 
       
   294 
       
   295 	// Take the size of the buffer before we add anything to it.
       
   296 	TUint startBufSize = buf->Size();
       
   297 
       
   298 	aStream.WriteUint32L( idLow ); 
       
   299 	aStream.WriteUint32L( idHigh ); 
       
   300 
       
   301 	TUint nameLength = 0;
       
   302 
       
   303 	if ( NULL != iName )
       
   304 		{
       
   305 		nameLength = iName->Des().Length();
       
   306 		if( nameLength > 0 )
       
   307 			{
       
   308 			// Write the number of character elements in the name. 
       
   309 			aStream.WriteUint32L( nameLength ); 
       
   310 			aStream << iName->Des();
       
   311 			}
       
   312 		}
       
   313 
       
   314 	if( nameLength == 0 )
       
   315 		{
       
   316 		aStream.WriteUint32L( 0 ); 
       
   317 		}
       
   318 
       
   319 	const TUint32 pIdLow = I64LOW( iProcessId ); 
       
   320 	const TUint32 pIdHigh = I64HIGH( iProcessId ); 
       
   321 	aStream.WriteUint32L( pIdLow ); 
       
   322 	aStream.WriteUint32L( pIdHigh );
       
   323 	
       
   324 	aStream.WriteUint32L( iPriority     ); 
       
   325 
       
   326 	aStream.WriteUint32L( iSvcStackPtr  ) ;
       
   327 	aStream.WriteUint32L( iSvcStackAddr ) ;
       
   328 	aStream.WriteUint32L( iSvcStackSize ) ;
       
   329 	aStream.WriteUint32L( iUsrStackAddr );
       
   330 	aStream.WriteUint32L( iUsrStackSize );
       
   331 	aStream.WriteUint32L( static_cast<TUint32>(iObserved) );
       
   332 	aStream.WriteInt32L(iLastCpuId);
       
   333 	aStream.WriteUint32L( iHeapBase );
       
   334 	aStream.WriteUint32L( iHeapSize );
       
   335 
       
   336 	// The real exteranlized size is the size of the buffer up to here plus the 
       
   337 	// 4 bytes for the size itself
       
   338 	iSize = buf->Size() - startBufSize + 4;
       
   339 	aStream.WriteUint32L( iSize );
       
   340 
       
   341 	}
       
   342 
       
   343 /**
       
   344 Obtain the kernel thread id.
       
   345 */
       
   346 EXPORT_C const TUint64 & CThreadInfo::Id() const 
       
   347 	 { 
       
   348 	 return ( iId ); 
       
   349 	 }
       
   350 
       
   351 /**
       
   352 Obtain the kernel thread name.
       
   353 */
       
   354 EXPORT_C const TDesC & CThreadInfo::Name() const 
       
   355 	{ 
       
   356 	return ( *iName ); 
       
   357 	}
       
   358 
       
   359 /**
       
   360 Obtain the kernel owning process id.
       
   361 */
       
   362 EXPORT_C const TUint64 & CThreadInfo::ProcessId() const 
       
   363 	 { 
       
   364 	 return ( iProcessId );
       
   365 	 }
       
   366 
       
   367 /**
       
   368 Obtain the kernel priority.
       
   369 */
       
   370 EXPORT_C TUint CThreadInfo::Priority() const 
       
   371 	 { 
       
   372 	 return ( iPriority ); 
       
   373 	 }
       
   374 
       
   375 /**
       
   376 Obtain the kernel supervisor mode stack pointer.
       
   377 */
       
   378 EXPORT_C TUint CThreadInfo::SvcStackPtr() const 
       
   379 	 { 
       
   380 	 return ( iSvcStackPtr ); 
       
   381 	 }
       
   382 
       
   383 /**
       
   384 Obtain the kernel supervisor mode stack base address.
       
   385 */
       
   386 EXPORT_C TUint CThreadInfo::SvcStackAddr() const 
       
   387 	 { 
       
   388 	 return ( iSvcStackAddr ); 
       
   389 	 }
       
   390 
       
   391 /**
       
   392 Obtain the kernel supervisor mode stack size in bytes.
       
   393 */
       
   394 EXPORT_C TUint CThreadInfo::SvcStackSize() const 
       
   395 	 { 
       
   396 	 return ( iSvcStackSize ); 
       
   397 	 }
       
   398 
       
   399 /**
       
   400 Obtain the kernel user mode stack base address.
       
   401 */
       
   402 EXPORT_C TUint CThreadInfo::UsrStackAddr() const 
       
   403 	 { 
       
   404 	 return ( iUsrStackAddr ); 
       
   405 	 }
       
   406 
       
   407 /**
       
   408 Obtain the kernel user mode stack size in bytes.
       
   409 */
       
   410 EXPORT_C TUint CThreadInfo::UsrStackSize() const 
       
   411 	 { 
       
   412 	 return ( iUsrStackSize ); 
       
   413 	 }
       
   414 
       
   415 
       
   416 /**
       
   417 Returns ETrue if the thread is being explicitly observed for crashes by the Core Dump Server.
       
   418 If only the owning process is being observed, this method returns EFalse.
       
   419 */
       
   420 EXPORT_C TBool CThreadInfo::Observed() const 
       
   421 	 { 
       
   422 	 return ( iObserved ); 
       
   423 	 }
       
   424 
       
   425 /**
       
   426 Set whether this thread is being observed for crashes by the Core Dump Server.
       
   427 */
       
   428 EXPORT_C void CThreadInfo::Observed(TBool aFlag) 
       
   429 	 { 
       
   430 	 iObserved = aFlag; 
       
   431 	 }
       
   432 
       
   433 CThreadInfo::CThreadInfo()
       
   434 	{
       
   435 	}
       
   436 
       
   437 
       
   438 /**
       
   439 Get the maximum size allowed for this object. This is needed as the object is passed  
       
   440 across the Client Server interface.
       
   441 */
       
   442 EXPORT_C TInt CThreadInfo::MaxSize()
       
   443 	{
       
   444 	
       
   445 	const TInt maxSize = 512;
       
   446 	return maxSize;
       
   447 	}
       
   448 
       
   449 
       
   450 /**
       
   451 Gets the size of the object when externalized. The sizeofs used to calculate this 
       
   452 must match the operators used in ExternalizeL and InternalizeL.
       
   453 Special attention must be paid to the name. If the object has not been 
       
   454 externalized yet then this method returns the maximum that it could take.
       
   455 The name descriptor is compressed when externalized, so it is not its Size().
       
   456 Furthermore the << operator adds two bytes to the stream when externalizing 
       
   457 a descriptor
       
   458 */
       
   459 EXPORT_C TInt CThreadInfo::Size() const
       
   460 	{
       
   461 
       
   462 	if( iSize != 0 )
       
   463 		{
       
   464 		return iSize;
       
   465 		}
       
   466 
       
   467 	// This is the maximum size of the object when externalized.
       
   468 	// It is a maximum since externalizing 16 bit descriptors compresses the data,
       
   469 	// and thus the real externalized size is only known at the end of the Externalize() call.
       
   470 	// The difference is the iName->Size()
       
   471 
       
   472 
       
   473 	TUint extNameSize = 0;
       
   474 	if( iName )
       
   475 		{
       
   476 		extNameSize = 2					// When externalized, the << operator writes 2 bytes for the descriptor size
       
   477 					+ iName->Size();	// iName itself, in bytes. Worst case
       
   478 		}
       
   479 
       
   480 	const TUint size = 
       
   481 		  sizeof( TUint32 )		// iId Low
       
   482 		+ sizeof( TUint32 )		// iId High
       
   483 		+ sizeof( TUint32 )		// When externalized, we send the name length, so must include this
       
   484 		+ extNameSize
       
   485 		+ sizeof( TUint32 )		// iProcessId Low
       
   486 		+ sizeof( TUint32 )		// iProcessId High
       
   487 		+ sizeof( TUint32 )		// iPriority
       
   488 		+ sizeof( TUint32 )		// iSvcStackPtr
       
   489 		+ sizeof( TUint32 )		// iSvcStackAddr
       
   490 		+ sizeof( TUint32 )		// iSvcStackSize
       
   491 		+ sizeof( TUint32 )		// iUsrStackAddr
       
   492 		+ sizeof( TUint32 )  	// iUsrStackSize
       
   493 		+ sizeof( TUint32 )  	// iObserved
       
   494 		+ sizeof( TInt32 )  	// iLastCpuId
       
   495 		+ sizeof( TUint32 )  	// iHeapBase
       
   496 		+ sizeof( TUint32 )  	// iHeapSize
       
   497 		+ sizeof( TUint32 );	// iSize When externalized, we send the real externalized size of the buffer
       
   498 	
       
   499 	return size;
       
   500 	}
       
   501 
       
   502 
       
   503 EXPORT_C void  CThreadInfo::SetLastCpuId(TInt32 aLastCpuId)
       
   504 	{
       
   505 	iLastCpuId = aLastCpuId;
       
   506 	}
       
   507 
       
   508 EXPORT_C TInt32  CThreadInfo::LastCpuId() const
       
   509 	{
       
   510 	return iLastCpuId;
       
   511 	}
       
   512 
       
   513 EXPORT_C void  CThreadInfo::SetHeapBase(TUint32 aHeapBase)
       
   514 	{
       
   515 	iHeapBase = aHeapBase;
       
   516 	}
       
   517 
       
   518 EXPORT_C TUint32  CThreadInfo::HeapBase() const
       
   519 	{
       
   520 	return iHeapBase;
       
   521 	}
       
   522 
       
   523 EXPORT_C void  CThreadInfo::SetHeapSize(TUint32 aHeapSize)
       
   524 	{
       
   525 	iHeapSize = aHeapSize;
       
   526 	}
       
   527 
       
   528 EXPORT_C TUint32  CThreadInfo::HeapSize() const
       
   529 	{
       
   530 	return iHeapSize;
       
   531 	}
       
   532