171 |
166 |
172 |
167 |
173 |
168 |
174 |
169 |
175 |
170 |
176 TInt DMemSpyDriverLogChanHeapBase::OpenUserHeap( DThread& aClientThread, TUint aExpectedHeapVTable, RMemSpyDriverRHeapUser& aHeap, DChunk*& aUserHeapChunk, TDes8* aClientHeapChunkName ) |
|
177 { |
|
178 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap() - START - aHeap.ChunkIsInitialised: %d, aExpectedHeapVTable: 0x%08x, aClientThread: %O", aHeap.ChunkIsInitialised(), aExpectedHeapVTable, &aClientThread )); |
|
179 __ASSERT_ALWAYS( aHeap.ChunkIsInitialised() == EFalse, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapChunkAlreadyCloned ) ); |
|
180 |
|
181 TInt r = KErrNotFound; |
|
182 aUserHeapChunk = NULL; |
|
183 |
|
184 NKern::ThreadEnterCS(); |
|
185 |
|
186 const TBool allocatorIsReallyRHeap = GetUserHeapHandle( aClientThread, aHeap, aExpectedHeapVTable ); |
|
187 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - allocatorIsReallyRHeap: %d", allocatorIsReallyRHeap)); |
|
188 |
|
189 if ( allocatorIsReallyRHeap ) |
|
190 { |
|
191 RAllocator* allocator = OSAdaption().DThread().GetAllocator( aClientThread ); |
|
192 |
|
193 // Open client's heap chunk in order to read it's dimensions |
|
194 const TInt clientsHeapChunkHandle = aHeap.iChunkHandle; |
|
195 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clientsHeapChunkHandle: 0x%08x, allocatorAddress: 0x%08x", clientsHeapChunkHandle, allocator)); |
|
196 |
|
197 NKern::LockSystem(); |
|
198 DChunk* clientsHeapChunk = (DChunk*) Kern::ObjectFromHandle( &aClientThread, clientsHeapChunkHandle, EChunk ); |
|
199 NKern::UnlockSystem(); |
|
200 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clientsHeapChunk: 0x%08x", clientsHeapChunk )); |
|
201 |
|
202 if ( clientsHeapChunk != NULL ) |
|
203 { |
|
204 // Get the chunk name (if the caller asked for it) |
|
205 if ( aClientHeapChunkName ) |
|
206 { |
|
207 clientsHeapChunk->FullName( *aClientHeapChunkName ); |
|
208 } |
|
209 |
|
210 // Update the heap chunk pointer. We do this now because this |
|
211 // should point to the _real_ user-side heap chunk, rather than |
|
212 // the copy of the chunk that we are about to make. |
|
213 aUserHeapChunk = clientsHeapChunk; |
|
214 |
|
215 // Set up ourselves to duplicate their heap chunk |
|
216 const TInt clientsHeapChunkSize = OSAdaption().DChunk().GetSize( *clientsHeapChunk ); |
|
217 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - chunkBase: 0x%08x, size: %8d, maxLen: %8d, chunk: %O", clientsHeapChunk->iBase, clientsHeapChunkSize, clientsHeapChunk->iMaxSize, clientsHeapChunk )); |
|
218 |
|
219 // Make a new chunk that is the same size, owned by this thread. |
|
220 TChunkCreateInfo info; |
|
221 info.iType = TChunkCreateInfo::ESharedKernelSingle; |
|
222 info.iMaxSize = clientsHeapChunkSize; |
|
223 info.iOwnsMemory = ETrue; // Use memory from system's free pool |
|
224 info.iDestroyedDfc = NULL; |
|
225 #ifdef __EPOC32__ |
|
226 info.iMapAttr = (TInt)EMapAttrFullyBlocking; // Full caching |
|
227 #endif |
|
228 |
|
229 // Holds a copy of the client's heap chunk |
|
230 DChunk* heapCopyChunk; |
|
231 TLinAddr heapCopyChunkAddress; |
|
232 TUint32 heapCopyChunkMappingAttributes; |
|
233 r = Kern::ChunkCreate( info, heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes ); |
|
234 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - creating chunk returned: %d", r)); |
|
235 // |
|
236 if ( r == KErrNone ) |
|
237 { |
|
238 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - copy chunk base: 0x%08x, heapCopyChunkAddress: 0x%08x", heapCopyChunk->iBase, heapCopyChunkAddress)); |
|
239 |
|
240 // Commit memory for entire buffer |
|
241 TUint32 physicalAddress = 0; |
|
242 r = Kern::ChunkCommitContiguous( heapCopyChunk, 0, clientsHeapChunkSize, physicalAddress ); |
|
243 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - commiting chunk returned: %d", r)); |
|
244 |
|
245 if ( r != KErrNone) |
|
246 { |
|
247 // On error, thow away the chunk we have created |
|
248 Kern::ChunkClose( heapCopyChunk ); |
|
249 heapCopyChunk = NULL; |
|
250 } |
|
251 else |
|
252 { |
|
253 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - heapCopyChunk->iSize: 0x%08x, heapCopyChunk->iBase: 0x%08x, heapCopyChunkAddress: 0x%08x, physicalAddress: 0x%08x", heapCopyChunk->iSize, heapCopyChunk->iBase, heapCopyChunkAddress, physicalAddress)); |
|
254 |
|
255 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - trying to copy %d bytes from clients allocator address of 0x%08x", clientsHeapChunkSize, allocator )); |
|
256 r = Kern::ThreadRawRead( &aClientThread, allocator, (TAny*) heapCopyChunkAddress, clientsHeapChunkSize ); |
|
257 |
|
258 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - read result of clients heap data is: %d", r)); |
|
259 if ( r == KErrNone ) |
|
260 { |
|
261 // Transfer ownership of the copy heap chunk to the heap object. This also calculates the delta |
|
262 // beween the heap addresses in the client's address space and the kernel address space. |
|
263 aHeap.AssociateWithKernelChunk( heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes ); |
|
264 } |
|
265 } |
|
266 } |
|
267 } |
|
268 else |
|
269 { |
|
270 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - could not open clients heap chunk by its handle" ) ); |
|
271 r = KErrNotFound; |
|
272 } |
|
273 } |
|
274 else |
|
275 { |
|
276 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clients heap is not an RHeap (allocated vTable mismatch)" ) ); |
|
277 r = KErrNotSupported; |
|
278 } |
|
279 |
|
280 NKern::ThreadLeaveCS(); |
|
281 |
|
282 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - r: %d", r )); |
|
283 return r; |
|
284 } |
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 |
|
295 |
|
296 |
|
297 |
|
298 |
|
299 |
|
300 |
|
301 |
|
302 |
|
303 |
|
304 |
|
305 |
|
306 |
|
307 |
|
308 TBool DMemSpyDriverLogChanHeapBase::GetUserHeapHandle( DThread& aThread, RMemSpyDriverRHeapUser& aHeap, TUint aExpectedVTable ) |
|
309 { |
|
310 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle() - START - aExpectedVTable: 0x%08x", aExpectedVTable) ); |
|
311 |
|
312 RAllocator* allocator = OSAdaption().DThread().GetAllocator( aThread ); |
|
313 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - allocator addr: 0x%08x", allocator) ); |
|
314 TUint* pAllocator = (TUint*) allocator; |
|
315 // |
|
316 TBool vTableOkay = EFalse; |
|
317 TUint vtable = 0; |
|
318 |
|
319 // Read a bit more data than is available for debugging purposes |
|
320 TBuf8<32> vtableBuf; |
|
321 TInt r = Kern::ThreadRawRead( &aThread, pAllocator, (TUint8*) vtableBuf.Ptr(), vtableBuf.MaxLength() ); |
|
322 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - read result of vtable data from requested thread is: %d", r)); |
|
323 if ( r == KErrNone ) |
|
324 { |
|
325 TRACE( MemSpyDriverUtils::DataDump("allocator vtable data - %lS", vtableBuf.Ptr(), vtableBuf.MaxLength(), vtableBuf.MaxLength() ) ); |
|
326 vtableBuf.SetLength( vtableBuf.MaxLength() ); |
|
327 |
|
328 vtable = vtableBuf[0] + |
|
329 (vtableBuf[1] << 8) + |
|
330 (vtableBuf[2] << 16) + |
|
331 (vtableBuf[3] << 24); |
|
332 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - client VTable is: 0x%08x", vtable) ); |
|
333 |
|
334 // Check the v-table to work out if it really is an RHeap |
|
335 vTableOkay = ( vtable == aExpectedVTable ); |
|
336 if ( vTableOkay ) |
|
337 { |
|
338 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - vtables okay") ); |
|
339 r = aHeap.ReadFromUserAllocator( aThread ); |
|
340 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - after userget, error: %d", r)); |
|
341 |
|
342 } |
|
343 else |
|
344 { |
|
345 TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - vtables dont match! - aExpectedVTable: 0x%08x, allocator addr: 0x%08x, client VTable is: 0x%08x, aThread: %O", aExpectedVTable, allocator, vtable, &aThread ) ); |
|
346 } |
|
347 } |
|
348 else |
|
349 { |
|
350 TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - error during client vTable reading: %d, aThread: %O", r, &aThread ) ); |
|
351 } |
|
352 // |
|
353 return (vTableOkay && (r == KErrNone)); |
|
354 } |
|
355 |
|
356 |
|
357 |
|
358 |
|
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 void DMemSpyDriverLogChanHeapBase::PrintHeapInfo( const TMemSpyHeapInfo& aInfo ) |
171 void DMemSpyDriverLogChanHeapBase::PrintHeapInfo( const TMemSpyHeapInfo& aInfo ) |
370 { |
172 { |
371 const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap(); |
173 const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap(); |
372 const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData(); |
174 //const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData(); |
373 const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics(); |
175 const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics(); |
374 const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); |
176 const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); |
375 |
177 |
376 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
178 /* |
|
179 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
377 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator -" ) ); |
180 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator -" ) ); |
378 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
181 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
379 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iAccessCount: %d", rHeapObjectData.iAccessCount ) ); |
182 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iAccessCount: %d", rHeapObjectData.iAccessCount ) ); |
380 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iHandleCount: %d", rHeapObjectData.iHandleCount ) ); |
183 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iHandleCount: %d", rHeapObjectData.iHandleCount ) ); |
381 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iHandles: 0x%08x", rHeapObjectData.iHandles ) ); |
184 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iHandles: 0x%08x", rHeapObjectData.iHandles ) ); |
406 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iFailed: %d", rHeapObjectData.iFailed ) ); |
209 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iFailed: %d", rHeapObjectData.iFailed ) ); |
407 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iFailAllocCount: %d", rHeapObjectData.iFailAllocCount ) ); |
210 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iFailAllocCount: %d", rHeapObjectData.iFailAllocCount ) ); |
408 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iRand: %d", rHeapObjectData.iRand ) ); |
211 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iRand: %d", rHeapObjectData.iRand ) ); |
409 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iTestData: 0x%08x", rHeapObjectData.iTestData ) ); |
212 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iTestData: 0x%08x", rHeapObjectData.iTestData ) ); |
410 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) ); |
213 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) ); |
411 |
214 */ |
412 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
215 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
413 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Free) -" ) ); |
216 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Free) -" ) ); |
414 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
217 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
415 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell count: %d", rHeapStats.StatsFree().TypeCount() ) ); |
218 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell count: %d", rHeapStats.StatsFree().TypeCount() ) ); |
416 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell size: %d", rHeapStats.StatsFree().TypeSize() ) ); |
219 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell size: %d", rHeapStats.StatsFree().TypeSize() ) ); |
429 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest: 0x%08x", rHeapStats.StatsAllocated().LargestCellAddress() ) ); |
232 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest: 0x%08x", rHeapStats.StatsAllocated().LargestCellAddress() ) ); |
430 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest size: %d", rHeapStats.StatsAllocated().LargestCellSize() ) ); |
233 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell largest size: %d", rHeapStats.StatsAllocated().LargestCellSize() ) ); |
431 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) ); |
234 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) ); |
432 |
235 |
433 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
236 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
434 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Common) -" ) ); |
|
435 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
|
436 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - total cell count: %d", rHeapStats.StatsCommon().TotalCellCount() ) ); |
|
437 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) ); |
|
438 |
|
439 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
|
440 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Misc. Info -" ) ); |
237 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Misc. Info -" ) ); |
441 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
238 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); |
442 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk size: %d", rHeapMetaData.ChunkSize() ) ); |
239 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk size: %d", rHeapMetaData.ChunkSize() ) ); |
443 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk handle: 0x%08x", rHeapMetaData.ChunkHandle() ) ); |
240 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk handle: 0x%08x", rHeapMetaData.ChunkHandle() ) ); |
444 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk base address: 0x%08x", rHeapMetaData.ChunkBaseAddress() ) ); |
241 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk base address: 0x%08x", rHeapMetaData.ChunkBaseAddress() ) ); |
445 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - debug allocator: %d", rHeapMetaData.IsDebugAllocator() ) ); |
242 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - debug allocator: %d", rHeapMetaData.IsDebugAllocator() ) ); |
446 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - shared heap: %d", rHeapMetaData.IsSharedHeap() ) ); |
243 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - shared heap: %d", rHeapMetaData.IsSharedHeap() ) ); |
447 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - user thread: %d", rHeapMetaData.IsUserThread() ) ); |
244 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - user thread: %d", rHeapMetaData.IsUserThread() ) ); |
448 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (free): %d", rHeapMetaData.HeaderSizeFree() ) ); |
245 //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (free): %d", rHeapMetaData.HeaderSizeFree() ) ); |
449 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (alloc): %d", rHeapMetaData.HeaderSizeAllocated() ) ); |
246 //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (alloc): %d", rHeapMetaData.HeaderSizeAllocated() ) ); |
450 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap vTable: 0x%08x", rHeapMetaData.VTable() ) ); |
247 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap vTable: 0x%08x", rHeapMetaData.VTable() ) ); |
451 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap object size: %d", rHeapMetaData.ClassSize() ) ); |
248 //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap object size: %d", rHeapMetaData.ClassSize() ) ); |
|
249 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap size: %d", rHeapMetaData.iHeapSize ) ); |
|
250 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - allocator address: 0x%08x", rHeapMetaData.iAllocatorAddress ) ); |
452 } |
251 } |
453 |
252 |
454 |
253 TInt DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel(RMemSpyDriverRHeapBase& aHeap, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer ) |
455 |
|
456 |
|
457 |
|
458 |
|
459 |
|
460 |
|
461 |
|
462 |
|
463 TBool DMemSpyDriverLogChanHeapBase::IsDebugKernel() |
|
464 { |
|
465 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - START") ); |
|
466 |
|
467 TInt r = KErrNone; |
|
468 TBool debugKernel = EFalse; |
|
469 |
|
470 NKern::ThreadEnterCS(); |
|
471 RMemSpyDriverRHeapKernelInPlace rHeap; |
|
472 r = OpenKernelHeap( rHeap ); |
|
473 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - open kernel heap returned: %d", r) ); |
|
474 |
|
475 if ( r == KErrNone ) |
|
476 { |
|
477 debugKernel = IsDebugKernel( rHeap ); |
|
478 |
|
479 // Tidy up |
|
480 rHeap.DisassociateWithKernelChunk(); |
|
481 } |
|
482 |
|
483 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - debugKernel: %d", debugKernel) ); |
|
484 NKern::ThreadLeaveCS(); |
|
485 |
|
486 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - END - ret: %d", r) ); |
|
487 return debugKernel; |
|
488 } |
|
489 |
|
490 |
|
491 TBool DMemSpyDriverLogChanHeapBase::IsDebugKernel( RMemSpyDriverRHeapKernelInPlace& aHeap ) |
|
492 { |
|
493 TBool debugKernel = EFalse; |
|
494 // |
|
495 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - START") ); |
|
496 NKern::ThreadEnterCS(); |
|
497 |
|
498 // Request that the kernel fail the next heap allocation |
|
499 aHeap.FailNext(); |
|
500 |
|
501 // Allocate a new cell, and in debug builds of the kernel, this should be NULL |
|
502 TInt* cell = new TInt(); |
|
503 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - cell: 0x%08x", cell) ); |
|
504 debugKernel = ( cell == NULL ); |
|
505 delete cell; |
|
506 |
|
507 NKern::ThreadLeaveCS(); |
|
508 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - END - debugKernel: %d", debugKernel) ); |
|
509 // |
|
510 return debugKernel; |
|
511 } |
|
512 |
|
513 |
|
514 TInt DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel( RMemSpyDriverRHeapBase& aHeap, TBool aIsDebugAllocator, const TDesC8& aChunkName, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer ) |
|
515 { |
254 { |
516 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel() - START - aTransferBuffer: 0x%08x", aTransferBuffer ) ); |
255 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel() - START - aTransferBuffer: 0x%08x", aTransferBuffer ) ); |
517 |
256 |
518 TInt r = KErrNone; |
257 TInt r = KErrNone; |
519 NKern::ThreadEnterCS(); |
258 NKern::ThreadEnterCS(); |
520 |
259 |
521 // This object holds all of the info we will accumulate for the client. |
260 // This object holds all of the info we will accumulate for the client. |
522 TMemSpyHeapInfo masterHeapInfo; |
261 TMemSpyHeapInfo masterHeapInfo; |
523 masterHeapInfo.SetType( TMemSpyHeapInfo::ETypeRHeap ); |
262 masterHeapInfo.SetType(aHeap.GetTypeFromHelper()); |
524 masterHeapInfo.SetTid( 2 ); |
263 masterHeapInfo.SetTid( 2 ); |
525 masterHeapInfo.SetPid( 1 ); |
264 masterHeapInfo.SetPid( 1 ); |
526 |
265 |
527 // This is the RHeap-specific object that contains all RHeap info |
266 // This is the RHeap-specific object that contains all RHeap info |
528 TMemSpyHeapInfoRHeap& rHeapInfo = masterHeapInfo.AsRHeap(); |
267 TMemSpyHeapInfoRHeap& rHeapInfo = masterHeapInfo.AsRHeap(); |
529 |
268 |
530 // This is the object data for the RHeap instance |
|
531 TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData(); |
|
532 aHeap.CopyObjectDataTo( rHeapObjectData ); |
|
533 |
269 |
534 // When walking the kernel heap we must keep track of the free cells |
270 // When walking the kernel heap we must keep track of the free cells |
535 // without allocating any more memory (on the kernel heap...) |
271 // without allocating any more memory (on the kernel heap...) |
536 // |
272 // |
537 // Therefore, we start a stream immediately, which is actually already |
273 // Therefore, we start a stream immediately, which is actually already |
594 TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics(); |
330 TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics(); |
595 heapWalker.CopyStatsTo( rHeapStats ); |
331 heapWalker.CopyStatsTo( rHeapStats ); |
596 |
332 |
597 // Get remaining meta data that isn't stored elsewhere |
333 // Get remaining meta data that isn't stored elsewhere |
598 TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); |
334 TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); |
599 rHeapMetaData.SetChunkName( aChunkName ); |
335 TFullName chunkName; |
|
336 aHeap.Chunk().FullName(chunkName); |
|
337 rHeapMetaData.SetChunkName(chunkName); |
600 rHeapMetaData.SetChunkSize( (TUint) aHeap.Chunk().Size() ); |
338 rHeapMetaData.SetChunkSize( (TUint) aHeap.Chunk().Size() ); |
601 rHeapMetaData.SetChunkHandle( &aHeap.Chunk() ); |
339 rHeapMetaData.SetChunkHandle( &aHeap.Chunk() ); |
602 rHeapMetaData.SetChunkBaseAddress( aHeap.Chunk().Base() ); |
340 rHeapMetaData.SetChunkBaseAddress( OSAdaption().DChunk().GetBase(aHeap.Chunk()) ); |
603 rHeapMetaData.SetDebugAllocator( aIsDebugAllocator ); |
341 rHeapMetaData.SetDebugAllocator(aHeap.Helper()->AllocatorIsUdeb()); |
604 rHeapMetaData.SetHeaderSizeFree( RMemSpyDriverRHeapBase::FreeCellHeaderSize() ); |
|
605 rHeapMetaData.SetHeaderSizeAllocated( RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( aIsDebugAllocator ) ); |
|
606 rHeapMetaData.SetUserThread( EFalse ); |
342 rHeapMetaData.SetUserThread( EFalse ); |
607 rHeapMetaData.SetSharedHeap( ETrue ); |
343 rHeapMetaData.SetSharedHeap( ETrue ); |
608 |
344 rHeapMetaData.iHeapSize = aHeap.Helper()->CommittedSize(); |
609 // Get any heap-specific info |
345 rHeapMetaData.iAllocatorAddress = (TAny*)aHeap.Helper()->AllocatorAddress(); |
610 aHeap.GetHeapSpecificInfo( masterHeapInfo ); |
346 rHeapMetaData.iMinHeapSize = aHeap.Helper()->MinCommittedSize(); |
|
347 rHeapMetaData.iMaxHeapSize = aHeap.Helper()->MaxCommittedSize(); |
611 |
348 |
612 PrintHeapInfo( masterHeapInfo ); |
349 PrintHeapInfo( masterHeapInfo ); |
613 |
350 |
614 // Update info ready for writing back to the user-side |
351 // Update info ready for writing back to the user-side |
615 if ( r == KErrNone ) |
352 if ( r == KErrNone ) |
667 { |
399 { |
668 Kern::Printf( "DMemSpyDriverLogChanHeapBase::HandleHeapCell - Kernel Free Cell stack stream IS FULL!" ); |
400 Kern::Printf( "DMemSpyDriverLogChanHeapBase::HandleHeapCell - Kernel Free Cell stack stream IS FULL!" ); |
669 error = KErrAbort; |
401 error = KErrAbort; |
670 } |
402 } |
671 } |
403 } |
672 else |
404 } |
673 { |
|
674 NKern::ThreadEnterCS(); |
|
675 error = iFreeCells.Append( cell ); |
|
676 NKern::ThreadLeaveCS(); |
|
677 // |
|
678 if ( error == KErrNone ) |
|
679 { |
|
680 ++iFreeCellCount; |
|
681 } |
|
682 } |
|
683 } |
|
684 // |
405 // |
685 return ( error == KErrNone ); |
406 return ( error == KErrNone ); |
686 } |
407 } |
687 |
408 |
688 |
409 |
689 void DMemSpyDriverLogChanHeapBase::HandleHeapWalkInit() |
410 void DMemSpyDriverLogChanHeapBase::HandleHeapWalkInit() |
690 { |
411 { |
691 // Can't delete the free cell list here as we might be walking the kernel heap |
412 iFreeCellCount = 0; |
692 iFreeCellCount = 0; |
413 } |
693 } |
|
694 |
|
695 |
|
696 |
|
697 |
|
698 |
|
699 |
|
700 TInt DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() |
|
701 { |
|
702 // Transfer free cells immediately from xfer stream |
|
703 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - START - iHeapStream: 0x%08x", iHeapStream )); |
|
704 __ASSERT_ALWAYS( !iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotClosed ) ); |
|
705 // |
|
706 TInt r = KErrNoMemory; |
|
707 // |
|
708 NKern::ThreadEnterCS(); |
|
709 // |
|
710 iHeapStream = new RMemSpyMemStreamWriter(); |
|
711 if ( iHeapStream ) |
|
712 { |
|
713 const TInt requiredMemory = CalculateFreeCellBufferSize(); |
|
714 r = OpenXferStream( *iHeapStream, requiredMemory ); |
|
715 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - requested %d bytes for free cell list, r: %d", requiredMemory, r )); |
|
716 |
|
717 if ( r == KErrNone ) |
|
718 { |
|
719 const TInt count = iFreeCells.Count(); |
|
720 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - free cell count: %d", count )); |
|
721 // |
|
722 iHeapStream->WriteInt32( count ); |
|
723 for( TInt i=0; i<count; i++ ) |
|
724 { |
|
725 const TMemSpyDriverFreeCell& cell = iFreeCells[ i ]; |
|
726 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - storing entry: %d", i )); |
|
727 // |
|
728 iHeapStream->WriteInt32( cell.iType ); |
|
729 iHeapStream->WriteUint32( reinterpret_cast<TUint32>( cell.iAddress ) ); |
|
730 iHeapStream->WriteInt32( cell.iLength ); |
|
731 } |
|
732 |
|
733 // Finished with the array now |
|
734 iFreeCells.Reset(); |
|
735 |
|
736 // We return the amount of client-side memory that needs to be allocated to hold the buffer |
|
737 r = requiredMemory; |
|
738 } |
|
739 } |
|
740 // |
|
741 NKern::ThreadLeaveCS(); |
|
742 |
|
743 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - END - r: %d", r)); |
|
744 return r; |
|
745 } |
|
746 |
|
747 |
|
748 TInt DMemSpyDriverLogChanHeapBase::FetchFreeCells( TDes8* aBufferSink ) |
|
749 { |
|
750 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::FetchFreeCells() - START - iHeapStream: 0x%08x", iHeapStream )); |
|
751 __ASSERT_ALWAYS( iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotOpen ) ); |
|
752 |
|
753 TInt r = KErrNone; |
|
754 |
|
755 // Write buffer to client |
|
756 NKern::ThreadEnterCS(); |
|
757 r = iHeapStream->WriteAndClose( aBufferSink ); |
|
758 |
|
759 // Tidy up |
|
760 ReleaseFreeCells(); |
|
761 |
|
762 NKern::ThreadLeaveCS(); |
|
763 // |
|
764 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::FetchFreeCells() - END - r: %d", r)); |
|
765 return r; |
|
766 } |
|
767 |
|
768 |
|
769 |
|
770 TInt DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() const |
|
771 { |
|
772 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() - START" )); |
|
773 |
|
774 const TInt count = iFreeCells.Count(); |
|
775 const TInt entrySize = sizeof( TInt32 ) + sizeof( TInt32 ) + sizeof( TUint32 ); |
|
776 const TInt r = ( count * entrySize ) + sizeof( TInt ); // Extra TInt to hold count |
|
777 |
|
778 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() - END - r: %d, count: %d, entrySize: %d", r, count, entrySize )); |
|
779 return r; |
|
780 } |
|
781 |
|
782 |
|
783 |
|
784 void DMemSpyDriverLogChanHeapBase::ReleaseFreeCells() |
|
785 { |
|
786 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::ReleaseFreeCells() - START - this: 0x%08x", this )); |
|
787 |
|
788 // Housekeeping |
|
789 NKern::ThreadEnterCS(); |
|
790 iFreeCells.Reset(); |
|
791 // |
|
792 iStackStream = NULL; |
|
793 // |
|
794 delete iHeapStream; |
|
795 iHeapStream = NULL; |
|
796 NKern::ThreadLeaveCS(); |
|
797 |
|
798 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::ReleaseFreeCells() - END - this: 0x%08x", this )); |
|
799 } |
|
800 |
|
801 |
|
802 |
|
803 |
|
804 |
|
805 |
|
806 |
|
807 |
|
808 |
|
809 |
|
810 |
|
811 |
|
812 |
|
813 |
|
814 |
|
815 |
|
816 |
|
817 |
|
818 |
|
819 |
|
820 |
|
821 |
|
822 |
|
823 |
|
824 |
|
825 |
|
826 |
|
827 |
|
828 |
|
829 |
414 |
830 TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RHeapK*& aHeap, DChunk*& aChunk, TDes8* aClientHeapChunkName ) |
415 TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RHeapK*& aHeap, DChunk*& aChunk, TDes8* aClientHeapChunkName ) |
831 { |
416 { |
832 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap() - START") ); |
417 TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap() - START") ); |
833 |
418 |