Results 1 to 4 of 4

Thread: Global debugging function

  1. #1
    Join Date
    Jan 2011
    Posts
    70
    Thanks
    43
    Thanked 4 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Global debugging function

    Maybe this functionality already exists in the Qt docs and I haven't come across it yet, so I'm open to suggestions.

    Basically what I'm trying to do is create a one-line, generic, global error reporting mechanism for my multi-file program. When it's compiled in debug mode, the function outputs to qDebug() and I read it from the application output in Qt Creator. However, if it's compiled in release mode, I want the function to output to a file instead of the command prompt.

    Here's my (buggy) implementation:
    Qt Code:
    1. //myerror.h:
    2. #ifndef MYERROR_H
    3. #define MYERROR_H
    4.  
    5. #ifdef DEBUGMODE //DEBUGMODE is defined in the .pro file by "Debug:DEFINES += DEBUGMODE"
    6. #include <QDebug>
    7. #else
    8. #include <QFile>
    9. QFile ERRLOG("c:/temp/my_errors.log");
    10. #endif
    11.  
    12. inline void QDEBUG(QString a)
    13. {
    14. #ifdef DEBUGMODE
    15. qDebug() << a;
    16. #else
    17. ERRLOG.write(QString("%1\n").arg(a).toAscii());
    18. #endif
    19. }
    20.  
    21. #endif // MYERROR_H
    22.  
    23. //mainwindow.cpp:
    24. MainWindow::MainWindow(QWidget *parent) :
    25. QMainWindow(parent),
    26. ui(new Ui::MainWindow)
    27. {
    28. #ifndef DEBUGMODE
    29. ERRLOG.open(QIODevice::WriteOnly);
    30. #endif
    31.  
    32. ui->setupUi(this);
    33. //etc
    34. }
    35. MainWindow::~MainWindow()
    36. {
    37. #ifndef DEBUGMODE
    38. ERRLOG.close();
    39. #endif
    40. delete ui;
    41. }
    To copy to clipboard, switch view to plain text mode 

    Now, this works while I'm in debug mode, but doesn't work when in release mode. The file "my_errors.log" is being generated, but as far as I can tell it was never opened or written to. I can't just open the QFile in myerror.h because it's a header, so I have to do it in mainwindow.cpp.

    Additionally, including this header in more than one cpp file resulted in a linker error complaining about multiple definitions, even though I've guarded myerror.h!

    Is there a better way to do this? Can I just re-route qDebug() to a file? I couldn't find anything on that in the documentation.

    Thanks!
    Last edited by Phlucious; 8th December 2011 at 00:04.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Global debugging function

    Why don't you look at qInstallMsgHandler()? Looks like that will do everything you're asking for in both release and debug modes.

  3. #3
    Join Date
    Jan 2011
    Posts
    70
    Thanks
    43
    Thanked 4 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Global debugging function

    Figures. I just found that, too! Thanks!

  4. #4
    Join Date
    Jan 2011
    Posts
    70
    Thanks
    43
    Thanked 4 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Global debugging function

    I followed the examples given in the docs and created my own little custom error handler like so:

    Qt Code:
    1. #define now QTime::currentTime().toString("HH:mm:ss").toLocal8Bit().data()
    2. #define today QDate::currentDate().toString("d-M-yyyy").toLocal8Bit().data()
    3.  
    4. void handler(QtMsgType type, const char *msg)
    5. {
    6. #ifdef DEBUGMODE
    7. switch (type)
    8. {
    9. case QtDebugMsg:
    10. fprintf(stdout, "Debug: %s\n", msg);
    11. fprintf(stderr, "%s Debug: %s\n", now, msg);
    12. break;
    13. case QtWarningMsg:
    14. fprintf(stdout, "Warning: %s\n", msg);
    15. fprintf(stderr, "%s Warning: %s\n", now, msg);
    16. break;
    17. case QtCriticalMsg:
    18. fprintf(stdout, "Error: %s\n", msg);
    19. fprintf(stderr, "%s Error: %s\n", now, msg);
    20. break;
    21. case QtFatalMsg:
    22. fprintf(stdout, "FATAL ERROR: %s\n", msg);
    23. fprintf(stderr, "%s FATAL ERROR: %s\n", now, msg);
    24. abort();
    25. }
    26. #else //RELEASEMODE
    27. switch (type)
    28. {
    29. case QtDebugMsg:
    30. break;
    31. case QtWarningMsg:
    32. fprintf(stderr, "%s Warning: %s\n", now, msg);
    33. break;
    34. case QtCriticalMsg:
    35. fprintf(stderr, "%s Error: %s\n", now, msg);
    36. break;
    37. case QtFatalMsg:
    38. fprintf(stderr, "%s FATAL ERROR: %s\n", now, msg);
    39. abort();
    40. }
    41. #endif
    42. }
    43.  
    44. myErrorHandler::myErrorHandler(const char* outfile)
    45. {
    46. freopen(outfile, "w", stderr);
    47. setbuf(stdout, NULL);
    48. fprintf(stderr, "Running LASE.exe on %s at %s.\n", today, now);
    49. }
    50.  
    51. myErrorHandler::~myErrorHandler()
    52. {
    53. }
    54.  
    55. void myErrorHandler::install()
    56. {
    57. qInstallMsgHandler(handler);
    58. }
    To copy to clipboard, switch view to plain text mode 

    Now, I'm compiling with MSVC2010 so I'm getting the typical "C4996 ______ This function of variable may be unsafe blah blah blah" warning for freopen and setbuf. Personally, I prefer to address all warnings whenever possible, so I'd prefer to use a QDataStream for portability instead of the standard library.

    The only way I can think of is to declare a global QDataStream variable with its device set to a global file, but I'd rather avoid setting more global variables if I can. Is this possible?

    I suppose I could content myself with disabling those particular warnings, but I can't figure out the syntax.

Similar Threads

  1. Connect to global function?
    By hakermania in forum Newbie
    Replies: 2
    Last Post: 3rd September 2011, 16:36
  2. QtConcurrentRun and global function
    By hakermania in forum Newbie
    Replies: 2
    Last Post: 16th July 2011, 10:05
  3. Replies: 3
    Last Post: 6th September 2010, 23:00
  4. Replies: 3
    Last Post: 25th May 2010, 09:46
  5. Replies: 0
    Last Post: 10th March 2010, 08:13

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.