// :FIXME: improve API TInt DKdaChannel::GetCodeSegs(RMinKda::TCodeSnapshotParams* aParams) { RMinKda::TCodeSnapshotParams params; umemget32(¶ms, aParams, sizeof(params)); TInt maxcount; umemget32(&maxcount, params.iCountPtr, sizeof(maxcount)); __KTRACE_OPT(KDEBUGGER, Kern::Printf(">DKdaChannel::GetCodeSegs pid=%d maxcount=%d", params.iPid, maxcount)); __ASSERT_DEBUG(! iTempObj, Kern::Fault(KFault, __LINE__)); TInt r = OpenTempObject(params.iPid, EProcess); if (r != KErrNone) { __KTRACE_OPT(KDEBUGGER, Kern::Printf("<DKdaChannel::GetCodeSegs process not found")); return r; } DProcess* pP = (DProcess*)iTempObj; Kern::AccessCode(); SDblQue q; TInt actcount = pP->TraverseCodeSegs(&q, NULL, DCodeSeg::EMarkDebug, DProcess::ETraverseFlagAdd); CloseTempObject(); TInt n = Min(actcount, maxcount); SDblQueLink* pL = q.iA.iNext; r = KErrNone; for (TInt i=0; i<n; ++i, pL = pL->iNext) { DCodeSeg* pS = _LOFF(pL, DCodeSeg, iTempLink); XTRAP(r, XT_DEFAULT, umemput32(params.iHandles + i, &pS, sizeof(TAny*))); if (r != KErrNone) break; } DCodeSeg::EmptyQueue(q, DCodeSeg::EMarkDebug); Kern::EndAccessCode(); if (r == KErrBadDescriptor) Kern::PanicCurrentThread(KLitKernExec, ECausedException); umemput32(params.iCountPtr, &actcount, sizeof(actcount)); __KTRACE_OPT(KDEBUGGER, Kern::Printf("<DKdaChannel::GetCodeSegs actcount=%d", actcount)); return r; }
TInt DKdaChannel::GetThreadInfo(TUint aTid, TAny* aInfo) { TInt r = OpenTempObject(aTid, EThread); if (r == KErrNone) { DThread* pT = (DThread*)iTempObj; TDbgThreadInfo info; pT->FullName(info.iFullName); info.iPid = pT->iOwningProcess->iId; info.iStackBase = pT->iUserStackRunAddress; info.iStackSize = pT->iUserStackSize; info.iExitCategory = pT->iExitCategory; info.iExitReason = pT->iExitReason; GetThreadCpuInfo(pT, info.iCpu); umemput32(aInfo, &info, sizeof(info)); CloseTempObject(); } return r; }
TInt DKdaChannel::ReadMem(RMinKda::TReadMemParams* aParams) { RMinKda::TReadMemParams params; umemget32(¶ms, aParams, sizeof(params)); TInt destLen; TInt destMax; TUint8* destPtr = (TUint8*)Kern::KUDesInfo(*params.iDes, destLen, destMax); TInt r = OpenTempObject(params.iTid, EThread); if (r == KErrNone) { r = Kern::ThreadRawRead((DThread*)iTempObj, (TAny*)params.iAddr, destPtr, destMax); if (r == KErrNone) Kern::KUDesSetLength(*params.iDes, destMax); CloseTempObject(); } return r; }
TInt DMemSpyDriverLogChanChunks::GetChunkHandles( TMemSpyDriverInternalChunkHandleParams* aParams ) { TMemSpyDriverInternalChunkHandleParams params; TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalChunkHandleParams) ); if ( r != KErrNone ) { TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - END - params read error: %d", r)); return r; } const TInt maxCount = params.iMaxCount; TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - START - id: %d, maxCount: %d, type: %d", params.iId, maxCount, params.iType)); DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread(); DMemSpyDriverOSAdaptionDProcess& processAdaption = OSAdaption().DProcess(); // This variable holds the number of handles that we have already // written to the client-side. TInt currentWriteIndex = 0; if ( params.iType == EMemSpyDriverPrivateObjectTypeProcess || params.iType == EMemSpyDriverPrivateObjectTypeThread ) { if ( params.iType == EMemSpyDriverPrivateObjectTypeThread ) { r = OpenTempObject( params.iId, EThread ); if ( r == KErrNone ) { // Open the owning process instead, so that we can see which chunks are mapped // into the thread. DThread* thread = (DThread*) TempObject(); DProcess* process = threadAdaption.GetOwningProcess( *thread ); if ( process ) { const TUint parentProcessId = processAdaption.GetId( *process ); CloseTempObject(); r = OpenTempObject( parentProcessId, EProcess ); } else { CloseTempObject(); r = KErrNotFound; } } } else { r = OpenTempObject( params.iId, EProcess ); } // Handle error opening correct process if (r != KErrNone) { Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - END - parent process not found"); return r; } DProcess* process = (DProcess*) TempObject(); NKern::ThreadEnterCS(); // Iterate through each handle in the process MemSpyObjectIx* processHandles = processAdaption.GetHandles( *process ); MemSpyObjectIx_HandleLookupLock(); const TInt processHandleCount = processHandles->Count(); MemSpyObjectIx_HandleLookupUnlock(); for( TInt processHandleIndex = 0; processHandleIndex<processHandleCount && r == KErrNone && currentWriteIndex < maxCount; processHandleIndex++ ) { // Get a handle from the process container... MemSpyObjectIx_HandleLookupLock(); if (processHandleIndex >= processHandles->Count()) break; // Count may have changed in the meantime DObject* object = (*processHandles)[ processHandleIndex ]; if (object && object->Open() != KErrNone) object = NULL; MemSpyObjectIx_HandleLookupUnlock(); if ( object ) { const TObjectType objectType = processAdaption.GetObjectType( *object ); if ( objectType == EChunk ) { DChunk* chunk = (DChunk*) object; TAny* handle = (TAny*) chunk; r = Kern::ThreadRawWrite( &ClientThread(), params.iHandles + currentWriteIndex, &handle, sizeof(TAny*) ); if ( r == KErrNone ) { ++currentWriteIndex; } } object->Close(NULL); } } // If we were asked for process-related chunks, also check the chunk container // for entries which we don't have handles to, but do refer to our process // Need a listing of all chunks in the system. Let client filter duplicates. DObjectCon* container = Kern::Containers()[ EChunk ]; container->Wait(); // const TInt count = container->Count(); for( TInt i=0; i<count && r == KErrNone && currentWriteIndex < maxCount; i++ ) { DChunk* chunk= (DChunk*) (*container)[ i ]; // const TBool isRelated = DoesChunkRelateToProcess( *chunk, TempObjectAsProcess() ); if ( isRelated ) { r = Kern::ThreadRawWrite( &ClientThread(), params.iHandles + currentWriteIndex, &chunk, sizeof(TAny*) ); if ( r == KErrNone ) { ++currentWriteIndex; } } } // container->Signal(); NKern::ThreadLeaveCS(); CloseTempObject(); } else { // Need a listing of all chunks in the system. Let client filter duplicates. DObjectCon* container = Kern::Containers()[ EChunk ]; NKern::ThreadEnterCS(); container->Wait(); // const TInt count = container->Count(); for( TInt i=0; i<count && r == KErrNone && currentWriteIndex < maxCount; i++ ) { DChunk* chunk= (DChunk*) (*container)[ i ]; // r = Kern::ThreadRawWrite( &ClientThread(), params.iHandles + currentWriteIndex, &chunk, sizeof(TAny*) ); if (r == KErrNone) { ++currentWriteIndex; } } // container->Signal(); NKern::ThreadLeaveCS(); } if ( r == KErrBadDescriptor ) { MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor ); } else { const TInt finalWrite = Kern::ThreadRawWrite( &ClientThread(), params.iCountPtr, ¤tWriteIndex, sizeof(TInt) ); if ( r == KErrNone ) { r = finalWrite; } } TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - END - number of handles written to client: %d, ret: %d", currentWriteIndex, r)); return r; }