dbgsrv/coredumpserver/server/src/coretargetobserver.cpp
changeset 0 c6b0df440bee
--- /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
+	}