122 |
122 |
123 |
123 |
124 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapInit( TMemSpyDriverInternalWalkHeapParamsInit* aParams ) |
124 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapInit( TMemSpyDriverInternalWalkHeapParamsInit* aParams ) |
125 { |
125 { |
126 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit() - START")); |
126 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit() - START")); |
127 __ASSERT_ALWAYS( !iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised() == EFalse, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkPending ) ); |
127 __ASSERT_ALWAYS( !iHeapWalkInitialised && iWalkHeap.Helper() == NULL, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkPending ) ); |
128 |
128 |
129 TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &iHeapWalkInitialParameters, sizeof(TMemSpyDriverInternalWalkHeapParamsInit) ); |
129 TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &iHeapWalkInitialParameters, sizeof(TMemSpyDriverInternalWalkHeapParamsInit) ); |
130 if ( r == KErrNone ) |
130 if ( r == KErrNone ) |
131 { |
131 { |
132 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, iHeapWalkInitialParameters.iDebugAllocator)); |
132 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, iHeapWalkInitialParameters.iDebugAllocator)); |
197 |
197 |
198 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell( TUint aTid, TMemSpyDriverInternalWalkHeapParamsCell* aParams ) |
198 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell( TUint aTid, TMemSpyDriverInternalWalkHeapParamsCell* aParams ) |
199 { |
199 { |
200 const TInt walkedHeapCellCount = iWalkHeapCells.Count(); |
200 const TInt walkedHeapCellCount = iWalkHeapCells.Count(); |
201 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell() - START - current cell count: %d", walkedHeapCellCount)); |
201 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell() - START - current cell count: %d", walkedHeapCellCount)); |
202 __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); |
202 __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); |
203 |
203 |
204 // Open the original thread |
204 // Open the original thread |
205 TInt r = OpenTempObject( aTid, EThread ); |
205 TInt r = OpenTempObject( aTid, EThread ); |
206 if ( r == KErrNone ) |
206 if ( r == KErrNone ) |
207 { |
207 { |
277 } |
272 } |
278 |
273 |
279 |
274 |
280 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData(TMemSpyDriverInternalWalkHeapCellDataReadParams* aParams) |
275 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData(TMemSpyDriverInternalWalkHeapCellDataReadParams* aParams) |
281 { |
276 { |
282 __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); |
277 __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); |
283 // |
278 // |
284 const TBool debugEUser = iHeapWalkInitialParameters.iDebugAllocator; |
279 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable)); |
285 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - START - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, debugEUser)); |
|
286 // |
280 // |
287 TMemSpyDriverInternalWalkHeapCellDataReadParams params; |
281 TMemSpyDriverInternalWalkHeapCellDataReadParams params; |
288 TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalWalkHeapCellDataReadParams) ); |
282 TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalWalkHeapCellDataReadParams) ); |
289 if ( r != KErrNone ) |
283 if ( r != KErrNone ) |
290 { |
284 { |
304 // Check the threads in the process are suspended |
298 // Check the threads in the process are suspended |
305 if ( SuspensionManager().IsSuspended( *thread ) ) |
299 if ( SuspensionManager().IsSuspended( *thread ) ) |
306 { |
300 { |
307 // Check we can find the cell in the cell list... |
301 // Check we can find the cell in the cell list... |
308 const TMemSpyDriverInternalWalkHeapParamsCell* cell = CellInfoForSpecificAddress( params.iCellAddress ); |
302 const TMemSpyDriverInternalWalkHeapParamsCell* cell = CellInfoForSpecificAddress( params.iCellAddress ); |
309 if ( cell == NULL ) |
|
310 { |
|
311 // Maybe the client tried the base address of the cell data. |
|
312 // try to take the header into account and retry. |
|
313 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - didnt find matching cell for address: 0x%08x... trying address minus allocatedCellHeaderSize", params.iCellAddress )); |
|
314 |
|
315 const TUint32 cellHeaderSize = (TUint32) RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( debugEUser ); |
|
316 |
|
317 TUint32 addr = (TUint32) params.iCellAddress; |
|
318 addr -= cellHeaderSize; |
|
319 params.iCellAddress = (TAny*) addr; |
|
320 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - new address: 0x%08x", params.iCellAddress )); |
|
321 |
|
322 // Last try |
|
323 cell = CellInfoForSpecificAddress( params.iCellAddress ); |
|
324 } |
|
325 |
303 |
326 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cell: 0x%08x for address: 0x%08x", cell, params.iCellAddress )); |
304 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cell: 0x%08x for address: 0x%08x", cell, params.iCellAddress )); |
327 |
305 |
328 if ( cell ) |
306 if ( cell ) |
329 { |
307 { |
330 const TBool isValidCell = iWalkHeap.CheckCell( cell->iCellAddress, cell->iLength ); |
308 const TInt cellLen = cell->iLength; |
331 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - isValidCell: %d", isValidCell )); |
309 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellLen: %d", cellLen )); |
332 |
310 |
333 if ( isValidCell ) |
311 if ( params.iReadLen <= cellLen ) |
334 { |
312 { |
335 // Check the length request is valid |
313 |
336 const TInt cellLen = cell->iLength; |
314 // Get user side descriptor length info |
337 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellLen: %d", cellLen )); |
315 TInt destLen = 0; |
338 |
316 TInt destMax = 0; |
339 if ( params.iReadLen <= cellLen ) |
317 TUint8* destPtr = NULL; |
|
318 |
|
319 r = Kern::ThreadGetDesInfo( &ClientThread(), params.iDes, destLen, destMax, destPtr, ETrue ); |
|
320 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", params.iDes, destPtr, destLen, destMax, r )); |
|
321 |
|
322 // Work out the start offset for the data... |
|
323 if ( r == KErrNone && destMax >= params.iReadLen ) |
340 { |
324 { |
341 const TInt cellHeaderSize = RMemSpyDriverRHeapBase::CellHeaderSize( *cell, debugEUser ); |
325 const TAny* srcPos = ((TUint8*) cell->iCellAddress); |
342 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellHeaderSize: %8d", cellHeaderSize )); |
326 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - srcPos: 0x%08x", srcPos )); |
343 |
327 |
344 // Get user side descriptor length info |
328 // Read some data |
345 TInt destLen = 0; |
329 r = Kern::ThreadRawRead( thread, srcPos, destPtr, params.iReadLen ); |
346 TInt destMax = 0; |
330 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - read from thread returned: %d", r)); |
347 TUint8* destPtr = NULL; |
331 |
348 |
332 if ( r == KErrNone ) |
349 r = Kern::ThreadGetDesInfo( &ClientThread(), params.iDes, destLen, destMax, destPtr, ETrue ); |
|
350 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", params.iDes, destPtr, destLen, destMax, r )); |
|
351 |
|
352 // Work out the start offset for the data... |
|
353 if ( r == KErrNone && destMax >= params.iReadLen ) |
|
354 { |
333 { |
355 const TAny* srcPos = ((TUint8*) cell->iCellAddress) + cellHeaderSize; |
334 // Client will update descriptor length in this situation. |
356 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - srcPos: 0x%08x", srcPos )); |
335 r = params.iReadLen; |
357 |
|
358 // Read some data |
|
359 r = Kern::ThreadRawRead( thread, srcPos, destPtr, params.iReadLen ); |
|
360 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - read from thread returned: %d", r)); |
|
361 |
|
362 if ( r == KErrNone ) |
|
363 { |
|
364 // Client will update descriptor length in this situation. |
|
365 r = params.iReadLen; |
|
366 } |
|
367 else if ( r == KErrBadDescriptor ) |
|
368 { |
|
369 MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor ); |
|
370 } |
|
371 } |
|
372 else |
|
373 { |
|
374 if ( r != KErrBadDescriptor ) |
|
375 { |
|
376 r = KErrArgument; |
|
377 Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - user-descriptor isnt big enough for requested data" ); |
|
378 } |
|
379 else |
|
380 { |
|
381 Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - bad or non-writable user-side descriptor" ); |
|
382 } |
|
383 } |
336 } |
384 } |
337 } |
385 else |
338 else |
386 { |
339 { |
387 r = KErrArgument; |
340 if ( r != KErrBadDescriptor ) |
388 Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - read length is bigger than cell length"); |
341 { |
|
342 r = KErrArgument; |
|
343 Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - user-descriptor isnt big enough for requested data" ); |
|
344 } |
|
345 else |
|
346 { |
|
347 Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - bad or non-writable user-side descriptor" ); |
|
348 } |
389 } |
349 } |
390 } |
350 } |
391 else |
351 else |
392 { |
352 { |
393 r = KErrArgument; |
353 r = KErrArgument; |
394 Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - invalid cell address: 0x%08x", cell); |
354 Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - read length is bigger than cell length"); |
395 } |
355 } |
396 } |
356 } |
397 else |
357 else |
398 { |
358 { |
399 r = KErrArgument; |
359 r = KErrArgument; |
411 else |
371 else |
412 { |
372 { |
413 Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - thread not found"); |
373 Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - thread not found"); |
414 } |
374 } |
415 // |
375 // |
416 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END")); |
376 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END result=%d", r)); |
417 return r; |
377 return r; |
418 } |
378 } |
419 |
379 |
420 |
380 |
421 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo( TAny* aCellAddress, TMemSpyDriverInternalWalkHeapParamsCell* aParams ) |
381 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo( TAny* aCellAddress, TMemSpyDriverInternalWalkHeapParamsCell* aParams ) |
422 { |
382 { |
423 __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); |
383 __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); |
424 // |
384 // |
425 const TBool debugEUser = iHeapWalkInitialParameters.iDebugAllocator; |
385 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable)); |
426 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - START - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, debugEUser)); |
|
427 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - cell: 0x%08x", aCellAddress)); |
386 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - cell: 0x%08x", aCellAddress)); |
428 |
387 |
429 // Open the original thread |
388 // Open the original thread |
430 TInt r = OpenTempObject( iHeapWalkInitialParameters.iTid, EThread ); |
389 TInt r = OpenTempObject( iHeapWalkInitialParameters.iTid, EThread ); |
431 if (r != KErrNone) |
390 if (r != KErrNone) |
448 // Check we can find the cell in the cell list... |
407 // Check we can find the cell in the cell list... |
449 const TMemSpyDriverInternalWalkHeapParamsCell* cell = CellInfoForSpecificAddress( aCellAddress ); |
408 const TMemSpyDriverInternalWalkHeapParamsCell* cell = CellInfoForSpecificAddress( aCellAddress ); |
450 if ( cell == NULL ) |
409 if ( cell == NULL ) |
451 { |
410 { |
452 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - no exact match for address: 0x%08x...", aCellAddress)); |
411 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - no exact match for address: 0x%08x...", aCellAddress)); |
453 |
|
454 // Maybe the client tried the base address of the cell data. |
|
455 // try to take the header into account and retry. |
|
456 const TUint32 cellHeaderSize = (TUint32) RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( debugEUser ); |
|
457 TUint32 addr = (TUint32) aCellAddress; |
|
458 addr -= cellHeaderSize; |
|
459 |
|
460 TAny* cellByRawStartingAddress = (TAny*) addr; |
|
461 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - trying to search by start of cell address: 0x%08x (cellHeaderSize: %d)", cellByRawStartingAddress, cellHeaderSize)); |
|
462 cell = CellInfoForSpecificAddress( cellByRawStartingAddress ); |
|
463 |
412 |
464 // If the cell still wasn't found, then let's look for any heap cell that contains |
413 // If the cell still wasn't found, then let's look for any heap cell that contains |
465 // the client-specified address (i.e. find the heap cell that contains the specified |
414 // the client-specified address (i.e. find the heap cell that contains the specified |
466 // address). |
415 // address). |
467 if ( cell == NULL ) |
416 if ( cell == NULL ) |
471 } |
420 } |
472 } |
421 } |
473 |
422 |
474 if ( cell ) |
423 if ( cell ) |
475 { |
424 { |
476 const TBool isValidCell = iWalkHeap.CheckCell( cell->iCellAddress, cell->iLength ); |
425 // Have enough info to write back to client now |
477 if ( isValidCell ) |
426 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - returning... cellType: %1d, addr: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", cell->iCellType, cell->iCellAddress, cell->iLength, cell->iNestingLevel, cell->iAllocNumber )); |
478 { |
427 r = Kern::ThreadRawWrite( &ClientThread(), aParams, cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) ); |
479 // Have enough info to write back to client now |
|
480 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - returning... cellType: %1d, addr: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", cell->iCellType, cell->iCellAddress, cell->iLength, cell->iNestingLevel, cell->iAllocNumber )); |
|
481 r = Kern::ThreadRawWrite( &ClientThread(), aParams, cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) ); |
|
482 } |
|
483 else |
|
484 { |
|
485 r = KErrArgument; |
|
486 Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - invalid cell address: 0x%08x", cell); |
|
487 } |
|
488 } |
428 } |
489 else |
429 else |
490 { |
430 { |
491 r = KErrArgument; |
431 r = KErrArgument; |
492 Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - no cell at user supplied address!"); |
432 Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - no cell at user supplied address!"); |
493 } |
433 } |
494 |
434 |
495 CloseTempObject(); |
435 CloseTempObject(); |
496 // |
436 // |
497 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END")); |
437 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END result=%d", r)); |
498 return r; |
438 return r; |
499 } |
439 } |
500 |
440 |
501 |
441 |
502 |
442 |