Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt Creator and other tools
  4. Q_ASSERT no longer pauses debugger
Forum Updated to NodeBB v4.3 + New Features

Q_ASSERT no longer pauses debugger

Scheduled Pinned Locked Moved Qt Creator and other tools
18 Posts 7 Posters 12.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    nirslsk
    wrote on last edited by
    #1

    Hi there,

    Please forgive me if this is a well known issue, I've searched the forum and couldn't find anything, although I can't imagine I'm the first one this is a problem for. I've noticed that in the last few versions of Qt Creator for Windows, Q_ASSERT no longer pauses the debugger but rather just crashes the application. This is a huge problem for me since my project uses Q_ASSERTs very liberally. I tried checking 'Stop when qWarning is issued' and 'Stop when qFatal is issued' under Options->Debugger->GDB, but in that case the application won't even load in debug mode. Is there any way at all to restore the debugger-pausing functionality of Q_ASSERT from previous versions of Qt Creator?

    Thanks, Nir

    1 Reply Last reply
    2
    • K Offline
      K Offline
      koahnig
      wrote on last edited by
      #2

      It sais in Qt Assistant
      @
      If b is zero, the Q_ASSERT statement will output the following message using the qFatal() function:
      @
      Under the debugging techniques is sais:
      @
      qFatal() is used for writing fatal error messages shortly before exiting.
      @
      Reading this, your debugger seems to behave as expected.
      This seems to complyant with the behaviour of "assert" under ms compilers.

      Vote the answer(s) that helped you to solve your issue(s)

      1 Reply Last reply
      0
      • D Offline
        D Offline
        dangelog
        wrote on last edited by
        #3
        1. Are you sure your application is compiled in debug mode?
        2. Can you try to manually put a breakpoint on qFatal and see if you hit it?

        Software Engineer
        KDAB (UK) Ltd., a KDAB Group company

        1 Reply Last reply
        0
        • N Offline
          N Offline
          nirslsk
          wrote on last edited by
          #4

          koahnig: I totally get that. I understand if pausing the debugger when a Q_ASSERT fails was just a freebie in previous versions of Qt Creator, but I'd love to have something like that again. Even if it's a different mechanism that does the same thing, ie pause the debugger when a condition fails. Also I find it odd that the application won't start at all in debug mode if the 'stop at qFatal/qWarning' options are checked.

          peppe: Absolutely. The application debugs just fine. It just crashes when a Q_ASSERT fails. I set a breakpoint on a qFatal call as you've suggested and it gets there just fine, then of course proceeds to crash when resumed :)

          1 Reply Last reply
          0
          • N Offline
            N Offline
            nirslsk
            wrote on last edited by
            #5

            I should have posted this earlier, I did some digging into this problem a couple of months ago (I've been dealing with it for a while :) and ended up finding this bug report: https://bugreports.qt.nokia.com/browse/QTCREATORBUG-5200 . I couldn't remember how it relates but indeed when stop on qWarning/qFatal are checked I get:

            (Internal error: pc 0x0 in read in psymtab, but not in symtab.)

            and sometimes:

            (Internal error: pc 0x6 in read in psymtab, but not in symtab.)

            in the application output window.

            Many of the related issues listed echo the kind of trouble I've been experiencing. The bug is not yet evaluated however.

            1 Reply Last reply
            0
            • D Offline
              D Offline
              dangelog
              wrote on last edited by
              #6

              Well, the application is supposed to "crash" when a Q_ASSERT fails*! :-)
              What's the strange behaviour in that?

              • This applies of course to debug builds only, release builds expand Q_ASSERT to nothing. The "crash" is calling abort(3) under *nix systems.

              Software Engineer
              KDAB (UK) Ltd., a KDAB Group company

              1 Reply Last reply
              0
              • K Offline
                K Offline
                koahnig
                wrote on last edited by
                #7

                [quote author="nirslsk" date="1325919907"]koahnig: I totally get that. I understand if pausing the debugger when a Q_ASSERT fails was just a freebie in previous versions of Qt Creator, but I'd love to have something like that again.
                [/quote]
                I am wondering if this was really a feature of qt creator. Since I am a mere user of debugger than one knowing the functionality and interaction per se, I might be wrong.
                However, to my understanding is qt creator a shell using different debuggers depending on the tool chains. It is not a simple shell, but has certainly enough hooks into the debuggers to perform a lot of things. The debugger itself is used somehow again as a shell for the program to be debugged. Again it is using hooks for "communicating" with the program. There are possibilities to manipulate the conditions within the debuggee. Finally the program is executing and it will crash under certain conditions.
                Some debuggers may be or are able to overwrite those conditions. However, do they provide also the hooks for creator?

                This description is certainly very, very simplistic of the whole situation. However, it leads to a point. The application your program is crashing. Seeing the complexity of the different stages of debugging process the question is wasn't it a bug in previous Qt version and not the creator which allowed keeping your application running?

                Vote the answer(s) that helped you to solve your issue(s)

                1 Reply Last reply
                0
                • N Offline
                  N Offline
                  nirslsk
                  wrote on last edited by
                  #8

                  What is the 'Stop when qFatal is issued' option supposed to do then?

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    koahnig
                    wrote on last edited by
                    #9

                    Judging by the name qFatal I would connect immediately to "no recovery possible" and "will not continue". What is more than fatal?
                    Therefore, it is "natural" that there nothing afterwards.

                    Vote the answer(s) that helped you to solve your issue(s)

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on last edited by
                      #10

                      @nirslsk
                      Could you point me to where you put that breakpoint exactly? I tried putting one, but the place where I tried did not seem to trigger (C:\QtSDK\QtSources\4.7.4\src\corelib\global\qglobal.cpp line 2518)

                      1 Reply Last reply
                      0
                      • N Offline
                        N Offline
                        nirslsk
                        wrote on last edited by
                        #11

                        Hi Andre,

                        I didn't actually put a breakpoint in the qFatal function... I don't think my Qt Creator setup is configured to work with the actual Qt sources. I put the breakpoint in my own code on a line where qFatal is being called.

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          andre
                          wrote on last edited by
                          #12

                          OK, my issue was finding that line :-)

                          It seems the root cause is actually a Qt Creator bug. Something is fishy when trying to set a breakpoint near qFatal itself.

                          This is my temporary solution. Insert the below in main.cpp

                          @
                          //debugging asserts in Qt code is tricky with MinGw. You get a crash, instead of a backtrace.
                          //enable the define below to get a crash that results in a backtrace instead. Note that it does
                          //mess up your debug output, so don't leave it enabled if you're not working on fixing an assert
                          #define DEBUG_QT_ASSERT

                          #ifdef DEBUG_QT_ASSERT
                          void crashMessageOutput(QtMsgType type, const char *msg)
                          {
                          switch (type) {
                          case QtDebugMsg:
                          fprintf(stderr, "Debug: %s\n", msg);
                          break;
                          case QtWarningMsg:
                          fprintf(stderr, "Warning: %s\n", msg);
                          break;
                          case QtCriticalMsg:
                          fprintf(stderr, "Critical: %s\n", msg);
                          break;
                          case QtFatalMsg:
                          fprintf(stderr, "Fatal: %s\n", msg);
                          __asm("int3");
                          abort();
                          }
                          }
                          #endif

                          int main(int argc, char *argv[])
                          {
                          #ifdef DEBUG_QT_ASSERT
                          qInstallMsgHandler(crashMessageOutput);
                          #endif

                          QApplication a(argc, argv);
                          
                          //etc. rest of main function
                          

                          }
                          @

                          1 Reply Last reply
                          0
                          • N Offline
                            N Offline
                            nirslsk
                            wrote on last edited by
                            #13

                            Thank you! That's already much better than the near empty crash message I currently get on a Q_ASSERT failure. Actually one thing I've found that works well for me is replacing the Q_ASSERTs in my program with a simple function that writes to a null pointer if the condition given is false:

                            @void CrashAssert (bool i_condition)
                            {
                            #ifdef DEBUG
                            if (! i_condition)
                            {
                            int * a = 0; *a = 0;
                            }
                            #endif
                            }@

                            (I take care to define the DEBUG macro in my project settings, I understand you can also ifndef QT_NO_DEBUG instead)

                            What happens then is that I actually get the debugger to stop at the point of the condition failure. I can't resume the program execution as when Q_ASSERT used to pause the debugger, but I can inspect the stack in detail and look at each variable as usual. Not the most elegant solution in the world, but it's worked well so far :)

                            Thanks much, Nir

                            1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              andre
                              wrote on last edited by
                              #14

                              Nice thing about my work-around, is that it is also useful for asserts inside the Qt library itself. For instance, if you call QList::at() with an out of bounds index, you get an assert. With the piece of code I posted, this now results in a stacktrace where you can figure out where that call to QList::at() is actually made in your own code. Also, my version will never be optimized out by a compiler. I think that yours may be, but I'm not sure.

                              It would be much better if such a hack was not needed though.

                              1 Reply Last reply
                              0
                              • N Offline
                                N Offline
                                nirslsk
                                wrote on last edited by
                                #15

                                True, I'll be sure to alternate between the two solutions as my needs change. Here's hoping for the return of Q_ASSERT's functionality of yore :)

                                1 Reply Last reply
                                0
                                • S Offline
                                  S Offline
                                  sharevari
                                  wrote on last edited by
                                  #16

                                  This was driving me mad as well, I ended up abandoning Q_ASSERT altogether and implemented my own simple SCASSERT (for Stop and Continue Assert) for when using Qt Creator with MinGW and GDB:

                                  @
                                  #define SCASSERT(cond)
                                  {
                                  if (!(cond))
                                  {
                                  qDebug("ASSERT: %s in %s (%s:%u)",
                                  #cond, PRETTY_FUNCTION, FILE, LINE);
                                  asm("int $3");
                                  }
                                  }
                                  @

                                  This will break into the debugger on the line of the assert and allow you to continue afterwards should you choose to.

                                  H 1 Reply Last reply
                                  1
                                  • S sharevari

                                    This was driving me mad as well, I ended up abandoning Q_ASSERT altogether and implemented my own simple SCASSERT (for Stop and Continue Assert) for when using Qt Creator with MinGW and GDB:

                                    @
                                    #define SCASSERT(cond)
                                    {
                                    if (!(cond))
                                    {
                                    qDebug("ASSERT: %s in %s (%s:%u)",
                                    #cond, PRETTY_FUNCTION, FILE, LINE);
                                    asm("int $3");
                                    }
                                    }
                                    @

                                    This will break into the debugger on the line of the assert and allow you to continue afterwards should you choose to.

                                    H Offline
                                    H Offline
                                    harveyab
                                    wrote on last edited by harveyab
                                    #17

                                    @sharevari Very good! Thank you. I had to reformat and make some changes to get it to run on my Linux Mint system. I also added the options for using either it, Q_ASSERT or turning it off by just changing a number in the first line (0, 1 or 2).

                                    #define ASSRT 2
                                    #if ASSRT == 1
                                    #define SCASSERT Q_ASSERT
                                    #elif ASSRT == 2
                                    #define SCASSERT(cond) {\
                                        if (!(cond)) {\
                                            qDebug("ASSERT: %s in %s (%s:%u)",#cond, Q_FUNC_INFO, __FILE__, __LINE__);\
                                            asm("int $3");\
                                        }\
                                    }
                                    #else
                                    #define SCASSERT(cond) {}
                                    #endif
                                    
                                    

                                    Notice the backslashes at the ends of the multi-line definition.

                                    1 Reply Last reply
                                    0
                                    • I Offline
                                      I Offline
                                      IanMoone
                                      wrote on last edited by IanMoone
                                      #18

                                      I still have the issue with QtCreator 4.7.0.
                                      This is boring when the assert comes from Qt.

                                      At least using qInstallMessageHandler works fine.

                                      Windows 10, with Mingw and Qt 5.10.1

                                      1 Reply Last reply
                                      0

                                      • Login

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • Users
                                      • Groups
                                      • Search
                                      • Get Qt Extensions
                                      • Unsolved