|
1 /* |
|
2 * Copyright (c) 2009 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: Trace macro declarations. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #ifndef CNTDEBUG_H |
|
20 #define CNTDEBUG_H |
|
21 |
|
22 #include <QDebug> // QDebug |
|
23 #include <QtGlobal> // qDebug() |
|
24 |
|
25 // #define TRACK_MEMORY_LEAKS |
|
26 |
|
27 /*! |
|
28 \def CNT_UNUSED(name) |
|
29 \brief Declares a single variable as unused when tracing is disabled. |
|
30 |
|
31 CNT_UNUSED allows variables (usually method parameters) to be declared as used only if |
|
32 tracing is enabled. Without this variables that are included in trace macros, but not otherwise |
|
33 used, would cause unused variable warnings on compilation. If tracing is enabled, CNT_UNUSED |
|
34 has no effect. |
|
35 |
|
36 Consider the following class method where the parameter number is not used at all, except for |
|
37 tracing its value on entry: |
|
38 |
|
39 \code |
|
40 #include <cntdebug.h> |
|
41 |
|
42 void MyClass::myMethod(int number) |
|
43 { |
|
44 CNT_UNUSED(number) |
|
45 CNT_ENTRY("number =" << number) |
|
46 |
|
47 // ...some more code where the parameter number is not used. |
|
48 |
|
49 CNT_EXIT |
|
50 } |
|
51 \endcode |
|
52 |
|
53 Compiling this method with tracing completely disabled at compile time would cause an unused |
|
54 variable warning to be issued unless the CNT_UNUSED macro is used to declare the variable as |
|
55 trace-only. |
|
56 |
|
57 \param name The name of the variable to declare as unused if tracing is disabled. To mark |
|
58 several variables as trace-only, add a separate CNT_UNUSED statement for each. |
|
59 \sa CNT_STATIC_ENTRY_ARGS(args), CNT_ENTRY_ARGS(args). |
|
60 */ |
|
61 |
|
62 /*! |
|
63 \def CNT_STATIC_ENTRY |
|
64 \brief A method entry trace macro for static class methods or global functions. |
|
65 |
|
66 Invoking CNT_STATIC_ENTRY outputs a timestamp followed by the scope in which the macro |
|
67 was invoked and the word "entry". |
|
68 |
|
69 CNT_STATIC_ENTRY is intended to be used as the first line of static class methods or |
|
70 global functions. There is a corresponding exit macro, CNT_EXIT. |
|
71 |
|
72 The following example shows proper usage of the CNT_STATIC_ENTRY macro. Assuming a class |
|
73 has been declared with a static method that is implemented like this: |
|
74 |
|
75 \code |
|
76 #include <cntdebug.h> |
|
77 |
|
78 void MyClass::myStaticMethod() |
|
79 { |
|
80 CNT_STATIC_ENTRY |
|
81 |
|
82 int i = 1; |
|
83 i++; |
|
84 |
|
85 CNT_EXIT |
|
86 } |
|
87 \endcode |
|
88 |
|
89 calling MyClass::myStaticMethod() generates output lines of the following format: |
|
90 |
|
91 \code |
|
92 2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod() entry |
|
93 2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod() exit |
|
94 \endcode |
|
95 |
|
96 \sa CNT_STATIC_ENTRY_ARGS(args), CNT_EXIT. |
|
97 */ |
|
98 |
|
99 /*! |
|
100 \def CNT_STATIC_ENTRY_ARGS(args) |
|
101 \brief A method entry trace macro with arguments for static class methods or global functions. |
|
102 |
|
103 CNT_STATIC_ENTRY_ARGS(args) is similar to CNT_STATIC_ENTRY but it allows arguments to be |
|
104 output on the same line without needing to resort to a separate CNT_LOG_ARGS call. This is |
|
105 especially handy for outputting the parameters of the method call. |
|
106 |
|
107 The following example shows proper usage of the CNT_STATIC_ENTRY_ARGS(args) macro. Assuming |
|
108 a class has been declared with a static method that is implemented like this: |
|
109 |
|
110 \code |
|
111 #include <QString> |
|
112 #include <cntdebug.h> |
|
113 |
|
114 void MyClass::myStaticMethod(const QString &text, int number) |
|
115 { |
|
116 CNT_STATIC_ENTRY_ARGS("text =" << text << "number =" << number); |
|
117 |
|
118 int i = 1; |
|
119 i++; |
|
120 |
|
121 CNT_EXIT |
|
122 } |
|
123 \endcode |
|
124 |
|
125 calling MyClass::myStaticMethod(QString("foo"), 74) generates output lines of the following |
|
126 format: |
|
127 |
|
128 \code |
|
129 2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod(const QString&, int) entry, text = "foo" number = 74 |
|
130 2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod(const QString&, int) exit |
|
131 \endcode |
|
132 |
|
133 \param args Any number of arguments that can be streamed into a QTextStream, joined together |
|
134 by the streaming operator <<. |
|
135 \sa CNT_STATIC_ENTRY. |
|
136 */ |
|
137 |
|
138 /*! |
|
139 \def CNT_ENTRY |
|
140 \brief A method entry trace macro for class methods. |
|
141 |
|
142 Invoking CNT_ENTRY outputs a timestamp followed by the scope in which the macro |
|
143 was invoked, the word "entry" and the this pointer value of the instance invoking the |
|
144 macro. |
|
145 |
|
146 The this pointer value included in the debug output can help make the output more readable, as |
|
147 it allows different instances of the same class to be distinguished from each other. |
|
148 |
|
149 CNT_ENTRY is intended to be used as the first line of class methods. There is a corresponding |
|
150 exit macro, CNT_EXIT. |
|
151 |
|
152 The following example shows proper usage of the CNT_ENTRY macro. Assuming a class has been |
|
153 declared with a non-static method that is implemented like this: |
|
154 |
|
155 \code |
|
156 #include <cntdebug.h> |
|
157 |
|
158 void MyClass::myMethod() |
|
159 { |
|
160 CNT_ENTRY |
|
161 |
|
162 int i = 1; |
|
163 i++; |
|
164 |
|
165 CNT_EXIT |
|
166 } |
|
167 \endcode |
|
168 |
|
169 calling myMethod() on an instance of MyClass generates output lines of the following format: |
|
170 |
|
171 \code |
|
172 2009-03-25 11:00:50.171 : void MyClass::myMethod() this 0x6cdab90 entry |
|
173 2009-03-25 11:00:50.171 : void MyClass::myMethod() exit |
|
174 \endcode |
|
175 |
|
176 \sa CNT_ENTRY_ARGS(args), CNT_EXIT. |
|
177 */ |
|
178 |
|
179 /*! |
|
180 \def CNT_ENTRY_ARGS(args) |
|
181 \brief A method entry trace macro with arguments for class methods. |
|
182 |
|
183 CNT_ENTRY_ARGS(args) is similar to CNT_ENTRY but it allows arguments to be output on the |
|
184 same line without needing to resort to a separate CNT_LOG_ARGS call. This is especially |
|
185 handy for outputting the parameters of the method call. |
|
186 |
|
187 The following example shows proper usage of the CNT_ENTRY_ARGS(args)) macro. Assuming a |
|
188 class has been declared with a non-static method that is implemented like this: |
|
189 |
|
190 \code |
|
191 #include <QString> |
|
192 #include <cntdebug.h> |
|
193 |
|
194 void MyClass::myMethod(const QString &text, int number) |
|
195 { |
|
196 CNT_ENTRY_ARGS("text =" << text << "number =" << number); |
|
197 |
|
198 int i = 1; |
|
199 i++; |
|
200 |
|
201 CNT_EXIT |
|
202 } |
|
203 \endcode |
|
204 |
|
205 calling myMethod(QString("foo"), 74) on an instance of MyClass generates output lines of the |
|
206 following format: |
|
207 |
|
208 \code |
|
209 2009-03-25 11:00:50.171 : void MyClass::myMethod(const QString&, int) this 0x6cdab90 entry, text = "foo" number = 74 |
|
210 2009-03-25 11:00:50.171 : void MyClass::myMethod(const QString&, int) exit |
|
211 \endcode |
|
212 |
|
213 \param args Any number of arguments that can be streamed into a QTextStream, joined together |
|
214 by the streaming operator <<. |
|
215 \sa CNT_ENTRY, CNT_EXIT. |
|
216 */ |
|
217 |
|
218 /*! |
|
219 \def CNT_EXIT |
|
220 \brief A method exit trace macro for class methods or global functions. |
|
221 |
|
222 Invoking CNT_EXIT outputs a timestamp followed by the scope in which the macro |
|
223 was invoked and the word "exit". |
|
224 |
|
225 CNT_EXIT is intended to be used as the last line of class methods and global functions, |
|
226 just before the return statement, if any. There are two corresponding entry macros, |
|
227 CNT_ENTRY and CNT_STATIC_ENTRY, depending on whether the method being traced is a |
|
228 non-static or a static class method. CNT_EXIT makes no distinction between these two types |
|
229 of methods and is to be used for both. |
|
230 |
|
231 See CNT_ENTRY or CNT_STATIC_ENTRY for an example of how to use CNT_EXIT. |
|
232 |
|
233 \sa CNT_EXIT_ARGS(args), CNT_ENTRY, CNT_STATIC_ENTRY. |
|
234 */ |
|
235 |
|
236 /*! |
|
237 \def CNT_EXIT_ARGS(args) |
|
238 \brief A method exit trace macro with arguments for class methods or global functions. |
|
239 |
|
240 CNT_EXIT_ARGS(args) is similar to CNT_EXIT but it allows arguments to be output on the |
|
241 same line without needing to resort to a separate CNT_LOG_ARGS call. This is especially |
|
242 handy for outputting the return value of the method call. |
|
243 |
|
244 The following example shows proper usage of the CNT_EXIT_ARGS(args) macro. Assuming a |
|
245 class has been declared with a static method that is implemented like this: |
|
246 |
|
247 \code |
|
248 #include <QString> |
|
249 #include <cntdebug.h> |
|
250 |
|
251 int MyClass::myStaticMethod(const QString &text) |
|
252 { |
|
253 CNT_STATIC_ENTRY_ARGS("text =" << text); |
|
254 |
|
255 int length = text.length(); |
|
256 |
|
257 CNT_EXIT_ARGS("length" << length); |
|
258 |
|
259 return length; |
|
260 } |
|
261 \endcode |
|
262 |
|
263 calling MyClass::myStaticMethod(QString("foo")) generates output lines of the following format: |
|
264 |
|
265 \code |
|
266 2009-03-25 13:20:36.448 : static int MyClass::myStaticMethod(const QString&) entry, text = "foo" |
|
267 2009-03-25 13:20:36.448 : static int MyClass::myStaticMethod(const QString&) exit, length 3 |
|
268 \endcode |
|
269 |
|
270 Although the example above is a static method, CNT_EXIT_ARGS(args) works identically for |
|
271 non-static class methods and global functions. |
|
272 |
|
273 \param args Any number of arguments that can be streamed into a QTextStream, joined together |
|
274 by the streaming operator <<. |
|
275 \sa CNT_EXIT |
|
276 */ |
|
277 |
|
278 /*! |
|
279 \def CNT_LOG |
|
280 \brief A trace macro for class methods or global functions. |
|
281 |
|
282 Invoking CNT_LOG outputs a timestamp followed by the scope in which the macro |
|
283 was invoked and the this pointer value of the instance invoking the |
|
284 macro. |
|
285 |
|
286 CNT_LOG is similar to CNT_ENTRY but it is especially handy for marking calls to methods that |
|
287 cannot fail, such as an empty constructor, without needing to resort to a separate CNT_EXIT call. |
|
288 |
|
289 The following example shows proper usage of the CNT_LOG(args) macro. Assuming a |
|
290 class has been declared with a static method that is implemented like this: |
|
291 |
|
292 \code |
|
293 #include <QString> |
|
294 #include <cntdebug.h> |
|
295 |
|
296 MyClass::MyClass() |
|
297 { |
|
298 CNT_LOG |
|
299 } |
|
300 \endcode |
|
301 |
|
302 calling new MyClass() generates output lines of the following format: |
|
303 |
|
304 \code |
|
305 2009-03-25 13:20:36.448 : MyClass::MyClass() this 0x6cdab90 |
|
306 \endcode |
|
307 |
|
308 \sa CNT_LOG_ARGS |
|
309 */ |
|
310 |
|
311 /*! |
|
312 \def CNT_LOG_ARGS(args) |
|
313 \brief A generic trace macro with arguments for class methods or global functions. |
|
314 |
|
315 The following example shows how to produce arbitrary debug output: |
|
316 |
|
317 \code |
|
318 #include <QString> |
|
319 #include <cntdebug.h> |
|
320 |
|
321 void MyClass::myMethod() |
|
322 { |
|
323 CNT_ENTRY |
|
324 |
|
325 QString myString("This is a string."); |
|
326 int myValue = 109; |
|
327 |
|
328 CNT_LOG_ARGS("this is a debug message, myString =" << myString << "myValue =" << myValue) |
|
329 |
|
330 CNT_EXIT |
|
331 } |
|
332 \endcode |
|
333 |
|
334 calling myMethod() on an instance of MyClass generates output lines of the following format: |
|
335 |
|
336 \code |
|
337 2009-03-25 13:45:22.083 : void MyClass::myMethod() this 0x6cdab90 entry |
|
338 2009-03-25 13:45:22.083 : void MyClass::myMethod() this is a debug message, myString = "This is a string." myValue = 109 |
|
339 2009-03-25 13:45:22.083 : void MyClass::myMethod() exit |
|
340 \endcode |
|
341 |
|
342 Any number of arguments may be printed by chaining them together with the streaming operator |
|
343 <<. Notice that a single space character is automatically added between each streamed |
|
344 argument, hence the hardcoded strings in the example above, such as "myValue =", do not have |
|
345 a space at the beginning and end of the string. This automatic space addition is a feature |
|
346 of qDebug() streaming and cannot be disabled. |
|
347 |
|
348 \param args Any number of arguments that can be streamed into a QTextStream, joined together |
|
349 by the streaming operator <<. |
|
350 */ |
|
351 |
|
352 |
|
353 #ifdef _DEBUG |
|
354 #define CNT_UNUSED(name) |
|
355 #define CNT_STATIC_ENTRY qDebug() << __PRETTY_FUNCTION__ << "entry"; |
|
356 #define CNT_STATIC_ENTRY_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "entry," << args; |
|
357 #define CNT_ENTRY qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this << "entry"; |
|
358 #define CNT_ENTRY_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this << "entry," << args; |
|
359 #define CNT_EXIT qDebug() << __PRETTY_FUNCTION__ << "exit"; |
|
360 #define CNT_EXIT_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "exit," << args; |
|
361 #define CNT_LOG qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this; |
|
362 #define CNT_LOG_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << args; |
|
363 #else |
|
364 #define CNT_UNUSED(name) Q_UNUSED(name) |
|
365 #define CNT_STATIC_ENTRY |
|
366 #define CNT_STATIC_ENTRY_ARGS(args) |
|
367 #define CNT_ENTRY |
|
368 #define CNT_ENTRY_ARGS(args) |
|
369 #define CNT_EXIT |
|
370 #define CNT_EXIT_ARGS(args) |
|
371 #define CNT_LOG |
|
372 #define CNT_LOG_ARGS(args) |
|
373 #endif // _DEBUG |
|
374 |
|
375 // for tracing memory leaks |
|
376 #ifdef TRACK_MEMORY_LEAKS |
|
377 #include <hbapplication.h> |
|
378 |
|
379 #define CNT_TRACK_QOBJECTLIFE(obj) { new CntQObjectTracker(obj, __FILE__, __LINE__); } |
|
380 #define CNT_TRACK_QOBJECTLIVES(objects) { foreach (QObject* object, objects) new CntQObjectTracker(object, __FILE__, __LINE__); } |
|
381 |
|
382 class CntQObjectTracker : public QObject |
|
383 { |
|
384 Q_OBJECT |
|
385 public: |
|
386 CntQObjectTracker(QObject *obj, QString fileName, int fileLine) { |
|
387 objectName = obj->metaObject()->className(); |
|
388 createdInFile = fileName; |
|
389 createdAtLine = fileLine; |
|
390 connect(obj, SIGNAL(destroyed()), this, SLOT(objectDestroyed())); |
|
391 connect(HbApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(reportMemoryLeak())); |
|
392 } |
|
393 public slots: |
|
394 void objectDestroyed() { delete this; } |
|
395 private slots: |
|
396 void reportMemoryLeak() { qDebug() << "MEMORY LEAK: The" << objectName << "object in" << createdInFile << "at line" << createdAtLine << "was never destroyed."; delete this; } |
|
397 private: // functions |
|
398 ~CntQObjectTracker() {} |
|
399 private: // data |
|
400 QString objectName; |
|
401 QString createdInFile; |
|
402 int createdAtLine; |
|
403 }; |
|
404 #else |
|
405 #define CNT_TRACK_QOBJECTLIFE(obj) |
|
406 #define CNT_TRACK_QOBJECTLIVES(obj) |
|
407 #endif |
|
408 |
|
409 #endif // CNTDEBUG_H |