66 } |
66 } |
67 |
67 |
68 |
68 |
69 EXPORT_C CMemSpyEngineActiveObjectArray* CMemSpyEngineHelperActiveObject::ActiveObjectListL( const CMemSpyThread& aThread ) |
69 EXPORT_C CMemSpyEngineActiveObjectArray* CMemSpyEngineHelperActiveObject::ActiveObjectListL( const CMemSpyThread& aThread ) |
70 { |
70 { |
71 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListL() - START"); |
71 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListLC() - START"); |
72 CMemSpyEngineActiveObjectArray* array = CMemSpyEngineActiveObjectArray::NewLC(); |
72 CMemSpyEngineActiveObjectArray* array = CMemSpyEngineActiveObjectArray::NewLC(); |
73 |
73 |
74 // Is the thread's process already suspended? If not, we need to do it now. |
74 // Is the thread's process already suspended? If not, we need to do it now. |
75 const TProcessId parentProcessId( aThread.Process().Id() ); |
75 const TProcessId parentProcessId( aThread.Process().Id() ); |
76 const TBool isSuspended = ( iEngine.SuspendedProcessId() == parentProcessId ); |
76 const TBool isSuspended = ( iEngine.SuspendedProcessId() == parentProcessId ); |
77 if ( !isSuspended ) |
77 if ( !isSuspended ) |
78 { |
78 { |
79 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListL() - suspending process"); |
79 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListLC() - suspending process"); |
80 iEngine.ProcessSuspendLC( parentProcessId ); |
80 iEngine.ProcessSuspendLC( parentProcessId ); |
81 } |
81 } |
82 |
82 |
83 // Push a cleanup item to close the heap walk in case of leaves |
83 // Push a cleanup item to close the heap walk in case of leaves |
84 CleanupStack::PushL( TCleanupItem( CleanupHeapWalk, this ) ); |
84 CleanupStack::PushL( TCleanupItem( CleanupHeapWalk, this ) ); |
85 |
85 |
86 // Get the thread info |
86 // Get the thread info |
87 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListL() - getting thread info..."); |
87 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListLC() - getting thread info..."); |
88 TMemSpyDriverThreadInfo threadInfo; |
88 TMemSpyDriverThreadInfo threadInfo; |
89 TInt err = iEngine.Driver().GetThreadInfo( aThread.Id(), threadInfo ); |
89 TInt err = iEngine.Driver().GetThreadInfo( aThread.Id(), threadInfo ); |
90 User::LeaveIfError( err ); |
90 User::LeaveIfError( err ); |
91 TAny* scheduler = threadInfo.iScheduler; |
91 TAny* scheduler = threadInfo.iScheduler; |
92 |
92 |
93 #if defined( _DEBUG ) && !defined( __WINS__ ) |
93 #if defined( _DEBUG ) && !defined( __WINS__ ) |
94 iEngine.HelperHeap().OutputCellListingUserL( aThread ); |
94 iEngine.HelperHeap().OutputCellListingUserL( aThread ); |
95 #endif |
95 #endif |
96 |
96 |
97 // Get the heap info - we need this for verification purposes |
97 // Get the heap info - we need this for verification purposes |
98 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListL() - getting heap info..."); |
98 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListLC() - getting heap info..."); |
99 err = iEngine.Driver().GetHeapInfoUser( iHeapInfo, aThread.Id() ); |
99 err = iEngine.Driver().GetHeapInfoUser( iHeapInfo, aThread.Id() ); |
100 User::LeaveIfError( err ); |
100 User::LeaveIfError( err ); |
101 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListL() - allocated cell header length is: %d", iHeapInfo.iHeapCellHeaderLengthAllocated); |
101 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListLC() - allocated cell header length is: %d", iHeapInfo.iHeapCellHeaderLengthAllocated); |
102 |
102 |
103 // Do we have a ROM-based scheduler pointer? |
103 // Do we have a ROM-based scheduler pointer? |
104 if ( scheduler != NULL && iHeapInfo.Type() != TMemSpyHeapInfo::ETypeUnknown ) |
104 if ( scheduler != NULL && iHeapInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) |
105 { |
105 { |
106 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListL() - scheduler: 0x%08x", scheduler); |
106 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListLC() - scheduler: 0x%08x", scheduler); |
107 |
107 |
108 // Let's try to get the scheduler's heap cell... |
108 // Let's try to get the scheduler's heap cell... |
109 HBufC8* data = SchedulerHeapCellDataLC( scheduler, aThread.Id() ); |
109 HBufC8* data = SchedulerHeapCellDataLC( scheduler, aThread.Id() ); |
110 |
110 |
111 // Try to extract the active object addresses |
111 // Try to extract the active object addresses |
112 ExtractActiveObjectAddressesL( scheduler, *data, *array ); |
112 ExtractActiveObjectAddressesL( scheduler, *data, *array ); |
113 CleanupStack::PopAndDestroy( data ); |
113 CleanupStack::PopAndDestroy( data ); |
114 } |
114 } |
115 |
115 |
116 // Tidy up |
116 // Tidy up |
117 CleanupStack::PopAndDestroy(this); // heap walk cleanup item |
117 CleanupStack::PopAndDestroy(); // heap walk cleanup item |
118 if ( !isSuspended ) |
118 if ( !isSuspended ) |
119 { |
119 { |
120 CleanupStack::PopAndDestroy(); // will resume the process we suspended earlier |
120 iEngine.ProcessResume(); |
121 } |
121 } |
122 // |
122 // |
123 CleanupStack::Pop( array ); |
123 CleanupStack::Pop( array ); |
124 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListL() - END"); |
124 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListLC() - END"); |
125 return array; |
125 return array; |
126 } |
126 } |
127 |
127 |
128 |
128 |
129 HBufC8* CMemSpyEngineHelperActiveObject::SchedulerHeapCellDataLC( TAny*& aCellAddress, TThreadId aThreadId ) |
129 HBufC8* CMemSpyEngineHelperActiveObject::SchedulerHeapCellDataLC( TAny*& aCellAddress, TThreadId aThreadId ) |
147 // |
147 // |
148 err = iEngine.Driver().WalkHeapGetCellInfo( aCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); |
148 err = iEngine.Driver().WalkHeapGetCellInfo( aCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); |
149 //RDebug::Printf("CMemSpyEngineHelperActiveObject::SchedulerHeapCellDataLC() - err: %d, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, cellLength, cellAllocationNumber, cellType); |
149 //RDebug::Printf("CMemSpyEngineHelperActiveObject::SchedulerHeapCellDataLC() - err: %d, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, cellLength, cellAllocationNumber, cellType); |
150 User::LeaveIfError( err ); |
150 User::LeaveIfError( err ); |
151 |
151 |
152 if (cellType & EMemSpyDriverAllocatedCellMask) |
152 if ( cellType == EMemSpyDriverGoodAllocatedCell ) |
153 { |
153 { |
154 const TInt payloadLength = cellLength; |
154 const TInt payloadLength = cellLength - iHeapInfo.AsRHeap().MetaData().HeaderSizeAllocated(); |
155 HBufC8* data = HBufC8::NewLC( payloadLength ); |
155 HBufC8* data = HBufC8::NewLC( payloadLength ); |
156 TPtr8 pData( data->Des() ); |
156 TPtr8 pData( data->Des() ); |
157 // |
157 // |
158 err = iEngine.Driver().WalkHeapReadCellData( aCellAddress, pData, payloadLength ); |
158 err = iEngine.Driver().WalkHeapReadCellData( aCellAddress, pData, payloadLength ); |
159 //RDebug::Printf("CMemSpyEngineHelperActiveObject::SchedulerHeapCellDataLC() - data fetch returned error: %d", err); |
159 //RDebug::Printf("CMemSpyEngineHelperActiveObject::SchedulerHeapCellDataLC() - data fetch returned error: %d", err); |
279 TAny* requestedCellAddress = aCellAddress; |
279 TAny* requestedCellAddress = aCellAddress; |
280 TInt err = iEngine.Driver().WalkHeapGetCellInfo( requestedCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); |
280 TInt err = iEngine.Driver().WalkHeapGetCellInfo( requestedCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); |
281 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ReadActiveObjectDataL() - err: %d, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, cellLength, cellAllocationNumber, cellType); |
281 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ReadActiveObjectDataL() - err: %d, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, cellLength, cellAllocationNumber, cellType); |
282 User::LeaveIfError( err ); |
282 User::LeaveIfError( err ); |
283 |
283 |
284 if (cellType & EMemSpyDriverAllocatedCellMask) |
284 if ( cellType == EMemSpyDriverGoodAllocatedCell ) |
285 { |
285 { |
286 const TInt payloadLength = cellLength; |
286 const TInt payloadLength = cellLength - iHeapInfo.AsRHeap().MetaData().HeaderSizeAllocated(); |
287 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ReadActiveObjectDataL() - payloadLength: %d", payloadLength); |
287 //RDebug::Printf("CMemSpyEngineHelperActiveObject::ReadActiveObjectDataL() - payloadLength: %d", payloadLength); |
288 |
288 |
289 // const TInt payloadLength = Max( 512, cellLength - iHeapInfo.iHeapCellHeaderLengthAllocated ); // Prevent negative payload lengths? |
289 // const TInt payloadLength = Max( 512, cellLength - iHeapInfo.iHeapCellHeaderLengthAllocated ); // Prevent negative payload lengths? |
290 CBufFlat* data = CBufFlat::NewL( payloadLength ); |
290 CBufFlat* data = CBufFlat::NewL( payloadLength ); |
291 CleanupStack::PushL( data ); |
291 CleanupStack::PushL( data ); |