diff -r 000000000000 -r a41df078684a kerneltest/e32utils/d_exc/minkda.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32utils/d_exc/minkda.h Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,319 @@ +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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: +// e32utils\d_exc\minkda.h +// API exposed by example of kernel-side debug agent. +// +// + +#ifndef __MINKDA_H__ +#define __MINKDA_H__ + +_LIT(KKdaLddName, "MINKDA"); + +inline TVersion KKdaLddVersion() { return TVersion(1, 0, 1); } + + +#if defined(__MARM__) + +/** + ARM user registers. + Size must be multiple of 4 bytes. + */ + +class TDbgRegSet + { +public: + enum { KRegCount = 16 }; + TUint32 iRn[KRegCount]; + TUint32 iCpsr; + }; + + +/** + ARM-specific exception-related data. + Size must be multiple of 4 bytes. + */ + +class TDbgCpuExcInfo + { +public: + enum TExcCode + { + EPrefetchAbort=0, + EDataAbort=1, + EUndefinedOpcode=2, + }; +public: + TExcCode iExcCode; + /** Point to instruction which caused exception */ + TUint32 iFaultPc; + /** + Address which caused exception (System Control Coprocessor Fault + Address Register) + */ + TUint32 iFaultAddress; + /** System Control Coprocessor Fault Status Register */ + TUint32 iFaultStatus; + /** R13 supervisor mode banked register */ + TUint32 iR13Svc; + /** R14 supervisor mode banked register */ + TUint32 iR14Svc; + /** SPSR supervisor mode banked register */ + TUint32 iSpsrSvc; + }; + +#else + +class TDbgRegSet + { + }; + +class TDbgCpuExcInfo + { + }; + +#endif + + +/** + Exception or panic information block. + Size must be multiple of 4 bytes. + */ + +class TDbgCrashInfo + { +public: + enum TType { EException, EPanic }; +public: + TType iType; + /** ID of thread which crashed */ + TUint iTid; + /** CPU-specific information (exception only) */ + TDbgCpuExcInfo iCpu; + }; + + +/** + Thread information block. + Size must be multiple of 4 bytes. + */ + +class TDbgThreadInfo + { +public: + TFullName iFullName; + /** ID of owning process */ + TUint iPid; + /** user stack base address */ + TLinAddr iStackBase; + /** user stack size */ + TInt iStackSize; + TExitCategoryName iExitCategory; + TInt iExitReason; + /** User context */ + TDbgRegSet iCpu; + }; + + +/** + Code Segment Information Block + Size must be multiple of 4 bytes. + */ + +class TDbgCodeSegInfo + { +public: + TPath iPath; + TUint32 iCodeBase; + TUint32 iCodeSize; + }; + + +/** + API exposed by minimal kernel debug agent. + + This API is provided as an example only. There are no guarantees of + binary/source compatibility. + */ + +class RMinKda : public RBusLogicalChannel + { +public: + enum TControl + { + ETrap, + ECancelTrap, + EKillCrashedThread, + EGetThreadInfo, + EReadMem, + EGetCodeSegs, + EGetCodeSegInfo, + }; + // Size of following structs must be multiple of 4 bytes. + struct TCodeSnapshotParams + { + TUint iPid; + TAny** iHandles; + TInt* iCountPtr; + }; + struct TCodeInfoParams + { + TUint iPid; + TAny* iHandle; + TDes8* iPathPtr; + TUint32 iCodeBase; + TUint32 iCodeSize; + }; + struct TReadMemParams + { + TUint iTid; + TLinAddr iAddr; + TDes8* iDes; + }; + struct TDbgInfoParams + { + TBuf8 iFullName; + TUint iPid; + TLinAddr iStackBase; + TInt iStackSize; + TBuf8 iExitCategory; + TInt iExitReason; + TDbgRegSet iCpu; + }; +public: +#ifndef __KERNEL_MODE__ + inline TInt Open(); + inline void Trap(TRequestStatus& aStatus, TDbgCrashInfo& aInfo); + inline void CancelTrap(); + inline void KillCrashedThread(); + inline TInt GetThreadInfo(TUint aTid, TDbgThreadInfo& aInfo); + inline TInt ReadMem(TUint aTid, TLinAddr aSrc, TDes8& aDest); + inline TInt GetCodeSegs(TUint aPid, TAny** aHandleArray, TInt& aHandleCount); + inline TInt GetCodeSegInfo(TAny* aHandle, TUint aPid, TDbgCodeSegInfo& aInfo); +#endif + }; + + +#ifndef __KERNEL_MODE__ + +inline TInt RMinKda::Open() + { + return DoCreate(KKdaLddName, KKdaLddVersion(), KNullUnit, NULL, NULL, EOwnerThread); + } + +/** + Ask to be notified of the next panic or exception occurence. + + The crashed thread will remain suspended until KillCrashedThread() is + called allowing more information to be gathered (e.g. stack content). + + If more threads panic or take an exception, they will be suspended + too until the first one is killed. + + @param aStatus Request to complete when panic/exception occurs + @param aInfo Filled when request completes + */ + +inline void RMinKda::Trap(TRequestStatus& aStatus, TDbgCrashInfo& aInfo) + { + DoControl(ETrap, &aStatus, &aInfo); + } + +/** Cancel previous call to Trap() */ + +inline void RMinKda::CancelTrap() + { + DoControl(ECancelTrap, NULL, NULL); + } + +/** + Kill the thread which crashed causing the Trap() request to complete. + */ + +inline void RMinKda::KillCrashedThread() + { + DoControl(EKillCrashedThread, NULL, NULL); + } + + +/** + Return information about thread identified by its ID. + */ + +inline TInt RMinKda::GetThreadInfo(TUint aTid, TDbgThreadInfo& aInfo) + { + TDbgInfoParams params; + TInt r=DoControl(EGetThreadInfo, (TAny*)aTid, ¶ms); + if (r==KErrNone) + { + aInfo.iFullName.Copy(params.iFullName); + aInfo.iPid = params.iPid; + aInfo.iStackBase = params.iStackBase; + aInfo.iStackSize = params.iStackSize; + aInfo.iExitCategory.Copy(params.iExitCategory); + aInfo.iExitReason = params.iExitReason; + aInfo.iCpu = params.iCpu; + } + return r; + } + +/** + Read memory from designated thread address space. + + @param aTid Thread id + @param aSrc Source address + @param aDest Destination descriptor. Number of bytes to read is + aDes.MaxSize(). + + @return standard error code + */ + +inline TInt RMinKda::ReadMem(TUint aTid, TLinAddr aSrc, TDes8& aDest) + { + TReadMemParams params; + params.iTid = aTid; + params.iAddr = aSrc; + params.iDes = &aDest; + return DoControl(EReadMem, ¶ms, NULL); + } + +inline TInt RMinKda::GetCodeSegs(TUint aPid, TAny** aHandleArray, TInt& aHandleCount) + { + TCodeSnapshotParams params; + params.iPid = aPid; + params.iHandles = aHandleArray; + params.iCountPtr = &aHandleCount; + return DoControl(EGetCodeSegs, ¶ms, NULL); + } + +inline TInt RMinKda::GetCodeSegInfo(TAny* aHandle, TUint aPid, TDbgCodeSegInfo& aInfo) + { + TBuf8 path; + TCodeInfoParams params; + params.iPid = aPid; + params.iHandle = aHandle; + params.iPathPtr = &path; + TInt r = DoControl(EGetCodeSegInfo, ¶ms, NULL); + if (r == KErrNone) + { + aInfo.iCodeBase = params.iCodeBase; + aInfo.iCodeSize = params.iCodeSize; + aInfo.iPath.Copy(path); + } + return r; + } + +#endif + +#endif