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