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