/** Allocates and constructs a CProcessInfo object. @param aId Kernel process id @param aName Kernel process name @see CProcessInfo::CProcessInfo */ EXPORT_C CProcessInfo* CProcessInfo::NewL( const TUint64 aId, const TDesC & aName ) { 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 ) // Observed + sizeof( TUint32 ); // iSize itself if( size >= MaxSize() ) { LOG_MSG3( "CProcessInfo::NewL() : Descriptorized object = 0x%X bytes would exceed the maximum of 0x%X\n", size, MaxSize() ); User::Leave( KErrTooBig ); } CProcessInfo * data = new (ELeave) CProcessInfo( aId ); CleanupStack::PushL( data ); data->ConstructL( aName ); CleanupStack::Pop(data); return (data); }
/** 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::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); }
/** * Read command line parameters and control the launching of the agents. */ void MainL() { LOG_MSG( "ENTER: t_multi_agent_launcher MainL()"); TInt ret = KErrNone; TInt numAgents = KNumAgents; TInt numTargets = KNumTargets; TInt numTestRuns = KNumTestRuns; TInt argc = User::CommandLineLength(); HBufC* commandLine = NULL; LOG_MSG2("t_multi_agent_launcher: MainL(): argc=%d", argc); if(argc) { commandLine = HBufC::NewLC(argc); TPtr commandLineBuffer = commandLine->Des(); User::CommandLine(commandLineBuffer); RBuf printCommandLine; CleanupClosePushL( printCommandLine ); printCommandLine.CreateL( commandLine->Des().Length() ); printCommandLine.Copy( commandLine->Des() ); printCommandLine.Collapse(); LOG_MSG2("t_multi_agent_launcher: command line = %S", &printCommandLine); CleanupStack::PopAndDestroy( &printCommandLine ); // create a lexer and read through the command line TLex lex(*commandLine); while (!lex.Eos()) { // only look for options with first character '-' if (lex.Get() == '-') { TChar arg = lex.Get(); switch ( arg ) { case 'n': lex.Val( numAgents ); LOG_MSG2("t_multi_agent_launcher: parsed numAgents as %d", numAgents); break; case 'm': lex.Val( numTargets ); LOG_MSG2("t_multi_agent_launcher: parsed numTargets as %d", numTargets); break; case 't': lex.Val( numTestRuns ); LOG_MSG2("t_multi_agent_launcher: parsed numTestRuns as %d", numTestRuns); break; default: LOG_MSG("t_multi_agent_launcher: unknown argument ignoring it"); break; } } } } // Note: below is a workaround to overcome an issue with RTest server crashing // when writing to the windows console from different agents (on different CPUs // at the same time). To overcome this we get signaled by the agents when they have // completed their tests so that we can do a RTest complete RSemaphore launchSemaphore; CleanupClosePushL(launchSemaphore); ret = launchSemaphore.CreateGlobal(KLaunchSemaphoreName, 0); LOG_MSG2( ">Target Launcher : RSemaphore.CreateGlobal ret %d", ret); User::LeaveIfError( ret ); ret = launchSemaphore.OpenGlobal(KLaunchSemaphoreName); LOG_MSG2( ">Target Launcher : RSemaphore.OpenGlobal ret %d", ret); User::LeaveIfError( ret ); //Now launch the requested number of apps for the requested number of test runs for( TInt j = 0; j < numTestRuns; j++ ) { for( TInt i = 0; i < numAgents; i++ ) { RBuf targetName; targetName.CleanupClosePushL(); targetName.CreateL(KAgentExe()); RProcess aProc; CleanupClosePushL(aProc); RBuf launcherOptions; CleanupClosePushL(launcherOptions); const TInt additionalWords = 2; launcherOptions.CreateL( KAgentOptions().Length() + additionalWords ); // Apply offset: launcherOptions.Format( .., .., i * numTargets, ..) // workaround to ensure we have the same binary for multiple agents. // e.g. So if offset = 0, agent attaches to app1, app2, app3, app4, app5 // if offset = 5, agent attached to app6, app7, app8, app9, app10 etc. // Note: apps need to be in rom otherwise the agent will fail on an assert // (with KErrNotFound) launcherOptions.Format( KAgentOptions(), (TUint)numTargets, i * numTargets, 0); ret = LaunchProcess( aProc, targetName, launcherOptions ); CleanupStack::PopAndDestroy(3,&targetName); User::LeaveIfError(ret); } } // Wait for all agents to do their testing before checking the semaphore User::After(12000000); LOG_MSG( ">Target Launcher: Semaphore wait"); for (TInt i = 0; i < numAgents; i ++) { //We need this delay just in case an agent crashes and never signals the sem ret = launchSemaphore.Wait(100000); if( ret != KErrNone ) { LOG_MSG3("launchSemaphore.Wait ret %d for agent %d", ret, i); break; } } LOG_MSG2( "testing for Semaphore ret %d", ret); // We only want to have one RTest instance at any one time since otherwise RTest can panic RTest test(_L("T_MULTI_AGENT_LAUNCHER")); test.Start(_L("t_multi_agent_launcher Check for agents finishing correctly")); test(ret == KErrNone); test.End(); test.Close(); CleanupStack::PopAndDestroy(&launchSemaphore); // launchSemaphore if( commandLine ) CleanupStack::PopAndDestroy(commandLine); LOG_MSG("EXIT: t_multi_agent_launcher MainL()"); }
void CTargetObserver::SetCrashEventL(TEventType aType, TKernelEventAction aAction) { LOG_MSG3("->CTargetObserver::SetCrashEventL(type=%d, action=%d)\n", aType, aAction ); User::LeaveIfError( iSecSess.SetEventAction( iTargetName, aType, aAction )); }