diff -r 000000000000 -r c6b0df440bee dbgsrv/coredumpserver/server/src/coretargetobserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dbgsrv/coredumpserver/server/src/coretargetobserver.cpp Tue Mar 02 10:33:16 2010 +0530 @@ -0,0 +1,217 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + + + +/** + @file + @internalComponent +*/ + +#include "coretargetobserver.h" + +CTargetObserver::CTargetObserver(RSecuritySvrSession &aSecSession, CCrashHandler &aHandler) + : CActive(CActive::EPriorityStandard), + iSecSess(aSecSession), + iHandler(aHandler), + iEventInfoPtr( (TUint8*)&iCrashEventInfo, 0, sizeof(TEventInfo) ) + { + CActiveScheduler::Add(this); + } + +CTargetObserver* CTargetObserver::NewL(RSecuritySvrSession &aSecSession, CCrashHandler &aHandler, const TDesC &aProcessName) +{ + LOG_MSG("->CTargetObserver::NewL()\n"); + CTargetObserver* self = CTargetObserver::NewLC(aSecSession, aHandler, aProcessName); + CleanupStack::Pop(self); + return self; +} + +CTargetObserver* CTargetObserver::NewLC(RSecuritySvrSession &aSession, CCrashHandler &aHandler, const TDesC& aProcessName) + { + LOG_MSG("->CTargetObserver::NewLC()\n"); + CTargetObserver *self = new (ELeave) CTargetObserver(aSession, aHandler); + CleanupStack::PushL(self); + self->ConstructL(aProcessName); + return self; + } + +void CTargetObserver::ConstructL(const TDesC& aTargetName) + { + LOG_MSG("->CTargetObserver::ConstructL()\n"); + + iTargetName.CreateL(aTargetName.Length()); + iTargetName.Copy(aTargetName); + + LOG_MSG("CTargetObserver::Observe -> AttachExecutable\n"); + User::LeaveIfError(iSecSess.AttachExecutable( iTargetName, EFalse)); + } + +void CTargetObserver::SetCrashEventL(TEventType aType, TKernelEventAction aAction) +{ + LOG_MSG3("->CTargetObserver::SetCrashEventL(type=%d, action=%d)\n", aType, aAction ); + User::LeaveIfError( iSecSess.SetEventAction( iTargetName, aType, aAction )); +} + +CTargetObserver::~CTargetObserver() + { + LOG_MSG("->CTargetObserver::~CTargetObserver()\n"); + Cancel(); + iTargetName.Close(); + iThreadList.ResetAndDestroy(); + } + +void CTargetObserver::DoCancel() + { + LOG_MSG( "CTargetObserver::DoCancel -> CancelGetEvent\n"); + TInt err = iSecSess.CancelGetEvent( iTargetName ); + if(err != KErrNone) + { + LOG_MSG2( "CTargetObserver::DoCancel - iSecSess.DetachExecutable returned:%d!", err); + //panic client?? close DSS session?? + } + + LOG_MSG("CTargetObserver::DoCancel -> iSecSess.DetachExecutable\n"); + err = iSecSess.DetachExecutable( iTargetName ); + if(err != KErrNone) + { + LOG_MSG2( "CTargetObserver::DoCancel iSecSess.DetachExecutable returned:%d!\n", err); + //panic client?? close DSS session?? + } + } + +const TDesC& CTargetObserver::TargetName() const +{ + return iTargetName; +} + +TInt CTargetObserver::ThreadCount() const +{ + return iThreadList.Count(); +} + +const TDesC& CTargetObserver::Thread(TInt aIndex) const +{ + LOG_MSG2("CTargetObserver::Thread(%d)\n", aIndex); + return *iThreadList[aIndex]; +} + +void CTargetObserver::AddThreadL(const TDesC &aThreadName) +{ + LOG_MSG("->CTargetObserver::AddThreadL()\n"); + + if(HasThread(aThreadName)) + { + LOG_MSG("->CTargetObserver::AddThreadL() - already exists!\n"); + User::Leave(KErrAlreadyExists); + } + + HBufC *thread; + thread = HBufC::NewL(aThreadName.Length()); + *thread = aThreadName; + iThreadList.AppendL(thread); + LOG_MSG("CTargetObserver::AddThreadL - thread added\n"); +} + +TBool CTargetObserver::HasThread(const TDesC &aThreadName) const +{ + LOG_MSG("->CTargetObserver::HasThread()"); + TInt count = iThreadList.Count(); + for(TInt i = 0; i < count; ++i) + { + if(iThreadList[i]->Des() == aThreadName) + { + LOG_MSG("CTargetObserver::HasThreadL - thread found"); + return ETrue; + } + } + LOG_MSG("CTargetObserver::HasThreadL - thread not found"); + return EFalse; +} + +void CTargetObserver::DelThreadL(const TDesC &aThreadName) +{ + LOG_MSG("->CTargetObserver::DelThreadL()"); + + TInt count = iThreadList.Count(); + for(TInt i = 0; i < count; ++i) + { + if(iThreadList[i]->Des() == aThreadName) + { + delete iThreadList[i]; + iThreadList.Remove(i); + LOG_MSG("CTargetObserver::DelThreadL - thread deleted"); + return; + } + } + + LOG_MSG("CTargetObserver::DelThreadL - thread not found!"); + User::Leave(KErrNotFound); +} + +void CTargetObserver::ClearThreads() +{ + LOG_MSG("->CTargetObserver::ClearThreadsL()\n"); + iThreadList.ResetAndDestroy(); +} + +// RunL() completes a previously issued Observe call +void CTargetObserver::RunL() + { + LOG_MSG2("->CTargetObserver::RunL(status:%d)", iStatus.Int()); + User::LeaveIfError(iStatus.Int()); //something bad happened + + iCrashEventInfo.iEventTime.UniversalTime(); //not 100% exact time of the crash, but as soon as we are notified about it + + Observe(); + + RThread thread; + LOG_MSG2("CTargetObserver::RunL() - opening handle to crashed thread:%Lu\n", iCrashEventInfo.iThreadId); + TInt err = thread.Open(iCrashEventInfo.iThreadId); + if(err != KErrNone) + { + LOG_MSG2("CTargetObserver::RunL - unable to open thread handle! err:%d\n", err); + User::Leave(err); + } + CleanupClosePushL(thread); + + if( (iThreadList.Count() == 0) || (HasThread(thread.FullName())) ) + { + //crash event of the whole process or thread that we observe + LOG_MSG("CTargetObserver::RunL() -> HandleCrashEventL()"); + iHandler.HandleCrashEventL(iCrashEventInfo); + } + else //crash event of thread that we don't care about + { + LOG_MSG("CTargetObserver::RunL() - resuming crashed thread"); + iSecSess.ResumeThread(iCrashEventInfo.iThreadId); + } + CleanupStack::PopAndDestroy(); //thread + + } + + +// Report any leave to the client if possible. +TInt CTargetObserver::RunError(TInt aError) + { + return KErrNone; + } + +void CTargetObserver::Observe() + { + LOG_MSG("->CTargetObserver::Observe()\n"); + iSecSess.GetEvent( iTargetName, iStatus, iEventInfoPtr ); + SetActive(); //wait for crash event + }