inc/cntdebug.h
changeset 46 efe85016a067
child 50 77bc263e1626
child 59 a642906a277a
equal deleted inserted replaced
40:b46a585f6909 46:efe85016a067
       
     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