1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <memspy/engine/memspyenginehelperchunk.h> |
|
19 |
|
20 // Driver includes |
|
21 #include <memspy/driver/memspydriverclient.h> |
|
22 |
|
23 // User includes |
|
24 #include <memspy/engine/memspyengine.h> |
|
25 #include <memspy/engine/memspyengineutils.h> |
|
26 #include <memspy/engine/memspyengineoutputsink.h> |
|
27 #include <memspy/engine/memspyengineoutputlist.h> |
|
28 #include <memspy/engine/memspyengineobjectthread.h> |
|
29 #include <memspy/engine/memspyengineobjectprocess.h> |
|
30 |
|
31 // Constants |
|
32 const TInt KMemSpyEngineMaxChunkCount = 768; |
|
33 |
|
34 // Literal constants |
|
35 _LIT( KMemSpyEngineChunkListOutputComma, ", " ); |
|
36 |
|
37 |
|
38 |
|
39 CMemSpyEngineHelperChunk::CMemSpyEngineHelperChunk( CMemSpyEngine& aEngine ) |
|
40 : iEngine( aEngine ) |
|
41 { |
|
42 } |
|
43 |
|
44 |
|
45 CMemSpyEngineHelperChunk::~CMemSpyEngineHelperChunk() |
|
46 { |
|
47 } |
|
48 |
|
49 |
|
50 void CMemSpyEngineHelperChunk::ConstructL() |
|
51 { |
|
52 } |
|
53 |
|
54 |
|
55 CMemSpyEngineHelperChunk* CMemSpyEngineHelperChunk::NewL( CMemSpyEngine& aEngine ) |
|
56 { |
|
57 CMemSpyEngineHelperChunk* self = new(ELeave) CMemSpyEngineHelperChunk( aEngine ); |
|
58 CleanupStack::PushL( self ); |
|
59 self->ConstructL(); |
|
60 CleanupStack::Pop( self ); |
|
61 return self; |
|
62 } |
|
63 |
|
64 |
|
65 EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForThreadL( const CMemSpyThread& aThread ) |
|
66 { |
|
67 OutputChunkInfoForThreadL( aThread.Id() ); |
|
68 } |
|
69 |
|
70 |
|
71 EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForThreadL( TThreadId aTid ) |
|
72 { |
|
73 TBuf<512> lineBuffer; |
|
74 OutputChunkInfoForThreadL( aTid, lineBuffer ); |
|
75 } |
|
76 |
|
77 |
|
78 EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForThreadL( TThreadId aTid, TDes& aLineBuffer ) |
|
79 { |
|
80 DoOutputChunkInfoForObjectL( aTid, aLineBuffer, EThread ); |
|
81 } |
|
82 |
|
83 |
|
84 EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForProcessL( const CMemSpyProcess& aProcess ) |
|
85 { |
|
86 OutputChunkInfoForProcessL( aProcess.Id() ); |
|
87 } |
|
88 |
|
89 |
|
90 EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForProcessL( TProcessId aPid ) |
|
91 { |
|
92 TBuf<512> lineBuffer; |
|
93 OutputChunkInfoForProcessL( aPid, lineBuffer ); |
|
94 } |
|
95 |
|
96 |
|
97 EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForProcessL( TProcessId aPid, TDes& aLineBuffer ) |
|
98 { |
|
99 DoOutputChunkInfoForObjectL( aPid, aLineBuffer, EProcess ); |
|
100 } |
|
101 |
|
102 |
|
103 EXPORT_C CMemSpyEngineChunkList* CMemSpyEngineHelperChunk::ListL() |
|
104 { |
|
105 RArray<TAny*> handles( 128 ); |
|
106 CleanupClosePushL( handles ); |
|
107 // |
|
108 GetChunkHandlesL( handles, EAll ); |
|
109 CMemSpyEngineChunkList* list = CreateListFromHandlesL( handles ); |
|
110 // |
|
111 CleanupStack::PopAndDestroy( &handles ); |
|
112 return list; |
|
113 } |
|
114 |
|
115 |
|
116 EXPORT_C CMemSpyEngineChunkList* CMemSpyEngineHelperChunk::ListForThreadL( TThreadId aTid ) |
|
117 { |
|
118 RArray<TAny*> handles( 128 ); |
|
119 CleanupClosePushL( handles ); |
|
120 // |
|
121 GetChunkHandlesL( handles, EThread, aTid ); |
|
122 CMemSpyEngineChunkList* list = CreateListFromHandlesL( handles ); |
|
123 // |
|
124 CleanupStack::PopAndDestroy( &handles ); |
|
125 return list; |
|
126 } |
|
127 |
|
128 |
|
129 EXPORT_C CMemSpyEngineChunkList* CMemSpyEngineHelperChunk::ListForProcessL( TProcessId aPid ) |
|
130 { |
|
131 RArray<TAny*> handles( 128 ); |
|
132 CleanupClosePushL( handles ); |
|
133 // |
|
134 GetChunkHandlesL( handles, EProcess, aPid ); |
|
135 CMemSpyEngineChunkList* list = CreateListFromHandlesL( handles ); |
|
136 // |
|
137 CleanupStack::PopAndDestroy( &handles ); |
|
138 return list; |
|
139 } |
|
140 |
|
141 |
|
142 void CMemSpyEngineHelperChunk::DoOutputChunkInfoForObjectL( TUint aId, TDes& aLineBuffer, TType aType ) |
|
143 { |
|
144 TFullName ownerName; |
|
145 // |
|
146 RArray<TAny*> handles( 128 ); |
|
147 CleanupClosePushL( handles ); |
|
148 // |
|
149 GetChunkHandlesL( handles, aType, aId ); |
|
150 CMemSpyEngineChunkList* list = CreateListFromHandlesL( handles ); |
|
151 // |
|
152 CleanupStack::PopAndDestroy( &handles ); |
|
153 CleanupStack::PushL( list ); |
|
154 // |
|
155 const TInt count = list->Count(); |
|
156 for (TInt i=0; i<count; i++) |
|
157 { |
|
158 const CMemSpyEngineChunkEntry& entry = list->At( i ); |
|
159 // |
|
160 _LIT(KLine1, "Name"); |
|
161 iEngine.Sink().OutputItemAndValueL( KLine1, entry.Name() ); |
|
162 // |
|
163 _LIT(KLine2, "Owner"); |
|
164 entry.OwnerName( ownerName ); |
|
165 iEngine.Sink().OutputItemAndValueL( KLine2, ownerName ); |
|
166 // |
|
167 _LIT(KLine3, "Address"); |
|
168 _LIT(KLine3Format, "0x%08x - 0x%08x"); |
|
169 aLineBuffer.Format(KLine3Format, entry.BaseAddress(), entry.UpperAddress() ); |
|
170 iEngine.Sink().OutputItemAndValueL( KLine3, aLineBuffer ); |
|
171 // |
|
172 _LIT(KLine4, "Size (max)"); |
|
173 _LIT(KLine4Format, "%d (%d)"); |
|
174 aLineBuffer.Format(KLine4Format, entry.Size(), entry.MaxSize()); |
|
175 iEngine.Sink().OutputItemAndValueL( KLine4, aLineBuffer ); |
|
176 // |
|
177 if ( i < count - 1 ) |
|
178 { |
|
179 iEngine.Sink().OutputBlankLineL(); |
|
180 } |
|
181 } |
|
182 // |
|
183 CleanupStack::PopAndDestroy( list ); |
|
184 } |
|
185 |
|
186 |
|
187 void CMemSpyEngineHelperChunk::GetChunkHandlesL( RArray<TAny*>& aHandles, TType aType, TUint aId ) |
|
188 { |
|
189 TAny* handles[ KMemSpyEngineMaxChunkCount ]; |
|
190 TInt count = KMemSpyEngineMaxChunkCount; |
|
191 |
|
192 TInt r = 0; |
|
193 // |
|
194 switch( aType ) |
|
195 { |
|
196 case EThread: |
|
197 r = iEngine.Driver().GetChunkHandlesForThread( aId, handles, count ); |
|
198 break; |
|
199 case EProcess: |
|
200 r = iEngine.Driver().GetChunkHandlesForProcess( aId, handles, count ); |
|
201 break; |
|
202 default: |
|
203 case EAll: |
|
204 r = iEngine.Driver().GetChunkHandles( handles, count ); |
|
205 break; |
|
206 } |
|
207 // |
|
208 if ( r == KErrNone ) |
|
209 { |
|
210 count = Min( count, KMemSpyEngineMaxChunkCount ); |
|
211 for( TInt index = 0; index < count; index++ ) |
|
212 { |
|
213 TAny* handle = handles[ index ]; |
|
214 |
|
215 if ( aHandles.Find( handle ) == KErrNotFound ) |
|
216 { |
|
217 aHandles.AppendL( handle ); |
|
218 } |
|
219 } |
|
220 } |
|
221 } |
|
222 |
|
223 |
|
224 CMemSpyEngineChunkList* CMemSpyEngineHelperChunk::CreateListFromHandlesL( const RArray<TAny*>& aHandles ) |
|
225 { |
|
226 CMemSpyEngineChunkList* list = CMemSpyEngineChunkList::NewLC( iEngine ); |
|
227 // |
|
228 TMemSpyDriverChunkInfo info; |
|
229 const TInt count = aHandles.Count(); |
|
230 // |
|
231 for( TInt i=0; i<count; i++ ) |
|
232 { |
|
233 TAny* handle = aHandles[ i ]; |
|
234 // |
|
235 const TInt error = iEngine.Driver().GetChunkInfo( handle, info ); |
|
236 if ( error == KErrNone ) |
|
237 { |
|
238 CMemSpyEngineChunkEntry* entry = CMemSpyEngineChunkEntry::NewLC( iEngine, info ); |
|
239 list->AddItemL( entry ); |
|
240 CleanupStack::Pop( entry ); |
|
241 } |
|
242 } |
|
243 // |
|
244 list->SortBySizeL(); |
|
245 // |
|
246 CleanupStack::Pop( list ); |
|
247 return list; |
|
248 } |
|
249 |
|
250 |
|
251 |
|
252 |
|
253 |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 |
|
266 |
|
267 |
|
268 |
|
269 |
|
270 |
|
271 |
|
272 |
|
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 CMemSpyEngineChunkList::CMemSpyEngineChunkList( CMemSpyEngine& aEngine ) |
|
295 : iEngine( aEngine ) |
|
296 { |
|
297 } |
|
298 |
|
299 |
|
300 EXPORT_C CMemSpyEngineChunkList::~CMemSpyEngineChunkList() |
|
301 { |
|
302 iItems.ResetAndDestroy(); |
|
303 iItems.Close(); |
|
304 } |
|
305 |
|
306 |
|
307 void CMemSpyEngineChunkList::ConstructL() |
|
308 { |
|
309 } |
|
310 |
|
311 |
|
312 CMemSpyEngineChunkList* CMemSpyEngineChunkList::NewLC( CMemSpyEngine& aEngine ) |
|
313 { |
|
314 CMemSpyEngineChunkList* self = new(ELeave) CMemSpyEngineChunkList( aEngine ); |
|
315 CleanupStack::PushL( self ); |
|
316 self->ConstructL(); |
|
317 return self; |
|
318 } |
|
319 |
|
320 |
|
321 EXPORT_C TInt CMemSpyEngineChunkList::Count() const |
|
322 { |
|
323 return iItems.Count(); |
|
324 } |
|
325 |
|
326 |
|
327 EXPORT_C CMemSpyEngineChunkEntry& CMemSpyEngineChunkList::At( TInt aIndex ) |
|
328 { |
|
329 return *iItems[ aIndex ]; |
|
330 } |
|
331 |
|
332 |
|
333 EXPORT_C const CMemSpyEngineChunkEntry& CMemSpyEngineChunkList::At( TInt aIndex ) const |
|
334 { |
|
335 return *iItems[ aIndex ]; |
|
336 } |
|
337 |
|
338 |
|
339 EXPORT_C void CMemSpyEngineChunkList::SortByNameL() |
|
340 { |
|
341 TLinearOrder< CMemSpyEngineChunkEntry > comparer( CompareByName ); |
|
342 iItems.Sort( comparer ); |
|
343 } |
|
344 |
|
345 |
|
346 EXPORT_C void CMemSpyEngineChunkList::SortBySizeL() |
|
347 { |
|
348 TLinearOrder< CMemSpyEngineChunkEntry > comparer( CompareBySize ); |
|
349 iItems.Sort( comparer ); |
|
350 } |
|
351 |
|
352 |
|
353 EXPORT_C TInt CMemSpyEngineChunkList::ItemIndex( const CMemSpyEngineChunkEntry& aEntry ) const |
|
354 { |
|
355 TInt ret = KErrNotFound; |
|
356 // |
|
357 const TInt count = Count(); |
|
358 for( TInt i=0; i<count; i++ ) |
|
359 { |
|
360 const CMemSpyEngineChunkEntry* item = iItems[ i ]; |
|
361 // |
|
362 if ( item == &aEntry ) |
|
363 { |
|
364 ret = i; |
|
365 break; |
|
366 } |
|
367 } |
|
368 // |
|
369 return ret; |
|
370 } |
|
371 |
|
372 |
|
373 EXPORT_C void CMemSpyEngineChunkList::OutputDataColumnsL( CMemSpyEngine& aEngine ) |
|
374 { |
|
375 HBufC* columns = HBufC::NewLC( 1024 ); |
|
376 TPtr pColumns( columns->Des() ); |
|
377 |
|
378 // |
|
379 _LIT(KCol1, "Name"); |
|
380 pColumns.Append( KCol1 ); |
|
381 pColumns.Append( KMemSpyEngineChunkListOutputComma ); |
|
382 |
|
383 // |
|
384 _LIT(KCol2, "Owning Process"); |
|
385 pColumns.Append( KCol2 ); |
|
386 pColumns.Append( KMemSpyEngineChunkListOutputComma ); |
|
387 |
|
388 // |
|
389 _LIT(KCol3, "Size"); |
|
390 pColumns.Append( KCol3 ); |
|
391 pColumns.Append( KMemSpyEngineChunkListOutputComma ); |
|
392 |
|
393 // |
|
394 _LIT(KCol4, "Max. Size"); |
|
395 pColumns.Append( KCol4 ); |
|
396 pColumns.Append( KMemSpyEngineChunkListOutputComma ); |
|
397 |
|
398 // |
|
399 _LIT(KCol5, "Address"); |
|
400 pColumns.Append( KCol5 ); |
|
401 |
|
402 // |
|
403 aEngine.Sink().OutputLineL( pColumns ); |
|
404 CleanupStack::PopAndDestroy( columns ); |
|
405 } |
|
406 |
|
407 |
|
408 EXPORT_C TBool CMemSpyEngineChunkList::EntryExists( TAny* aHandle ) const |
|
409 { |
|
410 TBool ret = EFalse; |
|
411 // |
|
412 const TInt count = Count(); |
|
413 for( TInt i=0; i<count && !ret; i++ ) |
|
414 { |
|
415 const CMemSpyEngineChunkEntry* item = iItems[ i ]; |
|
416 ret = ( item->Handle() == aHandle ); |
|
417 } |
|
418 // |
|
419 return ret; |
|
420 } |
|
421 |
|
422 |
|
423 void CMemSpyEngineChunkList::AddItemL( CMemSpyEngineChunkEntry* aItem ) |
|
424 { |
|
425 iItems.AppendL( aItem ); |
|
426 } |
|
427 |
|
428 |
|
429 void CMemSpyEngineChunkList::Remove( TInt aIndex ) |
|
430 { |
|
431 CMemSpyEngineChunkEntry* item = iItems[ aIndex ]; |
|
432 delete item; |
|
433 iItems.Remove( aIndex ); |
|
434 } |
|
435 |
|
436 |
|
437 void CMemSpyEngineChunkList::RemoveByHandle( TAny* aChunkHandle ) |
|
438 { |
|
439 const TInt index = ItemIndexByChunkHandle( aChunkHandle ); |
|
440 if ( index >= 0 ) |
|
441 { |
|
442 Remove( index ); |
|
443 } |
|
444 } |
|
445 |
|
446 |
|
447 TInt CMemSpyEngineChunkList::ItemIndexByProcessId( TUint aPid ) const |
|
448 { |
|
449 const TInt ret = ItemIndexByProcessId( aPid, 0 ); |
|
450 return ret; |
|
451 } |
|
452 |
|
453 |
|
454 TInt CMemSpyEngineChunkList::ItemIndexByProcessId( TUint aPid, TInt aStartIndex ) const |
|
455 { |
|
456 TInt ret = KErrNotFound; |
|
457 // |
|
458 const TInt count = Count(); |
|
459 for( TInt i=aStartIndex; i<count; i++ ) |
|
460 { |
|
461 const CMemSpyEngineChunkEntry* item = iItems[ i ]; |
|
462 // |
|
463 if ( item->OwnerId() == aPid ) |
|
464 { |
|
465 ret = i; |
|
466 break; |
|
467 } |
|
468 } |
|
469 // |
|
470 return ret; |
|
471 } |
|
472 |
|
473 |
|
474 TInt CMemSpyEngineChunkList::ItemIndexByProcessId( TUint aPid, TMemSpyDriverChunkType aType ) const |
|
475 { |
|
476 TInt ret = KErrNotFound; |
|
477 // |
|
478 const TInt count = Count(); |
|
479 for( TInt i=0; i<count; i++ ) |
|
480 { |
|
481 const CMemSpyEngineChunkEntry* item = iItems[ i ]; |
|
482 // |
|
483 if ( item->OwnerId() == aPid && item->Info().iType == aType ) |
|
484 { |
|
485 ret = i; |
|
486 break; |
|
487 } |
|
488 } |
|
489 // |
|
490 return ret; |
|
491 } |
|
492 |
|
493 |
|
494 TInt CMemSpyEngineChunkList::ItemIndexByChunkHandle( TAny* aHandle ) const |
|
495 { |
|
496 TInt ret = KErrNotFound; |
|
497 // |
|
498 const TInt count = Count(); |
|
499 for( TInt i=0; i<count; i++ ) |
|
500 { |
|
501 const CMemSpyEngineChunkEntry* item = iItems[ i ]; |
|
502 // |
|
503 if ( item->Handle() == aHandle ) |
|
504 { |
|
505 ret = i; |
|
506 break; |
|
507 } |
|
508 } |
|
509 // |
|
510 return ret; |
|
511 } |
|
512 |
|
513 |
|
514 EXPORT_C TInt CMemSpyEngineChunkList::MdcaCount() const |
|
515 { |
|
516 return Count(); |
|
517 } |
|
518 |
|
519 |
|
520 EXPORT_C TPtrC CMemSpyEngineChunkList::MdcaPoint( TInt aIndex ) const |
|
521 { |
|
522 const CMemSpyEngineChunkEntry& item = At( aIndex ); |
|
523 return TPtrC( item.Caption() ); |
|
524 } |
|
525 |
|
526 |
|
527 TInt CMemSpyEngineChunkList::CompareByName( const CMemSpyEngineChunkEntry& aLeft, const CMemSpyEngineChunkEntry& aRight ) |
|
528 { |
|
529 const TInt ret = aLeft.Name().CompareF( aRight.Name() ); |
|
530 return ret; |
|
531 } |
|
532 |
|
533 |
|
534 TInt CMemSpyEngineChunkList::CompareBySize( const CMemSpyEngineChunkEntry& aLeft, const CMemSpyEngineChunkEntry& aRight ) |
|
535 { |
|
536 TInt ret = -1; |
|
537 // |
|
538 if ( aLeft.Size() < aRight.Size() ) |
|
539 { |
|
540 ret = 1; |
|
541 } |
|
542 else if ( aLeft.Size() == aRight.Size() ) |
|
543 { |
|
544 ret = 0; |
|
545 } |
|
546 // |
|
547 return ret; |
|
548 } |
|
549 |
|
550 |
|
551 |
|
552 |
|
553 |
|
554 |
|
555 |
|
556 |
|
557 |
|
558 |
|
559 |
|
560 |
|
561 |
|
562 |
|
563 |
|
564 |
|
565 |
|
566 |
|
567 CMemSpyEngineChunkEntry::CMemSpyEngineChunkEntry( CMemSpyEngine& aEngine ) |
|
568 : iEngine( aEngine ) |
|
569 { |
|
570 } |
|
571 |
|
572 |
|
573 CMemSpyEngineChunkEntry::~CMemSpyEngineChunkEntry() |
|
574 { |
|
575 delete iCaption; |
|
576 delete iInfo; |
|
577 delete iList; |
|
578 } |
|
579 |
|
580 |
|
581 void CMemSpyEngineChunkEntry::ConstructL( const TMemSpyDriverChunkInfo& aInfo ) |
|
582 { |
|
583 // Copy info |
|
584 iInfo = new(ELeave) TMemSpyDriverChunkInfo(); |
|
585 *iInfo = aInfo; |
|
586 |
|
587 // Make caption |
|
588 TBuf<KMaxFullName+128> item; |
|
589 _LIT(KCaptionFormat, "\t%S\t\t%d"); |
|
590 item.Format( KCaptionFormat, &Name(), Size() ); |
|
591 iCaption = item.AllocL(); |
|
592 |
|
593 // Make other items |
|
594 iList = CMemSpyEngineOutputList::NewL(); |
|
595 |
|
596 _LIT( KEntry0, "Name"); |
|
597 iList->AddItemL( KEntry0, Name() ); |
|
598 |
|
599 _LIT( KEntryType, "Type" ); |
|
600 switch( aInfo.iType ) |
|
601 { |
|
602 default: |
|
603 case EMemSpyDriverChunkTypeUnknown: |
|
604 iList->AddItemL( KEntryType, _L("Unknown") ); |
|
605 break; |
|
606 case EMemSpyDriverChunkTypeHeap: |
|
607 iList->AddItemL( KEntryType, _L("Heap") ); |
|
608 break; |
|
609 case EMemSpyDriverChunkTypeHeapKernel: |
|
610 iList->AddItemL( KEntryType, _L("Kernel Heap") ); |
|
611 break; |
|
612 case EMemSpyDriverChunkTypeStackAndProcessGlobalData: |
|
613 iList->AddItemL( KEntryType, _L("Stack and Process Global Data") ); |
|
614 break; |
|
615 case EMemSpyDriverChunkTypeStackKernel: |
|
616 iList->AddItemL( KEntryType, _L("Kernel Stack") ); |
|
617 break; |
|
618 case EMemSpyDriverChunkTypeGlobalData: |
|
619 iList->AddItemL( KEntryType, _L("Global Data") ); |
|
620 break; |
|
621 case EMemSpyDriverChunkTypeCode: |
|
622 iList->AddItemL( KEntryType, _L("Code") ); |
|
623 break; |
|
624 case EMemSpyDriverChunkTypeCodeGlobal: |
|
625 iList->AddItemL( KEntryType, _L("Global Code") ); |
|
626 break; |
|
627 case EMemSpyDriverChunkTypeCodeSelfModifiable: |
|
628 iList->AddItemL( KEntryType, _L("Self Modifiable Code") ); |
|
629 break; |
|
630 case EMemSpyDriverChunkTypeLocal: |
|
631 iList->AddItemL( KEntryType, _L("Local") ); |
|
632 break; |
|
633 case EMemSpyDriverChunkTypeGlobal: |
|
634 iList->AddItemL( KEntryType, _L("Global") ); |
|
635 break; |
|
636 case EMemSpyDriverChunkTypeRamDrive: |
|
637 iList->AddItemL( KEntryType, _L("RAM Drive") ); |
|
638 break; |
|
639 } |
|
640 |
|
641 _LIT( KEntry1, "Owning Process"); |
|
642 OwnerName( item ); |
|
643 iList->AddItemL( KEntry1, item ); |
|
644 |
|
645 _LIT( KEntry2, "Address" ); |
|
646 _LIT( KEntry2Format, "0x%08x - 0x%08x" ); |
|
647 item.Format( KEntry2Format, BaseAddress(), UpperAddress() ); |
|
648 iList->AddItemL( KEntry2, item ); |
|
649 |
|
650 _LIT( KEntry3, "Size"); |
|
651 iList->AddItemL( KEntry3, Size() ); |
|
652 |
|
653 _LIT( KEntry4, "Max. Size"); |
|
654 iList->AddItemL( KEntry4, MaxSize() ); |
|
655 |
|
656 _LIT( KEntryAttributeFormat, "Attribute %d"); |
|
657 TInt attribNum = 0; |
|
658 // |
|
659 if ( aInfo.iAttributes & ENormal ) |
|
660 { |
|
661 item.Format( KEntryAttributeFormat, ++attribNum ); |
|
662 iList->AddItemL( item, _L("Normal") ); |
|
663 } |
|
664 if ( aInfo.iAttributes & EDoubleEnded ) |
|
665 { |
|
666 item.Format( KEntryAttributeFormat, ++attribNum ); |
|
667 iList->AddItemL( item, _L("Double Ended") ); |
|
668 } |
|
669 if ( aInfo.iAttributes & EDisconnected ) |
|
670 { |
|
671 item.Format( KEntryAttributeFormat, ++attribNum ); |
|
672 iList->AddItemL( item, _L("Disconnected") ); |
|
673 } |
|
674 if ( aInfo.iAttributes & EConstructed ) |
|
675 { |
|
676 item.Format( KEntryAttributeFormat, ++attribNum ); |
|
677 iList->AddItemL( item, _L("Constructed") ); |
|
678 } |
|
679 if ( aInfo.iAttributes & EMemoryNotOwned ) |
|
680 { |
|
681 item.Format( KEntryAttributeFormat, ++attribNum ); |
|
682 iList->AddItemL( item, _L("Memory Not Owned") ); |
|
683 } |
|
684 } |
|
685 |
|
686 |
|
687 CMemSpyEngineChunkEntry* CMemSpyEngineChunkEntry::NewLC( CMemSpyEngine& aEngine, const TMemSpyDriverChunkInfo& aInfo ) |
|
688 { |
|
689 CMemSpyEngineChunkEntry* self = new(ELeave) CMemSpyEngineChunkEntry( aEngine ); |
|
690 CleanupStack::PushL( self ); |
|
691 self->ConstructL( aInfo ); |
|
692 return self; |
|
693 } |
|
694 |
|
695 |
|
696 const TDesC& CMemSpyEngineChunkEntry::Name() const |
|
697 { |
|
698 return iInfo->iName; |
|
699 } |
|
700 |
|
701 |
|
702 TAny* CMemSpyEngineChunkEntry::Handle() const |
|
703 { |
|
704 return iInfo->iHandle; |
|
705 } |
|
706 |
|
707 |
|
708 TInt CMemSpyEngineChunkEntry::Size() const |
|
709 { |
|
710 return iInfo->iSize; |
|
711 } |
|
712 |
|
713 |
|
714 TInt CMemSpyEngineChunkEntry::MaxSize() const |
|
715 { |
|
716 return iInfo->iMaxSize; |
|
717 } |
|
718 |
|
719 |
|
720 TAny* CMemSpyEngineChunkEntry::BaseAddress() const |
|
721 { |
|
722 return iInfo->iBaseAddress; |
|
723 } |
|
724 |
|
725 |
|
726 TAny* CMemSpyEngineChunkEntry::UpperAddress() const |
|
727 { |
|
728 return (TAny*) (TUint(BaseAddress()) + TUint(Size())); |
|
729 } |
|
730 |
|
731 |
|
732 TUint CMemSpyEngineChunkEntry::OwnerId() const |
|
733 { |
|
734 return iInfo->iOwnerId; |
|
735 } |
|
736 |
|
737 |
|
738 EXPORT_C void CMemSpyEngineChunkEntry::OwnerName( TDes& aDes ) const |
|
739 { |
|
740 aDes.Zero(); |
|
741 AppendOwnerName( aDes ); |
|
742 } |
|
743 |
|
744 |
|
745 EXPORT_C void CMemSpyEngineChunkEntry::AppendOwnerName( TDes& aDes ) const |
|
746 { |
|
747 RProcess owner; |
|
748 const TInt error = owner.Open( (TProcessId) OwnerId() ); |
|
749 if ( error == KErrNone ) |
|
750 { |
|
751 aDes.Append( owner.FullName() ); |
|
752 owner.Close(); |
|
753 } |
|
754 } |
|
755 |
|
756 |
|
757 EXPORT_C void CMemSpyEngineChunkEntry::OutputDataL( CMemSpyEngineHelperChunk& aHelper ) const |
|
758 { |
|
759 HBufC* columns = HBufC::NewLC( 1024 ); |
|
760 TPtr pColumns( columns->Des() ); |
|
761 |
|
762 // Name |
|
763 pColumns.Copy( Name() ); |
|
764 MemSpyEngineUtils::TextAfterDoubleColon( pColumns ); |
|
765 pColumns.Append( KMemSpyEngineChunkListOutputComma ); |
|
766 |
|
767 // Owning Process |
|
768 AppendOwnerName( pColumns ); |
|
769 pColumns.Append( KMemSpyEngineChunkListOutputComma ); |
|
770 |
|
771 // Size |
|
772 pColumns.AppendNum( Size(), EDecimal ); |
|
773 pColumns.Append( KMemSpyEngineChunkListOutputComma ); |
|
774 |
|
775 // Max. Size |
|
776 pColumns.AppendNum( MaxSize(), EDecimal ); |
|
777 pColumns.Append( KMemSpyEngineChunkListOutputComma ); |
|
778 |
|
779 // Address |
|
780 _LIT( KAddressFormat, "0x%08x - 0x%08x"); |
|
781 pColumns.AppendFormat( KAddressFormat, BaseAddress(), UpperAddress() ); |
|
782 |
|
783 // |
|
784 aHelper.Engine().Sink().OutputLineL( pColumns ); |
|
785 CleanupStack::PopAndDestroy( columns ); |
|
786 } |
|
787 |
|
788 |
|
789 EXPORT_C TInt CMemSpyEngineChunkEntry::MdcaCount() const |
|
790 { |
|
791 return iList->MdcaCount(); |
|
792 } |
|
793 |
|
794 |
|
795 EXPORT_C TPtrC CMemSpyEngineChunkEntry::MdcaPoint( TInt aIndex ) const |
|
796 { |
|
797 return iList->MdcaPoint( aIndex ); |
|
798 } |
|
799 |
|
800 |
|
801 TMemSpyDriverChunkInfo& CMemSpyEngineChunkEntry::Info() |
|
802 { |
|
803 return *iInfo; |
|
804 } |
|
805 |
|
806 |
|
807 const TMemSpyDriverChunkInfo& CMemSpyEngineChunkEntry::Info() const |
|
808 { |
|
809 return *iInfo; |
|
810 } |
|
811 |
|
812 |
|