diff -r 000000000000 -r c6b0df440bee dbgsrv/coredumpserver/server/src/servercrashdatasource.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dbgsrv/coredumpserver/server/src/servercrashdatasource.cpp Tue Mar 02 10:33:16 2010 +0530 @@ -0,0 +1,951 @@ +// 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: +// + +#include +#include +#include + +#include "servercrashdatasource.h" + +// Required for interface to Debug Security Server via RSecuritySvrSession +#include "coredumpsession.h" + +CServerCrashDataSource::CServerCrashDataSource(RSecuritySvrSession &aSource) + : iSecSess(aSource) +{ +//no implementation +} + +CServerCrashDataSource* CServerCrashDataSource::NewL(RSecuritySvrSession &aSource) +{ + CServerCrashDataSource *self = new(ELeave) CServerCrashDataSource(aSource); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; +} + + +TTag* CServerCrashDataSource::GetTag(const TTagHeader* aTagHdr, const TInt aElement) + { + TUint8* ptr = (TUint8*)aTagHdr + sizeof(TTagHeader); + TUint8* blockEnd = ptr + (aTagHdr->iNumTags * sizeof(TTag)); + + while(ptr < blockEnd) + { + TTag* tag = (TTag*)ptr; + if(tag->iTagId == aElement) + { + return tag; + } + ptr += sizeof(TTag); + } + return NULL; + } + +// second-phase constructor +void CServerCrashDataSource::ConstructL() + { + LOG_MSG("->CServerCrashDataSource::ConstructL()\n" ); + // Get the debug func block and make appropriate changes to our structures + TInt err; + TUint32 bufsize = 0; + LOG_MSG( " -> iSecSess->GetDebugFunctionalityBufSize( &bufsize )\n" ); + err = iSecSess.GetDebugFunctionalityBufSize( &bufsize ); + + if( (err != KErrNone) || (0 == bufsize) ) + { + // No debug functionality block, cannot do much without that. + LOG_MSG2("CServerCrashDataSource::ConstructL() - unable to get debug functionality block! err:%d\n", err); + User::Leave( KErrNotSupported ); + } + + RBuf8 DFBlock; + DFBlock.CreateL(bufsize); + DFBlock.CleanupClosePushL(); + + LOG_MSG2( " -> HBufC8::NewLC( bufsize=%d )\n", bufsize ); + + + LOG_MSG("CServerCrashDataSource::ConstrucL -> GetDebugFunctionality()\n" ); + err = iSecSess.GetDebugFunctionality(DFBlock); + if( KErrNone != err ) + { + LOG_MSG( "CServerCrashDataSource::ConstructL() : ERROR !* : Could not retrieve debug functionality block\n" ); + User::Leave( KErrNotSupported ); + } + + LOG_MSG( " -> GetDebugHeader( EDF_TagHdrId_RegistersCore )\n" ); + TTagHeader * hdr = GetDebugHeader( ETagHeaderIdRegistersCore, DFBlock ); + + if( hdr == NULL ) + { + LOG_MSG( "Could not retrieve ETagHeaderIdRegistersCore register debug block\n" ); + } + else if( 0 == hdr->iNumTags ) + { + LOG_MSG( "Zero tags found for ETagHeaderIdRegistersCore register debug block\n" ); + } + else + { + + iRegisterList.ReserveL( (TInt)hdr->iNumTags ); + + // Skip the header to get to the tags + TUint8 * ptr = ((TUint8 *) hdr) + sizeof( TTagHeader ); + TTag * tag = (TTag *) ptr; + + TRegisterData regData; + TRegisterData * reg = ®Data; + + // Process all the register tags + for( TInt regIdx = 0; regIdx < hdr->iNumTags; regIdx ++ ) + { + reg->iRegClass = 0; // Core = 0 + reg->iId = tag->iTagId; // + reg->iSubId = 0; // + reg->iSize = 2; // Should all be 32 bits == 2. + reg->iAvailable = ETrue; + reg->iValue64 = 0; + iRegisterList.Append( *reg ); + tag++; + } + } + + hdr = GetDebugHeader( ETagHeaderIdMemory, DFBlock ); + if( hdr == NULL ) + { + LOG_MSG( "Could not retrieve ETagHeaderIdMemory. Cannot read memory\n" ); + iMaxMemReadSize = 0; + } + else if( 0 == hdr->iNumTags ) + { + LOG_MSG( "Zero tags found for ETagHeaderIdMemory register debug block\n" ); + iMaxMemReadSize = 0; + } + else + { + TTag* tag = GetTag( hdr, EMemoryMaxBlockSize ); + if( tag ) + { + //LOG_MSG2( " EMemoryMaxBlockSize =0x%X\n", tag->iValue ); + iMaxMemReadSize = tag->iValue; + } + } + + iLastThreadListSize = 1; + iLastProcListSize = 1; + iLastRegListSize = 1; + + CleanupStack::PopAndDestroy(&DFBlock); + } + +// +// Returns the start of the sub block for this TTagHdrId_e +// +TTagHeader * CServerCrashDataSource::GetDebugHeader( const TTagHeaderId aTagHdrId, const TDesC8 &aDFBlock ) + { + TInt DFBlockSize = aDFBlock.Size(); + + TTagHeader* headerPtr = (TTagHeader*) aDFBlock.Ptr(); + TUint8 * ptr = (TUint8 * ) aDFBlock.Ptr(); + + while( headerPtr < ( (TTagHeader*)aDFBlock.Ptr() + DFBlockSize ) ) + { + + if( headerPtr->iTagHdrId != aTagHdrId ) + { + ptr += sizeof(TTagHeader) + ( headerPtr->iNumTags * sizeof(TTag) ); + headerPtr = (TTagHeader*) ptr; + } + else + { + return ( headerPtr ); + } + } + + return NULL; + } + +// destructor +CServerCrashDataSource::~CServerCrashDataSource() + { + LOG_MSG( "server_crashdatasource.cpp::CServerCrashDataSource::~CServerCrashDataSource()\n" ); + iRegisterList.Reset(); + iThreadListBuffer.Close(); + iProcListBuffer.Close(); + iExecutableListBuffer.Close(); + } + +void CServerCrashDataSource::SetRegValuesL( const TUint64 aThreadId, RRegisterList &aRegisterList ) + { + + LOG_MSG2("->CServerCrashDataSource::SetRegValuesL(aThreadId=%Lu)\n", aThreadId); + + TInt numberOfRegisters = aRegisterList.Count(); + + RBuf8 ids; + ids.CreateL( numberOfRegisters * sizeof(TFunctionalityRegister) ); + ids.CleanupClosePushL(); + + TInt totalByteSize = 0; // Keeps track of the number of bytes that we are requesting + + for( TInt i=0; i < numberOfRegisters; i++ ) + { + TRegisterInfo reg = (TRegisterInfo)( aRegisterList[i].iId ); + + // iSize = (0 == 1 byte); (3 == 8 bytes) + TInt byteSize = (aRegisterList[i].iSize) << 1; + totalByteSize += byteSize; + ids.Append( reinterpret_cast(®), sizeof(TRegisterInfo) ); + } + + + RBuf8 registerValues; + registerValues.CreateL( totalByteSize ); + registerValues.CleanupClosePushL(); + + RBuf8 registerFlags; + registerFlags.CreateL( numberOfRegisters ); + registerFlags.CleanupClosePushL(); + + LOG_MSG("CServerCrashDataSource::SetRegValuesL - reading registers\n"); + User::LeaveIfError(iSecSess.ReadRegisters( aThreadId, ids, registerValues, registerFlags )); + + // Now copy the values back to the array and mark the availability from the flags + + TUint8* valuePtr = (TUint8*) registerValues.Ptr(); + + for( TInt i=0; i < numberOfRegisters; i++ ) + { + + TRegisterData & reg = aRegisterList[i]; + + switch( reg.iSize ) + { + case 0: + reg.iValue8 = *((TUint8 *)valuePtr); + valuePtr += 1; + break; + case 1: + reg.iValue16 = *((TUint16 *)valuePtr); + valuePtr += 2; + break; + case 2: + reg.iValue32 = *((TUint32 *)valuePtr); + valuePtr += 4; + break; + case 3: + reg.iValue64 = *((TUint64 *)valuePtr); + valuePtr += 8; + break; + } + + if( EValid == registerFlags[i] ) + { + reg.iAvailable = ETrue; + } + else + { + reg.iAvailable = EFalse; + } + } + + CleanupStack::PopAndDestroy(®isterFlags); + CleanupStack::PopAndDestroy(®isterValues); + CleanupStack::PopAndDestroy(&ids); + } + + +void CServerCrashDataSource::PrintRegs( RRegisterList & aRegisterList ) + { + + LOG_MSG( "CServerCrashDataSource::PrintRegs()\n" ); + + if( aRegisterList.Count() > 0 ) + { + + + for( TInt i = 0; i < aRegisterList.Count(); i ++ ) + { + + TRegisterData & reg = aRegisterList[i]; + + RDebug::Printf( " reg[%d] iRegClass=%d, iId=%d, iSubId=%d, iSize=%d, iAvailable=%d\n", + i, reg.iRegClass, reg.iId, reg.iSubId, reg.iSize, reg.iAvailable ); + + switch ( reg.iSize ) + { + case 0: + RDebug::Printf( " iValue8=0x%X\n", reg.iValue8 ); break; + case 1: + RDebug::Printf( " iValue16=0x%X\n", reg.iValue16 ); break; + case 2: + RDebug::Printf( " iValue32=0x%X\n", reg.iValue32 ); break; + case 3: + RDebug::Printf( " iValue64=0x%X%X\n", + I64HIGH(reg.iValue64), I64LOW(reg.iValue64) ); + break; + } + } + } + else + { + RDebug::Printf( " No registers to print\n" ); + } + } + + + +void CServerCrashDataSource::GetRegisterListL( RRegisterList & aRegisterList ) + { + + LOG_MSG("CServerCrashDataSource::GetRegisterListL()\n"); + /* Copy the registers that were returned in the debug functionality block */ + + aRegisterList.Reset(); + TInt count = iRegisterList.Count(); + for(TInt i = 0; i < count; ++i) + { + aRegisterList.AppendL( iRegisterList[i] ); + } + } + +void CServerCrashDataSource::ReadRegistersL( const TUint64 aThreadId, RRegisterList & aRegisterList ) + { + + LOG_MSG2("CServerCrashDataSource::ReadRegistersL(aThreadId=%Lu)\n", aThreadId); + + if( aRegisterList.Count() ) + { + LOG_MSG("CServerCrashDataSource::ReadRegistersL - register list already supplied\n" ); + SetRegValuesL( aThreadId, aRegisterList ); + } + else + { + LOG_MSG("CServerCrashDataSource::ReadRegistersL - suppliying register list\n" ); + GetRegisterListL( aRegisterList ); + SetRegValuesL( aThreadId, aRegisterList ); + } + + //PrintRegs( aRegisterList ); + } + + +/** +Purpose: +Read memory from the security server. If the length of the data is greater +than the maximum length supported by the security server (as reported debug +functionality block tag EMemoryMaxBlockSize), break up the read into reads +of this maximum size. + +@pre Must be connected to the debug security server +@pre Must be attached to the process that owns aThreadId + +@param aThreadId - The id of the thread relative to which the read should take place +@param aAddress - The virtual address to read from +@param aLength - The number of bytes to read +@param aData - The buffer to read into +@return Any error which may be returned by Security Server::ReadMemory() +*/ +void CServerCrashDataSource::ReadMemoryL( + const TUint64 aThreadId, + const TUint32 aAddress, + const TUint32 aLength, + TDes8 & aData ) + { + LOG_MSG4("->CServerCrashDataSource::ReadMemoryL(aThreadId=0x%X, aAddress=0x%X, aLength=%d)\n", + I64LOW(aThreadId), aAddress, aLength); + TInt err; + + if( aLength <= iMaxMemReadSize ) + { + err = iSecSess.ReadMemory( aThreadId, aAddress, aLength, aData, EAccess32, EEndLE8); + } + else + { + // If aLength is greater than iMaxMemReadSize, then break up the read into + // smaller packets and append them to aData + + RBuf8 readData; + readData.CreateL( iMaxMemReadSize ); + + TInt readLength = iMaxMemReadSize; + TInt readSoFar = 0; + do + { + LOG_MSG3( " iSecSess->ReadMemory(addr=0x%X, length=%d)\n", aAddress+readSoFar, readLength ); + err = iSecSess.ReadMemory( aThreadId, aAddress+readSoFar, readLength, readData, EAccess32, EEndLE8 ); + if(err != KErrNone) + break; + + readSoFar += readLength; + aData.Append( readData ); + if( (aLength - readSoFar) < iMaxMemReadSize ) + { + readLength = aLength - readSoFar; + } + } + while( readSoFar < aLength ); + readData.Close(); + } + User::LeaveIfError(err); + } + + +void CServerCrashDataSource::GetProcessListL( RProcessPointerList & aProcessList, + TUint & aTotalProcessListDescSize ) + { + //LOG_MSG( "CServerCrashDataSource::GetProcessListL()\n" ); + + // Delete any objects in the array, since we will replace them. + aProcessList.ResetAndDestroy(); + aTotalProcessListDescSize = 0; + + if( iProcListBuffer.Size() != iLastProcListSize ) + { + LOG_MSG2( " iProcListBuffer.ReAlloc( %d)\n", iLastProcListSize ); + iProcListBuffer.ReAllocL( iLastProcListSize ); + } + + DoGetListL( EProcesses, (TUint)(-1), (TUint)(-1), iProcListBuffer, iLastProcListSize ); + + iLastProcListSize = iProcListBuffer.Size(); + + TUint8* ptr = (TUint8*)( iProcListBuffer.Ptr() ); + const TUint8* ptrEnd = ptr + iLastProcListSize; + //LOG_MSG3( " Data start,end=(0x%x, 0x%x)\n", ptr, ptrEnd ); + + while( ptr < ptrEnd ) + { + + TProcessListEntry *entry = (TProcessListEntry*)ptr; + + if( !entry ) + { + LOG_MSG( " ERROR !* : TProcessListEntry is NULL\n" ); + User::Leave(KErrBadHandle); + } + + TUint64 id = entry->iProcessId; + if( entry->iFileNameLength == 0 ) + { + LOG_MSG4( " Skipping process 0x%X%X : entry->iFileNameLength=%d", + I64HIGH(entry->iProcessId), I64LOW(entry->iProcessId), entry->iFileNameLength ); + ptr += Align4( entry->GetSize() ); + continue; + } + + /* + LOG_MSG4( " process 0x%X%X has iFileNameLength=%d", + I64HIGH(entry->iProcessId), I64LOW(entry->iProcessId), entry->iFileNameLength ); + */ + + TPtrC entryName(&(entry->iNames[0]), entry->iFileNameLength); + + CProcessInfo *procInfoPtr = CProcessInfo::NewL(id, entryName ); + + TInt err = aProcessList.Append( procInfoPtr ); + if(err != KErrNone) + { + delete procInfoPtr; + User::Leave(err); + } + + aTotalProcessListDescSize += procInfoPtr->Size(); + + ptr += Align4( entry->GetSize() ); + } + } + + +void CServerCrashDataSource::GetExecutableListL( RExecutablePointerList & aExecutableList, + TUint & aTotalExecutableListDescSize ) + { + LOG_MSG( "CServerCrashDataSource::GetExecutableListL()\n" ); + + // Delete any objects in the array, since we will replace them. + aExecutableList.ResetAndDestroy(); + aTotalExecutableListDescSize = 0; + + if( iExecutableListBuffer.Size() != iLastExecutableListSize ) + { + LOG_MSG2( " iExecutableListBuffer.ReAlloc( %d)\n", iLastExecutableListSize ); + iExecutableListBuffer.ReAllocL( iLastExecutableListSize ); + } + + DoGetListL( EExecutables, (TUint)(-1), (TUint)(-1), iExecutableListBuffer, iLastExecutableListSize ); + + iLastExecutableListSize = iExecutableListBuffer.Size(); + + TUint8* ptr = (TUint8*)( iExecutableListBuffer.Ptr() ); + const TUint8* ptrEnd = ptr + iLastExecutableListSize; + //LOG_MSG3( " Data start,end=(0x%x, 0x%x)\n", ptr, ptrEnd ); + + while( ptr < ptrEnd ) + { + + TExecutablesListEntry *entry = (TExecutablesListEntry*)ptr; + + if( !entry ) + { + LOG_MSG( " ERROR !* : TExecutablesListEntry is NULL\n" ); + User::Leave(KErrBadHandle); + } + + if( entry->iNameLength == 0 ) + { + LOG_MSG( " Skipping executable : entry->iNameLength=0" ); + ptr += Align4( entry->GetSize() ); + continue; + } + + TPtrC entryName(&(entry->iName[0]), entry->iNameLength); + + CExecutableInfo *executableInfoPtr = + CExecutableInfo::NewL(entryName, entry->iIsActivelyDebugged, entry->iIsPassivelyDebugged ); + + TInt err = aExecutableList.Append( executableInfoPtr ); + if(err != KErrNone) + { + delete executableInfoPtr; + User::Leave(err); + } + + aTotalExecutableListDescSize += executableInfoPtr->Size(); + + ptr += Align4( entry->GetSize() ); + } + } + + +void CServerCrashDataSource::DoGetListL(const TListId aListId, + const TThreadId aThreadId, + const TProcessId aProcessId, + RBuf8 & aBuffer, + TUint32 & aSize ) + { + + LOG_MSG5( "->CServerCrashDataSource::DoGetList(aListId=%d, aThredId=%Lu, aProcessId=%Lu, aSize=%d\n", aListId, aThreadId.Id(), aProcessId.Id(), aSize ); + + TInt ret; + TListLevel listLevel; + + if( ((TUint)-1 == (TUint)aThreadId) && ((TUint)-1 == (TUint)aProcessId) ) + { + listLevel = EListGlobal; + ret = iSecSess.GetList( aListId, aBuffer, aSize ); + } + else if( ((TUint)-1 != (TUint)aThreadId) && ((TUint)-1 == (TUint)aProcessId) ) + { + listLevel = EListThread; + LOG_MSG("CServerCrashDataSource::DoGetList - EListThread"); + ret = iSecSess.GetList( aThreadId, aListId, aBuffer, aSize ); + } + else + { + listLevel = EListProcess; + LOG_MSG("CServerCrashDataSource::DoGetList - EListProcess"); + ret = iSecSess.GetList( aProcessId, aListId, aBuffer, aSize ); + } + + while( KErrTooBig == ret ) + { + LOG_MSG2( "CServerCrashDataSource::DoGetListL - list too big, new size=%d\n", aSize ); + + // Too big, and aSize should have been modified to the required new size + // Since the list could have increased in size between calls, give it an + // extra margin. + aSize += 256; + + aBuffer.ReAllocL( aSize ); + + if( EListGlobal == listLevel ) + { + ret = iSecSess.GetList( aListId, aBuffer, aSize ); + } + else if( EListThread == listLevel ) + { + ret = iSecSess.GetList( aThreadId, aListId, aBuffer, aSize ); + } + else + { + ret = iSecSess.GetList( aProcessId, aListId, aBuffer, aSize ); + } + + } + User::LeaveIfError(ret); + } + +/** Obtain the thread list. If aProcessId is negative, we obtain the entire system +thread list. If aProcessId is positive we get the thread list for that process */ +void CServerCrashDataSource::GetThreadListL( const TUint64 aProcessId, + RThreadPointerList & aThreadList, + TUint & aTotalThreadListDescSize ) + { + LOG_MSG2( "->CServerCrashDataSource::GetThreadListL(aProcessId=%Lu)\n", aProcessId); + + // Delete any objects in the array, since we will replace them. + aThreadList.ResetAndDestroy(); + + aTotalThreadListDescSize = 0; + + if( iThreadListBuffer.Size() != iLastThreadListSize ) + { + LOG_MSG2("CServerCrashDataSource::GetThreadListL -> iThreadListBuffer.ReAlloc(%d)\n", iLastThreadListSize ); + iThreadListBuffer.ReAllocL( iLastThreadListSize ); + } + + LOG_MSG( "CServerCrashDataSource::GetThreadListL -> DoGetListL()\n" ); + DoGetListL( EThreads, (TUint)-1, aProcessId, iThreadListBuffer, iLastThreadListSize ); + + iLastThreadListSize = iThreadListBuffer.Size(); + + + CThreadInfo * threadInfoPtr; + RThread thread; + TThreadStackInfo stackInfo; + TThreadListEntry * entry; + TUint usrStackSize; + TLinAddr usrStackAddr; + TLinAddr svcStackPtr; + TLinAddr svcStackBase; + TUint svcStackSize; + + TUint priority; + + TUint8* ptr = (TUint8*)( iThreadListBuffer.Ptr() ); + const TUint8* ptrEnd = ptr + iLastThreadListSize; + //LOG_MSG3( " Data start,end=(0x%x, 0x%x)\n", ptr, ptrEnd ); + + while( ptr < ptrEnd ) + { + + entry = (TThreadListEntry*)ptr; + + if( !entry ) + { + LOG_MSG( " ERROR !* : TThreadListEntry is NULL\n" ); + User::Leave(KErrBadHandle); + } + + if( entry->iNameLength == 0 ) + { + LOG_MSG4( " Skipping Thread 0x%X%X : entry->iNameLength=%d", + I64HIGH(entry->iThreadId), I64LOW(entry->iThreadId), entry->iNameLength ); + ptr += Align4( entry->GetSize() ); + continue; + } + + //LOG_MSG3( " entry &=0x%X, size=%d\n", &(entry->iThreadId), entry->GetSize() ); + //LOG_MSG3( " entry->iThreadId= 0x%X%X\n", I64HIGH(entry->iThreadId), I64LOW(entry->iThreadId) ); + //LOG_MSG3( " found tid=%d, pid=%d\n", I64LOW(entry->iThreadId), I64LOW(entry->iProcessId) ); + + if( entry->iSupervisorStackPtrValid ) + { + svcStackPtr = entry->iSupervisorStackPtr; + } + else + { + svcStackPtr = 0; + } + + if( entry->iSupervisorStackBaseValid ) + { + svcStackBase = entry->iSupervisorStackBase; + } + else + { + svcStackBase = 0; + } + + if( entry->iSupervisorStackSizeValid ) + { + svcStackSize = entry->iSupervisorStackSize; + } + else + { + svcStackSize = 0; + } + + + + if( KErrNone == thread.Open( entry->iThreadId ) ) + { + priority = (TUint)(thread.Priority()); + + if( KErrNone == thread.StackInfo( stackInfo ) ) + { + usrStackAddr = stackInfo.iLimit; + usrStackSize = stackInfo.iBase - stackInfo.iLimit; + } + else + { + usrStackSize = 0; + usrStackAddr = 0; + } + + thread.Close(); + } + else + { + usrStackSize = 0; + usrStackAddr = 0; + priority = 0; + } + + /* + LOG_MSG3( " entry->iNameLength=%d, &(entry->iName[0])=0x%X\n", + entry->iNameLength, &(entry->iName[0]) ); + */ + + TPtrC entryName( &(entry->iName[0]), entry->iNameLength ); + //LOG_MSG2( " -> threadInfoPtr = CThreadInfo::NewL( name.Size()=%d)\n", entryName.Size() ); + + threadInfoPtr = CThreadInfo::NewL( + entry->iThreadId, + entryName, + entry->iProcessId, + (TUint)priority, + svcStackPtr, + svcStackBase, + svcStackSize, + usrStackAddr, + usrStackSize ); + + /* + LOG_MSG3( " threadInfoPtr->iSvcStackAddr=0x%X, threadInfoPtr->iSvcStackSize=0x%X\n", + threadInfoPtr->SvcStackAddr(), threadInfoPtr->SvcStackSize() ); + */ + + TInt err = aThreadList.Append( threadInfoPtr ); + if( err != KErrNone ) + { + // We use this id so as not to use Push(), AppendL(), Pop() + delete threadInfoPtr; + User::Leave( err ); + } + + aTotalThreadListDescSize += threadInfoPtr->Size(); + + /* + LOG_MSG3( " aTotalThreadListDescSize = %d after adding %d\n", + aTotalThreadListDescSize, threadInfoPtr->Size() ); + + RBuf rPrintBuf; + rPrintBuf.Create( threadInfoPtr->Name()); + RDebug::Printf( " <- rPrintBuf.Create(), rPrintBuf.Length()=%d\n", rPrintBuf.Length() ); + char* cl = (char*) rPrintBuf.Collapse().PtrZ(); + RDebug::Printf(" name=%s\n", cl ); + rPrintBuf.Close(); + */ + + ptr += Align4( entry->GetSize() ); + //LOG_MSG2( " ptr += Align4(entry->GetSize()) = 0x%X\n", ptr ); + + } // while + + } + +void CServerCrashDataSource::GetCodeSegmentsL( const TUint64 aTid, RCodeSegPointerList &aCodeSegList, TUint & aTotalCodeSegListDescSize ) + { + LOG_MSG2("->CServerCrashDataSource::GetCodeSegmentsL(aTid=%Lu)\n", aTid ); + + aCodeSegList.ResetAndDestroy(); + aTotalCodeSegListDescSize = 0; + + TUint32 size = KMaxFileName; + RBuf8 buffer; + buffer.CreateL(KMaxFileName); + CleanupClosePushL(buffer); + + DoGetListL( ECodeSegs, aTid, (TUint)-1, buffer, size ); + LOG_MSG2( " DoGetListL( ECodeSegs ) returned buffer.Size()=0x%X\n", buffer.Size() ); + + TUint8* ptr = (TUint8*)buffer.Ptr(); + const TUint8* ptrEnd = ptr + size; + + while(ptr < ptrEnd) + { + TCodeSegListEntry* entry = (TCodeSegListEntry*)ptr; + + LOG_MSG4( " entry->CodeBase=0x%X, CodeSize=0x%X, ConstDataSize=0x%X\n", + entry->iCodeBase, entry->iCodeSize, entry->iConstDataSize ); + LOG_MSG4( " InitDataBase=0x%X, InitDataSize=0x%X, UnintDataSize=0x%X\n", + entry->iInitialisedDataBase, entry->iInitialisedDataSize, entry->iUninitialisedDataSize ); + LOG_MSG3( " IsXip=0x%X, CodeSegType=0x%X\n", entry->iIsXip, entry->iCodeSegType ); + + TCodeSegInfo *codeSeg = new(ELeave) TCodeSegInfo; + + TPtr name(&(entry->iName[0]), entry->iNameLength, entry->iNameLength); + codeSeg->iName = name; + + codeSeg->iType = entry->iCodeSegType; + codeSeg->iXIP = entry->iIsXip; + + codeSeg->iCodeSize = entry->iCodeSize; + codeSeg->iCodeRunAddr = entry->iCodeBase; + if( codeSeg->iXIP ) + { + codeSeg->iCodeLoadAddr = codeSeg->iCodeRunAddr; + } + else + { + codeSeg->iCodeLoadAddr = 0; //TODO + } + + codeSeg->iRoDataSize = entry->iConstDataSize; + codeSeg->iRoDataRunAddr = entry->iCodeBase + entry->iCodeSize; + if( codeSeg->iXIP ) + { + codeSeg->iRoDataLoadAddr = codeSeg->iRoDataRunAddr; + } + else + { + codeSeg->iRoDataLoadAddr = 0; //TODO + } + + codeSeg->iDataSize = entry->iInitialisedDataSize + entry->iUninitialisedDataSize; + codeSeg->iDataRunAddr = entry->iInitialisedDataBase; + if( codeSeg->iXIP ) + { + codeSeg->iDataLoadAddr = codeSeg->iDataRunAddr; + } + else + { + codeSeg->iDataLoadAddr = 0; //TODO + } + + TInt err = aCodeSegList.Append(codeSeg); + if(err != KErrNone) + { + delete codeSeg; + User::Leave(err); + } + + aTotalCodeSegListDescSize += sizeof(TCodeSegInfo); + ptr += Align4(entry->GetSize()); + } + + CleanupStack::PopAndDestroy(&buffer); + } + +/** + * Returns the size of the trace data available + * @return Trace Size + * @leave One of the system wide codes + */ +TUint CServerCrashDataSource::GetAvailableTraceSizeL() + { + LOG_MSG("->CServerCrashDataSource::GetAvailableTraceSizeL()"); + + RBTrace trace; + User::LeaveIfError(trace.Open()); + + TUint8 *data = NULL; + TInt size = trace.GetData(data); + + trace.Close(); + + return size; + } + +/** + Reads data from the trace buffer into the supplied descriptor. Not supported. Recommended + approach is to use the live trace framework. + @param aTraceData The buffer to be read into + @param aPos Ignored +*/ +void CServerCrashDataSource::ReadTraceBufferL(TDes8 &aTraceData, TUint aPos) + { + LOG_MSG("->CServerCrashDataSource::ReadTraceBuffer() -- Not supported: Please use the live trace system"); + + User::Leave(KErrNotSupported); + } + +/** + * Gets locks data + * @param aLockData stores lock data + * @leave one of the OS wide codes + */ +void CServerCrashDataSource::GetLocksL(TSCMLockData& aLockData) + { + User::Leave(KErrNotSupported); + } + +/** + * Gets the ROM build info if available + * @param aRomHeader + * @leave one of the OS wide codes + */ +void CServerCrashDataSource::GetROMBuildInfoL(TRomHeaderData& aRomHeader) + { + User::Leave(KErrNotSupported); + } + +/** + * @see CCrashDataSource::GetExceptionStackSizeL + */ +TUint CServerCrashDataSource::GetExceptionStackSizeL(const Debug::TArmProcessorModes aMode) + { + User::Leave(KErrNotSupported); + return 0; //comp warnings + } + +/** + * @see CCrashDataSource::GetExceptionStackL + */ +void CServerCrashDataSource::GetExceptionStackL(const Debug::TArmProcessorModes aMode, TDes8& aStack, TUint aStartReadPoint) + { + User::Leave(KErrNotSupported); + } + +/** + * @see CCrashDataSource::GetVersion + */ +TVersion CServerCrashDataSource::GetVersion() const + { + return KServerCrashDataSourceVersion; + } + +/** + * @see CCrashDataSource::GetDataSourceFunctionalityBufSize + */ +TInt CServerCrashDataSource::GetDataSourceFunctionalityBufSize(TUint& aBufSize) + { + return KErrNotSupported; + } + +/** + * @see CCrashDataSource::GetDataSourceFunctionality + */ +TInt CServerCrashDataSource::GetDataSourceFunctionality(TDes8& aFuncBuffer) + { + return KErrNotSupported; + } + +TInt CServerCrashDataSource::GetVariantSpecificDataSize(TUint& aDataSize) + { + (void)aDataSize; + return KErrNotSupported; + } + +TInt CServerCrashDataSource::GetVariantSpecificData(TDes8 &aVarSpecData) + { + (void)aVarSpecData; + return KErrNotSupported; + } + +//eof