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.
  • 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