|
1 /* |
|
2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Debug helpers |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #ifndef __AI2_DEBUG_H__ |
|
20 #define __AI2_DEBUG_H__ |
|
21 |
|
22 #include <e32def.h> |
|
23 |
|
24 // Uncomment to turn on RD logging |
|
25 //#define AI_ENABLE_RD_LOGGING |
|
26 |
|
27 #ifdef __WINS__ |
|
28 // On the emulator log to debug output |
|
29 #define AI_RD_LOG_TO_DEBUG_OUTPUT |
|
30 #endif |
|
31 |
|
32 #ifndef AI_ENABLE_RD_LOGGING |
|
33 // RD logging is off |
|
34 |
|
35 // Empty definitions of logging macros when RD logging is turned off |
|
36 #define __TIME_MARK(_var) |
|
37 #define __TIME_ENDMARK(_msg, _var) |
|
38 #define __TIME(_msg, _code) _code; |
|
39 #define __TICK(_msg) |
|
40 #define __HEAP(_msg) |
|
41 #define __DBG_FORMAT(_fmt) TAiEmptyDebugFormat() |
|
42 #define __PRINT __impl_print_empty |
|
43 #define __DBG_FORMAT8(_fmt) TAiEmptyDebugFormat() |
|
44 #define __PRINT8 __impl_print_empty |
|
45 #define __PRINTS(_str) |
|
46 #define __PRINT_IF_ERROR(_stmt, _fmt) (void)_stmt; |
|
47 #define __TRAP_AND_PRINT_IF_ERROR(_stmt, _fmt) TRAP_IGNORE(_stmt); |
|
48 |
|
49 // Unnamed namespace to keep debug functions out of global namespace |
|
50 namespace { |
|
51 |
|
52 /** |
|
53 * Zero-overhead definition for an empty debug formatting string. |
|
54 * @see macro __DBG_FORMAT |
|
55 */ |
|
56 NONSHARABLE_STRUCT(TAiEmptyDebugFormat) |
|
57 { |
|
58 }; |
|
59 |
|
60 /// Zero-overhead RD log print implementation when RD logging is turned off |
|
61 inline void __impl_print_empty(const TAiEmptyDebugFormat&) { } |
|
62 |
|
63 /// Zero-overhead RD log print implementation when RD logging is turned off |
|
64 template<class T0> inline |
|
65 void __impl_print_empty(const TAiEmptyDebugFormat&,T0) { } |
|
66 |
|
67 /// Zero-overhead RD log print implementation when RD logging is turned off |
|
68 template<class T0, class T1> inline |
|
69 void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1) { } |
|
70 |
|
71 /// Zero-overhead RD log print implementation when RD logging is turned off |
|
72 template<class T0, class T1, class T2> inline |
|
73 void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2) { } |
|
74 |
|
75 /// Zero-overhead RD log print implementation when RD logging is turned off |
|
76 template<class T0, class T1, class T2, class T3> inline |
|
77 void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2,T3) { } |
|
78 |
|
79 /// Zero-overhead RD log print implementation when RD logging is turned off |
|
80 template<class T0, class T1, class T2, class T3, class T4> inline |
|
81 void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2,T3,T4) { } |
|
82 |
|
83 /// Zero-overhead RD log print implementation when RD logging is turned off |
|
84 template<class T0, class T1, class T2, class T3, class T4, class T5> inline |
|
85 void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2,T3,T4,T5) { } |
|
86 |
|
87 /// Zero-overhead RD log print implementation when RD logging is turned off |
|
88 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline |
|
89 void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2,T3,T4,T5,T6) { } |
|
90 |
|
91 /// Zero-overhead RD log print implementation when RD logging is turned off |
|
92 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7> inline |
|
93 void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2,T3,T4,T5,T6,T7) { } |
|
94 |
|
95 } // namespace |
|
96 |
|
97 #else |
|
98 // RD logging is on |
|
99 |
|
100 #include <e32std.h> |
|
101 #include <e32debug.h> |
|
102 #include <flogger.h> |
|
103 |
|
104 /** |
|
105 * Stores the current time as microsecond value. |
|
106 * |
|
107 * @param _var A name, which will be declared as a TInt, and will receive the |
|
108 * current time value. After the macro, _var remains in scope until |
|
109 * the end of its enclosing block. |
|
110 * @see __TIME_ENDMARK |
|
111 */ |
|
112 #define __TIME_MARK(_var) TTime _var;_var.UniversalTime(); |
|
113 |
|
114 /** |
|
115 * Logs the microsecond difference between current value and stored earlier |
|
116 * with __TIME_MARK macro. |
|
117 * |
|
118 * @param _msg textual message to write to the RD log file. |
|
119 * @param _var the start time, the value is set by __TIME_MARK macro. |
|
120 * @see __TIME_MARK |
|
121 */ |
|
122 #define __TIME_ENDMARK(_msg, _var) __impl_time_endmark(_L(_msg), _var); |
|
123 |
|
124 /** |
|
125 * Measures the execution time of a code statement |
|
126 * |
|
127 * @param _msg textual message to write to the RD log file. |
|
128 * @param _code code statements to be measured. |
|
129 */ |
|
130 #define __TIME(_msg, _code) {TTime _time;_time.UniversalTime();_code;__impl_time_endmark(_L(_msg),_time);}; |
|
131 |
|
132 /* |
|
133 * Prints a message and current time as ms to the RD log file. |
|
134 * |
|
135 * @param _msg textual message to write to the log file. |
|
136 */ |
|
137 #define __TICK(_msg) __impl_tick(_L(_msg)); |
|
138 |
|
139 /* |
|
140 * Prints a message and current heap memory status to the log file. |
|
141 * |
|
142 * @param _msg textual message to write to the log file. |
|
143 */ |
|
144 #define __HEAP(_msg) __impl_heap(_L(_msg)); |
|
145 |
|
146 /** |
|
147 * Defines an UNICODE RD logging format string. Used with __PRINT macro. |
|
148 * @see __PRINT |
|
149 */ |
|
150 #define __DBG_FORMAT(_fmt) _L(_fmt) |
|
151 |
|
152 #ifdef AI_RD_LOG_TO_DEBUG_OUTPUT |
|
153 /** |
|
154 * Prints a printf-style formatted message to the debug output. |
|
155 * Format string needs to be defined with the __DBG_FORMAT macro. |
|
156 */ |
|
157 #define __PRINT RDebug::Print |
|
158 #else |
|
159 /** |
|
160 * Prints a printf-style formatted message to the RD log file. |
|
161 * Format string needs to be defined with the __DBG_FORMAT macro. |
|
162 */ |
|
163 #define __PRINT __impl_print |
|
164 #endif |
|
165 |
|
166 #ifdef AI_RD_LOG_TO_DEBUG_OUTPUT |
|
167 /** |
|
168 * Defines a 8-bit RD logging format string. Used with __PRINT8 macro. |
|
169 * @see __PRINT8 |
|
170 */ |
|
171 #define __DBG_FORMAT8(_fmt) _fmt |
|
172 |
|
173 /** |
|
174 * Prints a printf-style formatted message to the debug output. |
|
175 * The format string (first parameter) needs to be a 8-bit literal |
|
176 * C string. |
|
177 */ |
|
178 #define __PRINT8 RDebug::Printf |
|
179 #else |
|
180 /** |
|
181 * Defines a 8-bit RD logging format string. Used with __PRINT8 macro. |
|
182 * @see __PRINT8 |
|
183 */ |
|
184 #define __DBG_FORMAT8(_fmt) _L8(_fmt) |
|
185 |
|
186 /** |
|
187 * Prints a printf-style formatted message to the debug output. |
|
188 * The format string (first parameter) needs to be a 8-bit literal |
|
189 * C string. |
|
190 */ |
|
191 #define __PRINT8 __impl_print8 |
|
192 #endif |
|
193 |
|
194 /** |
|
195 * Prints a string to the RD log. |
|
196 * |
|
197 * @param _msg textual message to write to the log file. |
|
198 */ |
|
199 #define __PRINTS(_msg) __impl_prints(_L(_msg)); |
|
200 |
|
201 /** |
|
202 * Prints a message to the RD log if a statement returns an error code other |
|
203 * than KErrNone. |
|
204 * |
|
205 * @param _stmt statment to check for error return code. |
|
206 * @param _fmt textual message to write to the log file. If the message string |
|
207 * contains %d directive it is replaced with the error code that |
|
208 * _stmt returned. |
|
209 */ |
|
210 #define __PRINT_IF_ERROR(_stmt, _fmt) { TInt _error = _stmt; if (_error != KErrNone) __PRINT(_L(_fmt), _error); }; |
|
211 |
|
212 /** |
|
213 * Prints a message to the RD log if a statement leaves with an error code. |
|
214 * |
|
215 * @param _stmt statment to check for leave. |
|
216 * @param _fmt textual message to write to the log file. If the message string |
|
217 * contains %d directive it is replaced with the error code that |
|
218 * _stmt leaved with. |
|
219 */ |
|
220 #define __TRAP_AND_PRINT_IF_ERROR(_stmt, _fmt) { TRAPD(_error, _stmt); if (_error != KErrNone) __PRINT(_L(_fmt), _error); }; |
|
221 |
|
222 /** |
|
223 * Directory under C:\Logs in the device filesystem where the ActiveIdle2 RD |
|
224 * log file is stored. |
|
225 */ |
|
226 #define D_LOG_DIR _L("ActiveIdle2") |
|
227 |
|
228 /** |
|
229 * Name of the ActiveIdle2 RD log file under D_LOG_DIR. |
|
230 */ |
|
231 #define D_LOG_FILE _L("debug.log") |
|
232 |
|
233 // Unnamed namespace to keep debug functions out of global namespace |
|
234 namespace { |
|
235 |
|
236 // ---------------------------------------------------------------------------- |
|
237 // |
|
238 // Performance logging operation, give results in microseconds 10^-6 |
|
239 // The metricts are based on the measurment current value of microseconds in |
|
240 // the begining of operation and in the end. The time difference is actual result |
|
241 // |
|
242 // The logging operations take about 5ms, which should be considered if inner |
|
243 // tag are used. |
|
244 // |
|
245 // Examples: |
|
246 // |
|
247 // __TIME_MARK(t) |
|
248 // DoOperation(...); |
|
249 // __TIME_ENDMARK(_L("Message 1"), t); |
|
250 // |
|
251 // __TIME(_L("Message 1"), DoOperation(...)) |
|
252 // |
|
253 // ---------------------------------------------------------------------------- |
|
254 // |
|
255 |
|
256 // |
|
257 // Actual implementation of |
|
258 // Logs the microsecond difference between current value and stored earlier |
|
259 // aMsg - textual message stored to the log file |
|
260 // aStart - the start time, the value is set by previous macros |
|
261 // |
|
262 inline void __impl_time_endmark(const TDesC& aMsg, TTime aStart) |
|
263 { |
|
264 TTime now; |
|
265 now.UniversalTime(); |
|
266 TTimeIntervalMicroSeconds delta = now.MicroSecondsFrom(aStart); |
|
267 #ifdef AI_RD_LOG_TO_DEBUG_OUTPUT |
|
268 RDebug::Print( _L("\t[T]\t%S\tTime:\t%Ld"), &aMsg, delta.Int64() ); |
|
269 #else |
|
270 RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, _L("\t[T]\t%S\tTime:\t%Ld"), &aMsg, delta.Int64()); |
|
271 #endif |
|
272 } |
|
273 |
|
274 // |
|
275 // Prints the message and current ms value to the log file |
|
276 // |
|
277 inline void __impl_tick(const TDesC& aMsg) |
|
278 { |
|
279 //Gets the nanokernel tick count. This is the current value of the machine's millisecond tick counter. |
|
280 TUint32 nTick = User::NTickCount(); |
|
281 #ifdef AI_RD_LOG_TO_DEBUG_OUTPUT |
|
282 RDebug::Print( _L("\t[T]\t%S\tMicro Sec:\t%d000"), &aMsg, nTick ); |
|
283 #else |
|
284 RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, _L("\t[T]\t%S\tMicro Sec:\t%d000"), &aMsg, nTick); |
|
285 #endif |
|
286 } |
|
287 |
|
288 // ---------------------------------------------------------------------------- |
|
289 // |
|
290 // Logs the amout of used heap to log file. Notes that the Heap value equals |
|
291 // to the result provided by Goofy tool. |
|
292 // |
|
293 // ---------------------------------------------------------------------------- |
|
294 // |
|
295 inline void __impl_heap(const TDesC& aMsg) |
|
296 { |
|
297 TInt size; |
|
298 User::Heap().AllocSize(size); |
|
299 #ifdef AI_RD_LOG_TO_DEBUG_OUTPUT |
|
300 RDebug::Print( _L("\t[M]\t%S\tAlloc:\t%d\tHeap:\t%d"), &aMsg, size, User::Heap().Size() ); |
|
301 #else |
|
302 RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, _L("\t[M]\t%S\tAlloc:\t%d\tHeap:\t%d"), &aMsg, size, User::Heap().Size()); |
|
303 #endif |
|
304 } |
|
305 |
|
306 inline void __impl_print(TRefByValue<const TDesC16> aFmt, ...) |
|
307 { |
|
308 VA_LIST list; |
|
309 VA_START(list,aFmt); |
|
310 RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, aFmt, list); |
|
311 VA_END(list); |
|
312 } |
|
313 |
|
314 inline void __impl_print8(TRefByValue<const TDesC8> aFmt, ...) |
|
315 { |
|
316 VA_LIST list; |
|
317 VA_START(list,aFmt); |
|
318 RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, aFmt, list); |
|
319 VA_END(list); |
|
320 } |
|
321 |
|
322 inline void __impl_prints(const TDesC& aMsg) |
|
323 { |
|
324 #ifdef AI_RD_LOG_TO_DEBUG_OUTPUT |
|
325 RDebug::Print( aMsg ); |
|
326 #else |
|
327 RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, _L("\t[I]\t%S"), &aMsg); |
|
328 #endif |
|
329 } |
|
330 |
|
331 } // namespace |
|
332 |
|
333 #endif // AI_ENABLE_DEBUG_LOGGING |
|
334 |
|
335 #endif // !__AI2_DEBUG_H__ |