sl@0: // Copyright (c) 2007-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: // Trace API sl@0: // sl@0: sl@0: #include sl@0: #include "traceutils.h" sl@0: sl@0: sl@0: //Add the Doxygen macro so that Doxygen doesn't need to know about the SYMBIAN_TRACE_EXECUTABLE_IS_INCLUDED define. sl@0: //This allows doxygen to pick up the comments for the enabled implementation of the trace API. sl@0: #ifdef __DOXYGEN__ sl@0: #define SYMBIAN_TRACE_EXECUTABLE_IS_INCLUDED sl@0: #endif //__DOXYGEN__ sl@0: sl@0: sl@0: namespace UTF sl@0: { sl@0: sl@0: sl@0: /** sl@0: * This method currently returns 0 until a fix is provided sl@0: * for: sl@0: * DPDEF110067 [Trace STP][ADP37] No Way for The Secondary Category to Be Set To Default sl@0: * DEF119891 [TraceSTP] 1.4.1 Default the ModuleUid sl@0: * This will in the future return the UID3 of the executable. sl@0: * sl@0: * @return Returns 0. sl@0: */ sl@0: EXPORT_C TModuleUid TTraceContext::DefaultModuleUid() sl@0: { sl@0: return 0; sl@0: } sl@0: sl@0: sl@0: /** sl@0: * Check if thread identification will be added by default. sl@0: */ sl@0: EXPORT_C THasThreadIdentification TTraceContext::HasThreadIdentification() const sl@0: { sl@0: return iHasThreadIdentification; sl@0: }; sl@0: sl@0: /** sl@0: * Check if PC will be added by default. sl@0: */ sl@0: EXPORT_C THasProgramCounter TTraceContext::HasProgramCounter() const sl@0: { sl@0: return iHasProgramCounter; sl@0: }; sl@0: sl@0: sl@0: /** sl@0: * Get the current classification sl@0: * sl@0: * @return The current classification of the trace point context. sl@0: */ sl@0: EXPORT_C TClassification TTraceContext::Classification() const sl@0: { sl@0: return iClassification; sl@0: }; sl@0: sl@0: /** sl@0: * Get the current module Uid sl@0: * sl@0: * @return The currently set module Uid sl@0: */ sl@0: EXPORT_C TModuleUid TTraceContext::ModuleUid() const sl@0: { sl@0: return iModuleUid; sl@0: } sl@0: sl@0: sl@0: //--------------------- UTrace compiled in ------------------------ sl@0: #ifdef SYMBIAN_TRACE_EXECUTABLE_IS_INCLUDED sl@0: sl@0: sl@0: sl@0: // --------- printf ------------ sl@0: sl@0: /** sl@0: Prints a string by outputting a trace packet with the format id KFormatPrintf. sl@0: sl@0: If the specified string is too long to fit into a single trace packet sl@0: a multipart trace is generated. sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aDes The string. This can be of variable length. sl@0: sl@0: @return The trace packet was/was not output. sl@0: sl@0: @See BTrace::TMultipart sl@0: */ sl@0: EXPORT_C TBool Print(const TTraceContext& aContext, const TDesC8& aDes) sl@0: { sl@0: if(WouldBeTracedNow(aContext)) sl@0: { sl@0: GET_PC(pc); sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), pc, KFormatPrintf, aDes.Ptr(), aDes.Size()); sl@0: } sl@0: return EFalse; sl@0: }; sl@0: sl@0: sl@0: #ifdef __KERNEL_MODE__ sl@0: sl@0: /** sl@0: Prints a formatted string in kernel mode only by outputting a trace packet with the format id KFormatPrintf. sl@0: sl@0: The function uses Kern::AppendFormat() to do the formatting. sl@0: sl@0: Although it is safe to call this function from an ISR, it polls the output sl@0: serial port and may take a long time to complete, invalidating any sl@0: real-time guarantee. sl@0: sl@0: If called from an ISR, it is possible for output text to be intermingled sl@0: with other output text if one set of output interrupts or preempts another. sl@0: sl@0: Some of the formatting options may not work inside an ISR. sl@0: sl@0: Be careful not to use a string that is too long to fit onto the stack. sl@0: If the specified string is too long to fit into a single trace packet sl@0: a multipart trace is generated. sl@0: sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aFmt The format string. This must not be longer than 256 characters. sl@0: @param ... A variable number of arguments to be converted to text as dictated sl@0: by the format string. sl@0: sl@0: @return The trace packet was/was not output. sl@0: sl@0: @pre Calling thread can either be in a critical section or not. sl@0: @pre Interrupts must be enabled. sl@0: @pre Kernel must be unlocked sl@0: @pre Call in any context. sl@0: @pre Suitable for use in a device driver sl@0: sl@0: @see Kern::AppendFormat() sl@0: @See BTrace::TMultipart sl@0: sl@0: Note: Until the Utrace packet format is changed this call will not add the sl@0: FormatId to the trace packet for kernel side traces. sl@0: */ sl@0: EXPORT_C TBool Printf(const TTraceContext& aContext, const char* aFmt, ...) sl@0: { sl@0: if(WouldBeTracedNow(aContext)) sl@0: { sl@0: GET_PC(pc); sl@0: TBuf8 buf; sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: Kern::AppendFormat(buf,aFmt,list); sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), pc, KFormatPrintf, buf.Ptr(), buf.Size()); sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: /** sl@0: Prints a formatted string by outputting a trace packet with the format id KFormatPrintf. sl@0: sl@0: If the specified string is too long to fit into a single trace packet sl@0: a multipart trace is generated. sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aFmt The format string. This must not be longer than 256 characters. sl@0: @param ... A variable number of arguments to be converted to text as dictated sl@0: by the format string. sl@0: sl@0: @return The trace packet was/was not output. sl@0: sl@0: @See BTrace::TMultipart sl@0: */ sl@0: EXPORT_C TBool Printf(const TTraceContext& aContext, TRefByValue aFmt,...) sl@0: { sl@0: if(WouldBeTracedNow(aContext)) sl@0: { sl@0: GET_PC(pc); sl@0: TBuf8 buf; sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: TDesC8 fmt = aFmt; sl@0: Kern::AppendFormat(buf,(char*)fmt.Ptr(),list); sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), pc, KFormatPrintf, buf.Ptr(), buf.Size()); sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: #endif // __KERNEL_MODE__ sl@0: #ifndef __KERNEL_MODE__ sl@0: sl@0: /** sl@0: Prints a formatted string by outputting a trace packet with the format id KFormatPrintf. sl@0: sl@0: sl@0: If the specified string is too long to fit into a single trace packet sl@0: a multipart trace is generated. sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aFmt The format string. This must not be longer than 256 characters. sl@0: @param ... A variable number of arguments to be converted to text as dictated sl@0: by the format string. sl@0: sl@0: @return The trace packet was/was not output. sl@0: sl@0: @See BTrace::TMultipart sl@0: */ sl@0: EXPORT_C TBool Printf(const TTraceContext& aContext, const char* aFmt, ...) sl@0: { sl@0: if(WouldBeTracedNow(aContext)) sl@0: { sl@0: GET_PC(pc); sl@0: TTruncateOverflow8 overflow; sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: TPtrC8 fmt((const TText8*)aFmt); sl@0: TBuf8 buf; sl@0: // coverity[uninit_use_in_call] sl@0: buf.AppendFormatList(fmt,list,&overflow); sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), pc, KFormatPrintf, buf.Ptr(), buf.Size()); sl@0: } sl@0: return EFalse; sl@0: }; sl@0: sl@0: /** sl@0: Prints a formatted string by outputting a trace packet with the format id KFormatPrintf. sl@0: sl@0: If the specified string is too long to fit into a single trace packet sl@0: a multipart trace is generated. sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aFmt The format string. This must not be longer than 256 characters. sl@0: @param ... A variable number of arguments to be converted to text as dictated sl@0: by the format string. sl@0: sl@0: @return The trace packet was/was not output. sl@0: sl@0: @See BTrace::TMultipart sl@0: */ sl@0: EXPORT_C TBool Printf(const TTraceContext& aContext, TRefByValue aFmt,...) sl@0: { sl@0: if(WouldBeTracedNow(aContext)) sl@0: { sl@0: GET_PC(pc); sl@0: TTruncateOverflow8 overflow; sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: TBuf8 buf; sl@0: // coverity[uninit_use_in_call] sl@0: buf.AppendFormatList(aFmt,list,&overflow); sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), pc, KFormatPrintf, buf.Ptr(), buf.Size()); sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: /** sl@0: Prints a formatted string by outputting a trace packet with the format id sl@0: KFormatPrintfUnicode for unicode strings and KFormatPrintf for other strings. sl@0: sl@0: If the specified string is too long to fit into a single trace packet sl@0: a multipart trace is generated. sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aFmt The format string. This must not be longer than 256 characters. sl@0: @param ... A variable number of arguments to be converted to text as dictated sl@0: by the format string. sl@0: sl@0: @return The trace packet was/was not output. sl@0: sl@0: @See BTrace::TMultipart sl@0: */ sl@0: EXPORT_C TBool Printf(const TTraceContext& aContext, TRefByValue aFmt,...) sl@0: { sl@0: if(WouldBeTracedNow(aContext)) sl@0: { sl@0: GET_PC(pc); sl@0: TTruncateOverflow16 overflow; sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: TBuf buf; sl@0: // coverity[uninit_use_in_call] sl@0: buf.AppendFormatList(aFmt,list,&overflow); sl@0: #ifndef _UNICODE sl@0: TPtr8 p(buf.Collapse()); sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), myPc, KFormatPrintf, buf.PtrZ(), p.Size()); sl@0: #else //_UNICODE sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), pc, KFormatPrintfUnicode, buf.PtrZ(), buf.Size()); sl@0: #endif //_UNICODE sl@0: } sl@0: return EFalse; sl@0: }; sl@0: sl@0: sl@0: /** sl@0: Prints a string by outputting a trace packet with the format id KFormatPrintf sl@0: sl@0: If the specified string is too long to fit into a single trace packet sl@0: a multipart trace is generated. sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aDes The string. This must not be longer than 256 characters. sl@0: sl@0: @return The trace packet was/was not output. sl@0: sl@0: @See BTrace::TMultipart sl@0: */ sl@0: EXPORT_C TBool Print(const TTraceContext& aContext, const TDesC16& aDes) sl@0: { sl@0: if(WouldBeTracedNow(aContext)) sl@0: { sl@0: GET_PC(pc); sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), pc, KFormatPrintfUnicode, aDes.Ptr(), aDes.Size()); sl@0: } sl@0: return EFalse; sl@0: } sl@0: #endif // __KERNEL_MODE__ sl@0: sl@0: sl@0: // --------- trace ------------ sl@0: sl@0: /** sl@0: Outputs a trace packet containing no payload data. sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aFormatId A format identifier as specified by @see TFormatId sl@0: sl@0: @return The trace packet was/was not output. sl@0: */ sl@0: EXPORT_C TBool Trace(const TTraceContext& aContext, TFormatId aFormatId) sl@0: { sl@0: GET_PC(pc); sl@0: return UTRACE_SECONDARY_0(aContext.Classification(),aContext.ModuleUid(),aContext.HasThreadIdentification(),aContext.HasProgramCounter(), pc, aFormatId); sl@0: } sl@0: sl@0: /** sl@0: Outputs a trace packet containing 4 bytes of data. sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aFormatId A format identifier as specified by @see TFormatId sl@0: @param aData 4 bytes of data sl@0: sl@0: @return The trace packet was/was not output. sl@0: */ sl@0: EXPORT_C TBool Trace(const TTraceContext& aContext, TFormatId aFormatId, TUint32 aData) sl@0: { sl@0: GET_PC(pc); sl@0: return UTRACE_SECONDARY_1(aContext.Classification(),aContext.ModuleUid(),aContext.HasThreadIdentification(),aContext.HasProgramCounter(),pc,aFormatId,aData); sl@0: } sl@0: sl@0: /** sl@0: Outputs a trace packet containing 8 bytes of data. sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aFormatId A format identifier as specified by @see TFormatId sl@0: @param aData1 4 bytes of data sl@0: @param aData2 4 bytes of data sl@0: sl@0: @return The trace packet was/was not output. sl@0: */ sl@0: EXPORT_C TBool Trace(const TTraceContext& aContext, TFormatId aFormatId, TUint32 aData1, TUint32 aData2) sl@0: { sl@0: GET_PC(pc); sl@0: TUint32 packet[2]; sl@0: packet[0] = aData1; sl@0: packet[1] = aData2; sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), pc, aFormatId, &packet, 8); sl@0: } sl@0: sl@0: /** sl@0: Outputs a trace packet containing variable length data. sl@0: sl@0: If the specified data is too big to fit into a single sl@0: trace packet a multipart trace is generated. sl@0: sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aFormatId A format identifier as specified by @see TFormatId sl@0: @param aData Address of additional data to add to trace packet. sl@0: Must be word aligned, i.e. a multiple of 4. sl@0: @param aSize Number of bytes of additional data. sl@0: sl@0: @return The trace packet was/was not output. sl@0: sl@0: @See BTrace::TMultipart sl@0: */ sl@0: EXPORT_C TBool Trace(const TTraceContext& aContext, TFormatId aFormatId, const TAny* aData, TInt aSize) sl@0: { sl@0: if(WouldBeTracedNow(aContext)) sl@0: { sl@0: GET_PC(pc); sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), pc, aFormatId, aData, aSize); sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: /** sl@0: Outputs a trace packet containing 4 bytes of data. sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aFormatId A format identifier as specified by @see TFormatId sl@0: @param aData 4 bytes of data sl@0: sl@0: @return The trace packet was/was not output. sl@0: */ sl@0: EXPORT_C TBool Trace(const TTraceContext& aContext, const TFormatId aFormatId, const TUint16 aData) sl@0: { sl@0: GET_PC(pc); sl@0: return UTRACE_SECONDARY_1(aContext.Classification(),aContext.ModuleUid(),aContext.HasThreadIdentification(),aContext.HasProgramCounter(),pc,aFormatId,aData); sl@0: } sl@0: sl@0: /** sl@0: Outputs a trace packet containing 4 bytes of data. sl@0: sl@0: @param aContext The trace packet context. @see TTraceContext sl@0: @param aFormatId A format identifier as specified by @see TFormatId sl@0: @param aData 4 bytes of data sl@0: sl@0: @return The trace packet was/was not output. sl@0: */ sl@0: EXPORT_C TBool Trace(const TTraceContext& aContext, const TFormatId aFormatId, const TUint8 aData) sl@0: { sl@0: GET_PC(pc); sl@0: return UTRACE_SECONDARY_1(aContext.Classification(),aContext.ModuleUid(),aContext.HasThreadIdentification(),aContext.HasProgramCounter(),pc,aFormatId,aData); sl@0: } sl@0: sl@0: #ifndef __KERNEL_MODE__ sl@0: /** sl@0: Outputs a trace packet containing variable length data. sl@0: sl@0: If the specified data is too big to fit into a single sl@0: trace record a multipart trace is generated. sl@0: sl@0: @param aContext Attributes of the trace point. sl@0: @param aFormatId A format identifier as specified by @see TFormatId sl@0: @param aData Additional data to add to trace packet. sl@0: Must be word aligned, i.e. a multiple of 4. sl@0: sl@0: @return The trace packet was/was not logged. sl@0: sl@0: @See BTrace::TMultipart sl@0: */ sl@0: EXPORT_C TBool Trace(const TTraceContext& aContext, const TFormatId aFormatId, const TDesC16& aData) sl@0: { sl@0: if(WouldBeTracedNow(aContext)) sl@0: { sl@0: GET_PC(pc); sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), pc, aFormatId, aData.Ptr(), aData.Size()); sl@0: } sl@0: return EFalse; sl@0: } sl@0: #endif //__KERNEL_MODE__ sl@0: sl@0: /** sl@0: Outputs a trace packet containing variable length data. sl@0: sl@0: If the specified data is too big to fit into a single sl@0: trace record a multipart trace is generated. sl@0: sl@0: @param aContext Attributes of the trace point. sl@0: @param aFormatId A format identifier as specified by @see TFormatId sl@0: @param aData Additional data to add to trace packet. sl@0: Must be word aligned, i.e. a multiple of 4. sl@0: sl@0: @return The trace packet was/was not logged. sl@0: sl@0: @See BTrace::TMultipart sl@0: */ sl@0: EXPORT_C TBool Trace(const TTraceContext& aContext, const TFormatId aFormatId, const TDesC8& aData) sl@0: { sl@0: if(WouldBeTracedNow(aContext)) sl@0: { sl@0: GET_PC(pc); sl@0: return UTRACE_SECONDARY_ANY(aContext.Classification(), aContext.ModuleUid(), aContext.HasThreadIdentification(), aContext.HasProgramCounter(), pc, aFormatId, aData.Ptr(), aData.Size()); sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: sl@0: sl@0: /** sl@0: * Check whether a trace packet would be traced or not. sl@0: * sl@0: * @param aContext The context of the trace packet(s) to be checked. sl@0: * @return Returns whether the trace packet would be traced or not. sl@0: * Note: The value should never be stored since the filters can be changed without warning. sl@0: */ sl@0: EXPORT_C TBool WouldBeTracedNow(const TTraceContext& aContext) sl@0: { sl@0: return BTrace::CheckFilter2(aContext.Classification(), aContext.ModuleUid()); sl@0: }; sl@0: sl@0: //--------------------- UTrace compiled out ------------------------ sl@0: sl@0: #else //SYMBIAN_TRACE_EXECUTABLE_IS_INCLUDED sl@0: sl@0: //--------printf sl@0: EXPORT_C TBool Printf(const TTraceContext&, const char*, ...) { return EFalse; } sl@0: EXPORT_C TBool Print(const TTraceContext&, const TDesC8&) { return EFalse; } sl@0: EXPORT_C TBool Printf(const TTraceContext&, TRefByValue ,...) { return EFalse; } sl@0: #ifndef __KERNEL_MODE__ sl@0: EXPORT_C TBool Printf(const TTraceContext&, TRefByValue,...) { return EFalse; } sl@0: EXPORT_C TBool Print(const TTraceContext&, const TDesC16&) { return EFalse; } sl@0: #endif //__KERNEL_MODE__ sl@0: sl@0: //--------trace sl@0: EXPORT_C TBool Trace(const TTraceContext&, TFormatId) { return EFalse; } sl@0: EXPORT_C TBool Trace(const TTraceContext&, TFormatId, TUint32) { return EFalse; } sl@0: EXPORT_C TBool Trace(const TTraceContext&, TFormatId, TUint32, TUint32) { return EFalse; } sl@0: EXPORT_C TBool Trace(const TTraceContext&, TFormatId, const TAny*, TInt) { return EFalse; } sl@0: sl@0: EXPORT_C TBool Trace(const TTraceContext&, const TFormatId, const TUint8) { return EFalse; } sl@0: EXPORT_C TBool Trace(const TTraceContext&, const TFormatId, const TUint16) { return EFalse; } sl@0: EXPORT_C TBool Trace(const TTraceContext&, const TFormatId, const TDesC8&) { return EFalse; } sl@0: #ifndef __KERNEL_MODE__ sl@0: EXPORT_C TBool Trace(const TTraceContext&, const TFormatId, const TDesC16&) { return EFalse; } sl@0: #endif sl@0: EXPORT_C TBool WouldBeTracedNow(const TTraceContext&) { return EFalse; } sl@0: sl@0: sl@0: #endif //SYMBIAN_TRACE_EXECUTABLE_IS_INCLUDED sl@0: sl@0: }//namespace UTF sl@0: sl@0: