126 |
127 |
127 |
128 |
128 |
129 |
129 TInt DMemSpyInspectedProcess::NotifyOnChange( DThread* aThread, TRequestStatus* aRequestStatus, TMemSpyDriverProcessInspectionInfo* aInfo ) |
130 TInt DMemSpyInspectedProcess::NotifyOnChange( DThread* aThread, TRequestStatus* aRequestStatus, TMemSpyDriverProcessInspectionInfo* aInfo ) |
130 { |
131 { |
131 Kern::MutexWait( *iLock ); |
132 Lock(); |
132 |
133 |
133 TInt err = KErrInUse; |
134 TInt err = KErrInUse; |
134 const TBool notificationQueued = NotifyOnChangeQueued(); |
135 const TBool notificationQueued = NotifyOnChangeQueued(); |
135 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChange() - START - this: 0x%08x, iAmDead: %d, aRequestStatus: 0x%08x, notificationQueued: %d, iChangeObserverThread: 0x%08x (%O)", this, iAmDead, aRequestStatus, notificationQueued, iChangeObserverThread, iChangeObserverThread ) ); |
136 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChange() - START - this: 0x%08x, iAmDead: %d, aRequestStatus: 0x%08x, notificationQueued: %d, iChangeObserverThread: 0x%08x (%O)", this, iAmDead, aRequestStatus, notificationQueued, iChangeObserverThread, iChangeObserverThread ) ); |
136 // |
137 // |
156 |
157 |
157 // Notify about change |
158 // Notify about change |
158 CompleteClientsRequest( KErrNone, &cachedChange->iInfo ); |
159 CompleteClientsRequest( KErrNone, &cachedChange->iInfo ); |
159 |
160 |
160 // Discard cached entry |
161 // Discard cached entry |
161 NKern::ThreadEnterCS(); |
|
162 delete cachedChange; |
162 delete cachedChange; |
163 NKern::ThreadLeaveCS(); |
|
164 } |
163 } |
165 else if ( iAmDead ) |
164 else if ( iAmDead ) |
166 { |
165 { |
167 // We must stop listening outside of an event monitor callback... |
166 // We must stop listening outside of an event monitor callback... |
168 EventMonitor().RequestEventsCancel( *this ); |
167 EventMonitor().RequestEventsCancel( *this ); |
172 err = KErrNone; |
171 err = KErrNone; |
173 } |
172 } |
174 // |
173 // |
175 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChange() - END - this: 0x%08x, err: %d", this, err ) ); |
174 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChange() - END - this: 0x%08x, err: %d", this, err ) ); |
176 |
175 |
177 Kern::MutexSignal( *iLock ); |
176 Unlock(); |
178 return err; |
177 return err; |
179 } |
178 } |
180 |
179 |
181 |
180 |
182 TInt DMemSpyInspectedProcess::NotifyOnChangeCancel() |
181 TInt DMemSpyInspectedProcess::NotifyOnChangeCancel() |
183 { |
182 { |
184 Kern::MutexWait( *iLock ); |
183 Lock(); |
185 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeCancel() - START - this: 0x%08x, queued: %d, iChangeObserverThread: 0x%08x, iChangeObserverRS: 0x%08x", this, NotifyOnChangeQueued(), iChangeObserverThread, iChangeObserverRS ) ); |
184 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeCancel() - START - this: 0x%08x, queued: %d, iChangeObserverThread: 0x%08x, iChangeObserverRS: 0x%08x", this, NotifyOnChangeQueued(), iChangeObserverThread, iChangeObserverRS ) ); |
186 // |
185 // |
187 if ( NotifyOnChangeQueued() ) |
186 if ( NotifyOnChangeQueued() ) |
188 { |
187 { |
189 TRACE( Kern::Printf( "DMemSpyInspectedProcess::NotifyOnChangeCancel() - this: 0x%08x, iChangeObserverRS: 0x%08x, iProcessId: %d (0x%04x)", this, iChangeObserverRS, iProcessId, iProcessId ) ); |
188 TRACE( Kern::Printf( "DMemSpyInspectedProcess::NotifyOnChangeCancel() - this: 0x%08x, iChangeObserverRS: 0x%08x, iProcessId: %d (0x%04x)", this, iChangeObserverRS, iProcessId, iProcessId ) ); |
192 iChangeObserverRS = NULL; |
191 iChangeObserverRS = NULL; |
193 iChangeObserverInfo = NULL; |
192 iChangeObserverInfo = NULL; |
194 } |
193 } |
195 // |
194 // |
196 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeCancel() - END - this: 0x%08x", this ) ); |
195 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeCancel() - END - this: 0x%08x", this ) ); |
197 Kern::MutexSignal( *iLock ); |
196 Unlock(); |
198 |
197 |
199 return KErrNone; |
198 return KErrNone; |
200 } |
199 } |
201 |
200 |
202 |
201 |
203 TBool DMemSpyInspectedProcess::NotifyOnChangeQueued() const |
202 TBool DMemSpyInspectedProcess::NotifyOnChangeQueued() const |
204 { |
203 { |
205 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeQueued() - START - this: 0x%08x", this ) ); |
204 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeQueued() - START - this: 0x%08x", this ) ); |
206 // |
205 // |
207 Kern::MutexWait( *iLock ); |
206 Lock(); |
208 const TBool queued = ( iChangeObserverRS != NULL ); |
207 const TBool queued = ( iChangeObserverRS != NULL ); |
209 Kern::MutexSignal( *iLock ); |
208 Unlock(); |
210 // |
209 // |
211 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeQueued() - END - this: 0x%08x, queued: %d", this, queued ) ); |
210 TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeQueued() - END - this: 0x%08x, queued: %d", this, queued ) ); |
212 return queued; |
211 return queued; |
213 } |
212 } |
214 |
213 |
447 void DMemSpyInspectedProcess::EMHandleProcessUpdated( DProcess& aProcess ) |
446 void DMemSpyInspectedProcess::EMHandleProcessUpdated( DProcess& aProcess ) |
448 { |
447 { |
449 const TUint procId = iDevice.OSAdaption().DProcess().GetId( aProcess ); |
448 const TUint procId = iDevice.OSAdaption().DProcess().GetId( aProcess ); |
450 if ( procId == iProcessId ) |
449 if ( procId == iProcessId ) |
451 { |
450 { |
452 Kern::MutexWait( *iLock ); |
451 Lock(); |
453 |
452 |
454 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessUpdated() - START - this: 0x%08x, iProcess: 0x%08x (%O)", this, iProcess, iProcess ) ); |
453 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessUpdated() - START - this: 0x%08x, iProcess: 0x%08x (%O)", this, iProcess, iProcess ) ); |
455 NKern::ThreadEnterCS(); |
|
456 |
454 |
457 // Mark all tracked chunks as dirty whilst we work out |
455 // Mark all tracked chunks as dirty whilst we work out |
458 // what is and isn't mapped into the process |
456 // what is and isn't mapped into the process |
459 SetTrackedListUnused(); |
457 SetTrackedListUnused(); |
460 SetTrackedListUnusedStatusByType( TMemSpyTrackedChunk::ETypeChunkGlobalData, EFalse /* global data chunks are still in use */ ); |
458 SetTrackedListUnusedStatusByType( TMemSpyTrackedChunk::ETypeChunkGlobalData, EFalse /* global data chunks are still in use */ ); |
474 { |
472 { |
475 // Inform observer about new results. |
473 // Inform observer about new results. |
476 CompleteClientsRequest( KErrNone, &iInfoCurrent ); |
474 CompleteClientsRequest( KErrNone, &iInfoCurrent ); |
477 } |
475 } |
478 |
476 |
479 NKern::ThreadLeaveCS(); |
|
480 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessUpdated() - END - this: 0x%08x", this ) ); |
477 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessUpdated() - END - this: 0x%08x", this ) ); |
481 |
478 |
482 Kern::MutexSignal( *iLock ); |
479 Unlock(); |
483 } |
480 } |
484 } |
481 } |
485 |
482 |
486 |
483 |
487 void DMemSpyInspectedProcess::EMHandleProcessRemoved( DProcess& aProcess ) |
484 void DMemSpyInspectedProcess::EMHandleProcessRemoved( DProcess& aProcess ) |
489 DMemSpyDriverOSAdaptionDProcess& dProcessAdaption = iDevice.OSAdaption().DProcess(); |
486 DMemSpyDriverOSAdaptionDProcess& dProcessAdaption = iDevice.OSAdaption().DProcess(); |
490 const TUint pid = dProcessAdaption.GetId( aProcess ); |
487 const TUint pid = dProcessAdaption.GetId( aProcess ); |
491 |
488 |
492 if ( pid == iProcessId ) |
489 if ( pid == iProcessId ) |
493 { |
490 { |
494 Kern::MutexWait( *iLock ); |
491 Lock(); |
495 |
492 |
496 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessRemoved() - START - this: 0x%08x", this ) ); |
493 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessRemoved() - START - this: 0x%08x", this ) ); |
497 NKern::ThreadEnterCS(); |
|
498 |
494 |
499 // We will implement a multi phased approach to the process being removed. |
495 // We will implement a multi phased approach to the process being removed. |
500 // |
496 // |
501 // The first notification we will send will show that the process heap and |
497 // The first notification we will send will show that the process heap and |
502 // local chunks have been removed, leaving shared chunk sizes intact. |
498 // local chunks have been removed, leaving shared chunk sizes intact. |
598 } |
593 } |
599 |
594 |
600 |
595 |
601 void DMemSpyInspectedProcess::EMHandleThreadChanged( DThread& /*aThread*/ ) |
596 void DMemSpyInspectedProcess::EMHandleThreadChanged( DThread& /*aThread*/ ) |
602 { |
597 { |
603 Kern::MutexWait( *iLock ); |
598 Lock(); |
604 |
599 |
605 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleThreadChanged() - START - this: 0x%08x", this ) ); |
600 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleThreadChanged() - START - this: 0x%08x", this ) ); |
606 |
601 |
607 // This is called when a thread is added, changed, or terminated/killed. |
602 // This is called when a thread is added, changed, or terminated/killed. |
608 // We must be careful to only access the members of aThread that still |
603 // We must be careful to only access the members of aThread that still |
609 // exist as if it is being destroyed, the object may be in an intermediate |
604 // exist as if it is being destroyed, the object may be in an intermediate |
610 // state. |
605 // state. |
611 NKern::ThreadEnterCS(); |
|
612 |
606 |
613 // All we are really interested in is recalculating the stack usage |
607 // All we are really interested in is recalculating the stack usage |
614 // for the process... |
608 // for the process... |
615 iInfoCurrent.iMemoryStack = StackSize( *iProcess ); |
609 iInfoCurrent.iMemoryStack = StackSize( *iProcess ); |
616 |
610 |
617 // Always inform observer about new results. |
611 // Always inform observer about new results. |
618 CompleteClientsRequest( KErrNone, &iInfoCurrent ); |
612 CompleteClientsRequest( KErrNone, &iInfoCurrent ); |
619 |
613 |
620 NKern::ThreadLeaveCS(); |
|
621 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleThreadChanged() - END - this: 0x%08x", this ) ); |
614 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleThreadChanged() - END - this: 0x%08x", this ) ); |
622 |
615 |
623 Kern::MutexSignal( *iLock ); |
616 Unlock(); |
624 } |
617 } |
625 |
618 |
626 |
619 |
627 void DMemSpyInspectedProcess::EMHandleChunkAdd( DChunk& aChunk ) |
620 void DMemSpyInspectedProcess::EMHandleChunkAdd( DChunk& aChunk ) |
628 { |
621 { |
629 Kern::MutexWait( *iLock ); |
622 Lock(); |
630 |
623 |
631 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkAdd() - START - this: 0x%08x, aChunk: 0x%08x (%O)", this, &aChunk, &aChunk ) ); |
624 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkAdd() - START - this: 0x%08x, aChunk: 0x%08x (%O)", this, &aChunk, &aChunk ) ); |
632 NKern::ThreadEnterCS(); |
|
633 |
625 |
634 // Is this chunk related to our process somehow? |
626 // Is this chunk related to our process somehow? |
635 if ( IsChunkRelevantToOurProcess( aChunk ) ) |
627 if ( IsChunkRelevantToOurProcess( aChunk ) ) |
636 { |
628 { |
637 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkAdd() - processes match, checking chunk type..." ) ); |
629 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkAdd() - processes match, checking chunk type..." ) ); |
654 CompleteClientsRequest( KErrNone, &iInfoCurrent ); |
646 CompleteClientsRequest( KErrNone, &iInfoCurrent ); |
655 } |
647 } |
656 } |
648 } |
657 } |
649 } |
658 |
650 |
659 NKern::ThreadLeaveCS(); |
|
660 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkAdd() - END - this: 0x%08x", this ) ); |
651 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkAdd() - END - this: 0x%08x", this ) ); |
661 |
652 |
662 Kern::MutexSignal( *iLock ); |
653 Unlock(); |
663 } |
654 } |
664 |
655 |
665 |
656 |
666 void DMemSpyInspectedProcess::EMHandleChunkUpdated( DChunk& aChunk ) |
657 void DMemSpyInspectedProcess::EMHandleChunkUpdated( DChunk& aChunk ) |
667 { |
658 { |
668 Kern::MutexWait( *iLock ); |
659 Lock(); |
669 |
660 |
670 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkUpdated() - START - this: 0x%08x, aChunk: 0x%08x [S: %8d] (%O)", this, &aChunk, aChunk.Size(), &aChunk ) ); |
661 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkUpdated() - START - this: 0x%08x, aChunk: 0x%08x [S: %8d] (%O)", this, &aChunk, aChunk.Size(), &aChunk ) ); |
671 NKern::ThreadEnterCS(); |
|
672 |
662 |
673 // Is this chunk mapped into our process? |
663 // Is this chunk mapped into our process? |
674 TMemSpyTrackedChunk* trackedEntry = TrackedChunkByHandle( &aChunk ); |
664 TMemSpyTrackedChunk* trackedEntry = TrackedChunkByHandle( &aChunk ); |
675 if ( trackedEntry != NULL ) |
665 if ( trackedEntry != NULL ) |
676 { |
666 { |
710 // Inform observer about new results. |
700 // Inform observer about new results. |
711 CompleteClientsRequest( KErrNone, &iInfoCurrent ); |
701 CompleteClientsRequest( KErrNone, &iInfoCurrent ); |
712 } |
702 } |
713 } |
703 } |
714 |
704 |
715 NKern::ThreadLeaveCS(); |
|
716 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkUpdated() - END - this: 0x%08x", this ) ); |
705 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkUpdated() - END - this: 0x%08x", this ) ); |
717 |
706 |
718 Kern::MutexSignal( *iLock ); |
707 Unlock(); |
719 } |
708 } |
720 |
709 |
721 |
710 |
722 void DMemSpyInspectedProcess::EMHandleChunkDeleted( DChunk& aChunk ) |
711 void DMemSpyInspectedProcess::EMHandleChunkDeleted( DChunk& aChunk ) |
723 { |
712 { |
724 Kern::MutexWait( *iLock ); |
713 Lock(); |
725 |
714 |
726 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkDeleted() - START - this: 0x%08x", this ) ); |
715 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkDeleted() - START - this: 0x%08x", this ) ); |
727 NKern::ThreadEnterCS(); |
|
728 |
716 |
729 // Is this chunk mapped into our process? |
717 // Is this chunk mapped into our process? |
730 TMemSpyTrackedChunk* trackedEntry = TrackedChunkByHandle( &aChunk ); |
718 TMemSpyTrackedChunk* trackedEntry = TrackedChunkByHandle( &aChunk ); |
731 if ( trackedEntry != NULL ) |
719 if ( trackedEntry != NULL ) |
732 { |
720 { |
740 // Inform observer about new results. |
728 // Inform observer about new results. |
741 CompleteClientsRequest( KErrNone, &iInfoCurrent ); |
729 CompleteClientsRequest( KErrNone, &iInfoCurrent ); |
742 } |
730 } |
743 } |
731 } |
744 |
732 |
745 NKern::ThreadLeaveCS(); |
|
746 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkDeleted() - END - this: 0x%08x", this ) ); |
733 TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkDeleted() - END - this: 0x%08x", this ) ); |
747 |
734 |
748 Kern::MutexSignal( *iLock ); |
735 Unlock(); |
749 } |
736 } |
750 |
737 |
751 |
738 |
752 void DMemSpyInspectedProcess::PrintChunkInfo( DChunk& aChunk ) const |
739 void DMemSpyInspectedProcess::PrintChunkInfo( DChunk& aChunk ) const |
753 { |
740 { |
882 // Chunks are mapped into entire process so any thread within the process is enough... |
869 // Chunks are mapped into entire process so any thread within the process is enough... |
883 DThread* firstThread = iProcess->FirstThread(); |
870 DThread* firstThread = iProcess->FirstThread(); |
884 TRACE( Kern::Printf("DMemSpyInspectedProcess::IsHeapChunk() - firstThread: 0x%08x (%O)", firstThread, firstThread ) ); |
871 TRACE( Kern::Printf("DMemSpyInspectedProcess::IsHeapChunk() - firstThread: 0x%08x (%O)", firstThread, firstThread ) ); |
885 if ( firstThread != NULL ) |
872 if ( firstThread != NULL ) |
886 { |
873 { |
|
874 NKern::ThreadEnterCS(); |
887 TInt err = firstThread->Open(); |
875 TInt err = firstThread->Open(); |
888 TRACE( Kern::Printf("DMemSpyInspectedProcess::IsHeapChunk() - firstThread open result: %d", err ) ); |
876 TRACE( Kern::Printf("DMemSpyInspectedProcess::IsHeapChunk() - firstThread open result: %d", err ) ); |
889 |
877 |
890 if ( err == KErrNone ) |
878 if ( err == KErrNone ) |
891 { |
879 { |
1114 } |
1103 } |
1115 |
1104 |
1116 |
1105 |
1117 void DMemSpyInspectedProcess::FindChunks( DProcess& aProcess ) |
1106 void DMemSpyInspectedProcess::FindChunks( DProcess& aProcess ) |
1118 { |
1107 { |
|
1108 __ASSERT_CRITICAL; |
1119 TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - START - this: 0x%08x", this ) ); |
1109 TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - START - this: 0x%08x", this ) ); |
1120 |
1110 |
1121 DMemSpyDriverOSAdaptionDChunk& chunkAdaption = iDevice.OSAdaption().DChunk(); |
1111 DMemSpyDriverOSAdaptionDChunk& chunkAdaption = iDevice.OSAdaption().DChunk(); |
1122 DMemSpyDriverOSAdaptionDProcess& processAdaption = iDevice.OSAdaption().DProcess(); |
1112 DMemSpyDriverOSAdaptionDProcess& processAdaption = iDevice.OSAdaption().DProcess(); |
1123 |
1113 |
1124 // Iterate through each handle in the process |
1114 // Iterate through each handle in the process |
1125 if ( processAdaption.IsHandleIndexValid( aProcess ) ) |
1115 if ( processAdaption.IsHandleIndexValid( aProcess ) ) |
1126 { |
1116 { |
1127 MemSpyObjectIx* processHandles = processAdaption.GetHandles( aProcess ); |
1117 MemSpyObjectIx* processHandles = processAdaption.GetHandles( aProcess ); |
1128 MemSpyObjectIx_Wait( processHandles ); |
1118 |
1129 |
1119 MemSpyObjectIx_HandleLookupLock(); |
1130 const TInt count = processHandles->Count(); |
1120 const TInt count = processHandles->Count(); |
|
1121 MemSpyObjectIx_HandleLookupUnlock(); |
|
1122 |
1131 TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - got: %d handles...", count ) ); |
1123 TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - got: %d handles...", count ) ); |
1132 |
1124 |
1133 for( TInt i=0; i<count; i++ ) |
1125 for( TInt i=0; i<count; i++ ) |
1134 { |
1126 { |
1135 TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - checking handle index: %2d", i ) ); |
1127 TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - checking handle index: %2d", i ) ); |
1136 |
1128 |
1137 // Get a handle from the process container... |
1129 // Get a handle from the process container... |
1138 NKern::LockSystem(); |
1130 MemSpyObjectIx_HandleLookupLock(); |
|
1131 if (i >= processHandles->Count()) break; // Count may have changed in the meantime |
1139 DObject* object = (*processHandles)[ i ]; |
1132 DObject* object = (*processHandles)[ i ]; |
1140 NKern::UnlockSystem(); |
1133 if (object && object->Open() != KErrNone) object = NULL; |
|
1134 MemSpyObjectIx_HandleLookupUnlock(); |
1141 |
1135 |
1142 const TObjectType objectType = ( object ? chunkAdaption.GetObjectType( *object ) : EObjectTypeAny ); |
1136 const TObjectType objectType = ( object ? chunkAdaption.GetObjectType( *object ) : EObjectTypeAny ); |
1143 TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - object: 0x%08x, type: %2d (%O)", object, objectType, object ) ); |
1137 TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - object: 0x%08x, type: %2d (%O)", object, objectType, object ) ); |
1144 |
1138 |
1145 // Is it a chunk that is already mapped into our process? |
1139 // Is it a chunk that is already mapped into our process? |