162 DProcess* process = (DProcess*) TempObject(); |
162 DProcess* process = (DProcess*) TempObject(); |
163 NKern::ThreadEnterCS(); |
163 NKern::ThreadEnterCS(); |
164 |
164 |
165 // Iterate through each handle in the process |
165 // Iterate through each handle in the process |
166 MemSpyObjectIx* processHandles = processAdaption.GetHandles( *process ); |
166 MemSpyObjectIx* processHandles = processAdaption.GetHandles( *process ); |
167 MemSpyObjectIx_Wait( processHandles ); |
167 MemSpyObjectIx_HandleLookupLock(); |
168 |
|
169 const TInt processHandleCount = processHandles->Count(); |
168 const TInt processHandleCount = processHandles->Count(); |
|
169 MemSpyObjectIx_HandleLookupUnlock(); |
|
170 |
170 for( TInt processHandleIndex = 0; processHandleIndex<processHandleCount && r == KErrNone && currentWriteIndex < maxCount; processHandleIndex++ ) |
171 for( TInt processHandleIndex = 0; processHandleIndex<processHandleCount && r == KErrNone && currentWriteIndex < maxCount; processHandleIndex++ ) |
171 { |
172 { |
172 // Get a handle from the process container... |
173 // Get a handle from the process container... |
173 NKern::LockSystem(); |
174 MemSpyObjectIx_HandleLookupLock(); |
|
175 if (processHandleIndex >= processHandles->Count()) break; // Count may have changed in the meantime |
174 DObject* object = (*processHandles)[ processHandleIndex ]; |
176 DObject* object = (*processHandles)[ processHandleIndex ]; |
175 NKern::UnlockSystem(); |
177 if (object && object->Open() != KErrNone) object = NULL; |
|
178 MemSpyObjectIx_HandleLookupUnlock(); |
176 |
179 |
177 if ( object ) |
180 if ( object ) |
178 { |
181 { |
179 const TObjectType objectType = processAdaption.GetObjectType( *object ); |
182 const TObjectType objectType = processAdaption.GetObjectType( *object ); |
180 if ( objectType == EChunk ) |
183 if ( objectType == EChunk ) |
274 |
276 |
275 DObjectCon* container = Kern::Containers()[EChunk]; |
277 DObjectCon* container = Kern::Containers()[EChunk]; |
276 NKern::ThreadEnterCS(); |
278 NKern::ThreadEnterCS(); |
277 |
279 |
278 container->Wait(); |
280 container->Wait(); |
279 NKern::LockSystem(); |
|
280 const TInt count = container->Count(); |
281 const TInt count = container->Count(); |
281 NKern::UnlockSystem(); |
|
282 |
282 |
283 DChunk* foundChunk = NULL; |
283 DChunk* foundChunk = NULL; |
284 |
284 |
285 for(TInt i=0; i<count; i++) |
285 for(TInt i=0; i<count; i++) |
286 { |
286 { |
287 NKern::LockSystem(); |
|
288 DChunk* chunk = (DChunk*) (*container)[i]; |
287 DChunk* chunk = (DChunk*) (*container)[i]; |
289 NKern::UnlockSystem(); |
|
290 // |
|
291 if ( chunk == params.iHandle ) |
288 if ( chunk == params.iHandle ) |
292 { |
289 { |
293 foundChunk = chunk; |
290 foundChunk = chunk; |
294 TRACE( PrintChunkInfo( *chunk ) ); |
291 TRACE( PrintChunkInfo( *chunk ) ); |
|
292 r = foundChunk->Open(); |
295 break; |
293 break; |
296 } |
294 } |
297 } |
295 } |
298 |
296 |
299 container->Signal(); |
297 container->Signal(); |
300 NKern::ThreadLeaveCS(); |
|
301 |
298 |
302 if ( foundChunk == NULL ) |
299 if ( foundChunk == NULL ) |
303 { |
300 { |
304 Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - END - KErrNotFound - couldnt find chunk"); |
301 Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - END - KErrNotFound - couldnt find chunk"); |
|
302 NKern::ThreadLeaveCS(); |
305 return KErrNotFound; |
303 return KErrNotFound; |
306 } |
304 } |
|
305 if (r) |
|
306 { |
|
307 Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - END - %d - Failed to open chunk", r); |
|
308 NKern::ThreadLeaveCS(); |
|
309 return r; |
|
310 } |
307 |
311 |
308 // Prepare return data |
312 // Prepare return data |
309 DMemSpyDriverOSAdaptionDChunk& chunkAdaption = OSAdaption().DChunk(); |
313 DMemSpyDriverOSAdaptionDChunk& chunkAdaption = OSAdaption().DChunk(); |
310 // |
314 // |
311 params.iBaseAddress = chunkAdaption.GetBase( *foundChunk ); |
315 params.iBaseAddress = chunkAdaption.GetBase( *foundChunk ); |
333 } |
337 } |
334 |
338 |
335 // Get type & attribs |
339 // Get type & attribs |
336 params.iType = IdentifyChunkType( *foundChunk ); |
340 params.iType = IdentifyChunkType( *foundChunk ); |
337 params.iAttributes = chunkAdaption.GetAttributes( *foundChunk ); |
341 params.iAttributes = chunkAdaption.GetAttributes( *foundChunk ); |
|
342 |
|
343 // Finished with foundChunk |
|
344 foundChunk->Close(NULL); |
|
345 NKern::ThreadLeaveCS(); |
338 |
346 |
339 // Write back to client |
347 // Write back to client |
340 r = Kern::ThreadRawWrite( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalChunkInfoParams) ); |
348 r = Kern::ThreadRawWrite( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalChunkInfoParams) ); |
341 if ( r == KErrBadDescriptor ) |
349 if ( r == KErrBadDescriptor ) |
342 { |
350 { |
468 const TInt size = chunkAdaption.GetSize( aChunk ); |
476 const TInt size = chunkAdaption.GetSize( aChunk ); |
469 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - base: 0x%08x, size: %d, process: 0x%08x (%O)", base, size, process, process ) ); |
477 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - base: 0x%08x, size: %d, process: 0x%08x (%O)", base, size, process, process ) ); |
470 |
478 |
471 if ( process && size >= 4 ) |
479 if ( process && size >= 4 ) |
472 { |
480 { |
|
481 NKern::ThreadEnterCS(); |
473 // Chunks are mapped into entire process so any thread within the process is enough... |
482 // Chunks are mapped into entire process so any thread within the process is enough... |
474 DThread* firstThread = processAdaption.GetFirstThread( *process ); |
483 DThread* firstThread = processAdaption.OpenFirstThread( *process ); |
475 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - firstThread: 0x%08x (%O)", firstThread, firstThread ) ); |
484 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - firstThread: 0x%08x (%O)", firstThread, firstThread ) ); |
476 if ( firstThread != NULL ) |
485 if ( firstThread != NULL ) |
477 { |
486 { |
478 TInt err = firstThread->Open(); |
487 TBuf8<4> allocatorVTableBuffer; |
479 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - firstThread open result: %d", err ) ); |
488 TInt err = Kern::ThreadRawRead( firstThread, base, (TUint8*) allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength() ); |
480 |
489 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - read result of vtable data from requested thread is: %d", err )); |
|
490 // |
481 if ( err == KErrNone ) |
491 if ( err == KErrNone ) |
482 { |
492 { |
483 TBuf8<4> allocatorVTableBuffer; |
493 TRACE( MemSpyDriverUtils::DataDump("possible chunk vtable data - %lS", allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength(), allocatorVTableBuffer.MaxLength() ) ); |
484 err = Kern::ThreadRawRead( firstThread, base, (TUint8*) allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength() ); |
494 allocatorVTableBuffer.SetLength( allocatorVTableBuffer.MaxLength() ); |
485 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - read result of vtable data from requested thread is: %d", err )); |
495 |
486 // |
496 const TUint32 vtable = allocatorVTableBuffer[0] + |
487 if ( err == KErrNone ) |
497 (allocatorVTableBuffer[1] << 8) + |
488 { |
498 (allocatorVTableBuffer[2] << 16) + |
489 TRACE( MemSpyDriverUtils::DataDump("possible chunk vtable data - %lS", allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength(), allocatorVTableBuffer.MaxLength() ) ); |
499 (allocatorVTableBuffer[3] << 24); |
490 allocatorVTableBuffer.SetLength( allocatorVTableBuffer.MaxLength() ); |
500 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - [possible] vTable within chunk is: 0x%08x", vtable) ); |
491 |
501 |
492 const TUint32 vtable = allocatorVTableBuffer[0] + |
502 // Check the v-table to work out if it really is an RHeap |
493 (allocatorVTableBuffer[1] << 8) + |
503 isHeap = ( vtable == rHeapVTable ); |
494 (allocatorVTableBuffer[2] << 16) + |
504 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - isHeap: %d", isHeap ) ); |
495 (allocatorVTableBuffer[3] << 24); |
|
496 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - [possible] vTable within chunk is: 0x%08x", vtable) ); |
|
497 |
|
498 // Check the v-table to work out if it really is an RHeap |
|
499 isHeap = ( vtable == rHeapVTable ); |
|
500 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - isHeap: %d", isHeap ) ); |
|
501 } |
|
502 |
|
503 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - closing first thread..." ) ); |
|
504 Kern::SafeClose( (DObject*&) firstThread, NULL ); |
|
505 } |
505 } |
506 } |
506 |
|
507 TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - closing first thread..." ) ); |
|
508 Kern::SafeClose( (DObject*&) firstThread, NULL ); |
|
509 } |
|
510 NKern::ThreadLeaveCS(); |
507 } |
511 } |
508 |
512 |
509 /* We only want RHeap's at the moment |
513 /* We only want RHeap's at the moment |
510 if ( !isHeap && aName == KMemSpyLitDollarHeap ) |
514 if ( !isHeap && aName == KMemSpyLitDollarHeap ) |
511 { |
515 { |