Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Memory access errors from QMessageBox
Forum Updated to NodeBB v4.3 + New Features

Memory access errors from QMessageBox

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 5 Posters 5.3k 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
    NigelMcFarlane
    wrote on last edited by
    #1

    I am using Qt 5.5 on Windows 8.1. As a result of an application crashing when a dialog box is displayed, I ran it under DrMemory, and discovered that there are memory access errors when I launch any kind of dialog box. The problem is reproducible from the following very simple QMessageBox code:

    #include <QApplication>
    #include <QMessageBox>

    int main(int argc, char* argv[])
    {
    QApplication app(argc, argv); // application object manages everything

    QMessageBox* messageBox = new QMessageBox;
    messageBox->setWindowTitle("My Message");
    messageBox->setText("Hello World");
    messageBox->setModal(true);
    messageBox->exec();
    delete messageBox;
    }

    To be precise, the access errors happen when the mouse is hovered over the "ok" button and then moved away. Launching a QPushButton on its own instead of a QMessageBox also causes the errors. Parenting the message box to a QMainWindow does not help. The DrMemory reports look like this (though there are usually several such errors):

    Dr. Memory version 1.9.0 build 0 built on Aug 28 2015 22:56:18
    Dr. Memory results for pid 8724: "MessageBox.exe"
    Application cmdline: ""C:\Users\Nigel\Visual Studio Projects\Qt.build\bin\Debug\MessageBox.exe""
    Recorded 110 suppression(s) from default C:\Program Files (x86)\Dr. Memory\bin\suppress-default.txt

    Error #1: UNADDRESSABLE ACCESS beyond heap bounds: reading 0x0365f8b0-0x0365f8b8 8 byte(s) within 0x0365f8b0-0x0365f8c0
    #0 Qt5Guid.dll!QPainter::drawImage +0x1a928 (0x00e7b0d8 <Qt5Guid.dll+0x4b0d8>)
    #1 Qt5Guid.dll!QPainter::drawImage +0x317822 (0x01177fd3 <Qt5Guid.dll+0x347fd3>)
    #2 Qt5Guid.dll!QPainter::drawImage +0x3119a8 (0x01172159 <Qt5Guid.dll+0x342159>)
    #3 Qt5Guid.dll!QPainter::drawImage +0x32d55d (0x0118dd0e <Qt5Guid.dll+0x35dd0e>)
    #4 Qt5Guid.dll!QPainter::drawImage +0x1df01 (0x00e7e6b2 <Qt5Guid.dll+0x4e6b2>)
    #5 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x13d6b5 (0x6502f096 <Qt5Widgetsd.dll+0x15f096>)
    #6 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x13626d (0x65027c4e <Qt5Widgetsd.dll+0x157c4e>)
    #7 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0xccf27 (0x64fbe908 <Qt5Widgetsd.dll+0xee908>)
    #8 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x15f8c7 (0x650512a8 <Qt5Widgetsd.dll+0x1812a8>)
    #9 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x1482d2 (0x65039cb3 <Qt5Widgetsd.dll+0x169cb3>)
    #10 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x139aaf (0x6502b490 <Qt5Widgetsd.dll+0x15b490>)
    #11 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x1a4b5c (0x6509653d <Qt5Widgetsd.dll+0x1c653d>)
    #12 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x244a66 (0x65136447 <Qt5Widgetsd.dll+0x266447>)
    #13 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x7e6eb (0x64f700cc <Qt5Widgetsd.dll+0xa00cc>)
    #14 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x183470 (0x65074e51 <Qt5Widgetsd.dll+0x1a4e51>)
    #15 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x244a1a (0x651363fb <Qt5Widgetsd.dll+0x2663fb>)
    #16 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x33aad (0x64f2548e <Qt5Widgetsd.dll+0x5548e>)
    #17 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0x31c14 (0x64f235f5 <Qt5Widgetsd.dll+0x535f5>)
    #18 Qt5Cored.dll!QSortFilterProxyModel::mapToSource +0x2ca891 (0x66a26b47 <Qt5Cored.dll+0x2e6b47>)
    #19 Qt5Cored.dll!QSortFilterProxyModel::mapToSource +0x3e9a42 (0x66b45cf8 <Qt5Cored.dll+0x405cf8>)
    Note: @0:00:23.901 in thread 7476
    Note: next higher malloc: 0x0365f8b8-0x036613ac
    Note: 0x0365f8b0-0x0365f8b8 is 28 byte(s) beyond memory 0x0365dda0-0x0365f894 that was freed here:
    Note: # 0 replace_free [d:\drmemory_package\common\alloc_replace.c:2514]
    Note: # 1 Qt5Guid.dll!QPainter::drawImage +0xe28d9 (0x00f4308a <Qt5Guid.dll+0x11308a>)
    Note: # 2 Qt5Guid.dll!QPainter::drawImage +0xea41e (0x00f4abcf <Qt5Guid.dll+0x11abcf>)
    Note: # 3 Qt5Guid.dll!QPainter::drawImage +0xdb28b (0x00f3ba3c <Qt5Guid.dll+0x10ba3c>)
    Note: # 4 Qt5Widgetsd.dll!QAbstractScrollArea::setHorizontalScrollBar+0xc0e56 (0x64fb2837 <Qt5Widgetsd.dll+0xe2837>)
    Note: # 5 Qt5Cored.dll!QSortFilterProxyModel::mapToSource +0x2d4ed (0x667897a3 <Qt5Cored.dll+0x497a3>)
    Note: instruction: movdqa (%ecx,%eax,4) -> %xmm0

    ===========================================================================
    FINAL SUMMARY:

    DUPLICATE ERROR COUNTS:

    SUPPRESSIONS USED:

    ERRORS FOUND:
    1 unique, 1 total unaddressable access(es)
    0 unique, 0 total uninitialized access(es)
    0 unique, 0 total invalid heap argument(s)
    0 unique, 0 total GDI usage error(s)
    0 unique, 0 total handle leak(s)
    0 unique, 0 total warning(s)
    0 unique, 0 total, 0 byte(s) of leak(s)
    0 unique, 0 total, 0 byte(s) of possible leak(s)
    ERRORS IGNORED:
    61 potential error(s) (suspected false positives)
    (details: C:\Users\Nigel\AppData\Roaming\Dr. Memory\DrMemory-MessageBox.exe.8724.000\potential_errors.txt)
    199 potential leak(s) (suspected false positives)
    (details: C:\Users\Nigel\AppData\Roaming\Dr. Memory\DrMemory-MessageBox.exe.8724.000\potential_errors.txt)
    5 unique, 10 total, 3234 byte(s) of still-reachable allocation(s)
    (re-run with "-show_reachable" for details)
    Details: C:\Users\Nigel\AppData\Roaming\Dr. Memory\DrMemory-MessageBox.exe.8724.000\results.txt

    Is there something wrong with my program, perhaps something wrong with my installation, or is it a bug in Qt?

    1 Reply Last reply
    0
    • H Offline
      H Offline
      Helson
      wrote on last edited by
      #2

      Try change QMessageBox* messageBox = new QMessageBox;
      to
      QMessageBox messageBox;
      and remove delete messageBox;

      N 1 Reply Last reply
      2
      • raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by
        #3

        first of all you should start the main event-loop (QApplication::exec())
        And open the the messageboxes once it runs, then check again if the error occurs.

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        N 1 Reply Last reply
        2
        • H Helson

          Try change QMessageBox* messageBox = new QMessageBox;
          to
          QMessageBox messageBox;
          and remove delete messageBox;

          N Offline
          N Offline
          NigelMcFarlane
          wrote on last edited by
          #4

          @Helson Thank you for your reply. Unfortuntately changing QMessageBox to an automatic variable makes no difference.

          1 Reply Last reply
          0
          • raven-worxR raven-worx

            first of all you should start the main event-loop (QApplication::exec())
            And open the the messageboxes once it runs, then check again if the error occurs.

            N Offline
            N Offline
            NigelMcFarlane
            wrote on last edited by
            #5

            @raven-worx
            thank you for your reply. I did forget to add app.exec() at the end, but adding it does not remove the errors.

            It's a bit tricky in this small example to run app.exec() before showing the box. However, in my much larger application, the dialogs and message boxes are created by events from a QMainWindow, when the QApplication is already running, and they do suffer from the same problem. Curiously the main window is itself completely clean of errors.

            raven-worxR 1 Reply Last reply
            0
            • N NigelMcFarlane

              @raven-worx
              thank you for your reply. I did forget to add app.exec() at the end, but adding it does not remove the errors.

              It's a bit tricky in this small example to run app.exec() before showing the box. However, in my much larger application, the dialogs and message boxes are created by events from a QMainWindow, when the QApplication is already running, and they do suffer from the same problem. Curiously the main window is itself completely clean of errors.

              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by
              #6

              @NigelMcFarlane
              the callstacks you've posted don't make much sense and i would say they can be carelessly discarded.
              So maybe you are overwriting the some memory in your application .. i don't know.
              And obviously you haven't even tried the snipped you've posted but claim that it isn't working. You should run this minimal example and check again if it still crashes. This is as easy as subclassing a plain QWidget and open the dialog on a button press for example.
              If it doesn't crash the issue is somewhere else in your code.

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              N 1 Reply Last reply
              0
              • raven-worxR raven-worx

                @NigelMcFarlane
                the callstacks you've posted don't make much sense and i would say they can be carelessly discarded.
                So maybe you are overwriting the some memory in your application .. i don't know.
                And obviously you haven't even tried the snipped you've posted but claim that it isn't working. You should run this minimal example and check again if it still crashes. This is as easy as subclassing a plain QWidget and open the dialog on a button press for example.
                If it doesn't crash the issue is somewhere else in your code.

                N Offline
                N Offline
                NigelMcFarlane
                wrote on last edited by
                #7

                @raven-worx
                I may not have attempted your suggestion on the mini-snippet but I most certainly tested the snippet itself before I posted it!!
                In any case, I have now found the cause of the crash in my application, and it was not caused by these "leaks". Whatever they are, they seem to be harmless. If no one else is seeing them perhaps they are just artefacts of the diagnostic tool.

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mjsurette
                  wrote on last edited by
                  #8

                  Normal practice is to construct with an argument

                  QMessageBox* messageBox = new QMessageBox(this);

                  and let Qt automatically delete it when "this" goes out of scope. This follows the RAII principle.

                  N 1 Reply Last reply
                  0
                  • kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by
                    #9

                    Hello,
                    Are you sure that this stack trace corresponds to the particular example code?
                    These two lines:

                    #18 Qt5Cored.dll!QSortFilterProxyModel::mapToSource +0x2ca891 (0x66a26b47 <Qt5Cored.dll+0x2e6b47>)
                    #19 Qt5Cored.dll!QSortFilterProxyModel::mapToSource +0x3e9a42 (0x66b45cf8 <Qt5Cored.dll+0x405cf8>)
                    

                    are most certainly very suspicious. I wouldn't expect a message box to have anything to do with any of the model classes. That said, I don't believe you can have a modal dialog as a main window, it makes no sense - it should be modal to what? Maybe simply try showing it as you would any other ordinary widget, i.e:

                    int main(int argc, char ** argv)
                    {
                        QApplication app(argc, argv); // application object manages everything
                    
                        QMessageBox messageBox;
                        messageBox.setWindowTitle("My Message");
                        messageBox.setText("Hello World");
                        messageBox.show();
                    
                        return QApplication::exec();
                    }
                    

                    Kind regards.

                    Read and abide by the Qt Code of Conduct

                    N 1 Reply Last reply
                    0
                    • M mjsurette

                      Normal practice is to construct with an argument

                      QMessageBox* messageBox = new QMessageBox(this);

                      and let Qt automatically delete it when "this" goes out of scope. This follows the RAII principle.

                      N Offline
                      N Offline
                      NigelMcFarlane
                      wrote on last edited by
                      #10

                      @mjsurette
                      Thank you for your reply, I did not know that Qt objects were smart pointers in this way.
                      Regards
                      Nigel

                      1 Reply Last reply
                      0
                      • kshegunovK kshegunov

                        Hello,
                        Are you sure that this stack trace corresponds to the particular example code?
                        These two lines:

                        #18 Qt5Cored.dll!QSortFilterProxyModel::mapToSource +0x2ca891 (0x66a26b47 <Qt5Cored.dll+0x2e6b47>)
                        #19 Qt5Cored.dll!QSortFilterProxyModel::mapToSource +0x3e9a42 (0x66b45cf8 <Qt5Cored.dll+0x405cf8>)
                        

                        are most certainly very suspicious. I wouldn't expect a message box to have anything to do with any of the model classes. That said, I don't believe you can have a modal dialog as a main window, it makes no sense - it should be modal to what? Maybe simply try showing it as you would any other ordinary widget, i.e:

                        int main(int argc, char ** argv)
                        {
                            QApplication app(argc, argv); // application object manages everything
                        
                            QMessageBox messageBox;
                            messageBox.setWindowTitle("My Message");
                            messageBox.setText("Hello World");
                            messageBox.show();
                        
                            return QApplication::exec();
                        }
                        

                        Kind regards.

                        N Offline
                        N Offline
                        NigelMcFarlane
                        wrote on last edited by
                        #11

                        @kshegunov
                        Thank you for reply.
                        I don't think the error list actually represents a stack trace in any way, though I agree that the list of classes involved is strange.

                        Now I know these "errors" were a red herring in terms of my larger application crashing; they seem to be harmless, possibly an artefact of Dr Memory or my Windows installation, and I guess not of great general interest. If I get a moment I might try running a different memory tool for comparison.
                        Thank you
                        Best regards
                        Nigel

                        kshegunovK 1 Reply Last reply
                        0
                        • N NigelMcFarlane

                          @kshegunov
                          Thank you for reply.
                          I don't think the error list actually represents a stack trace in any way, though I agree that the list of classes involved is strange.

                          Now I know these "errors" were a red herring in terms of my larger application crashing; they seem to be harmless, possibly an artefact of Dr Memory or my Windows installation, and I guess not of great general interest. If I get a moment I might try running a different memory tool for comparison.
                          Thank you
                          Best regards
                          Nigel

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on last edited by kshegunov
                          #12

                          @NigelMcFarlane
                          Hello,

                          Thank you for your reply, I did not know that Qt objects were smart pointers in this way.

                          QObjects are smart in many ways, they can and will make your life easier in multitude of cases, but one should know when and how to use them cleverly. I will argue what @mjsurette suggested, namely this:

                          Normal practice is to construct with an argument
                          QMessageBox* messageBox = new QMessageBox(this);
                          and let Qt automatically delete it when "this" goes out of scope. This follows the RAII principle.

                          to be a bad advice! It is true that your QWidget (this is supposed to be a QWidget in this case) will free the message box in its destructor, however you're delegating responsibility for a local variable to the global scope (not program-global, but class-global). What happens to the message box when you give it a parent is that it's added to the list of children of your widget. Putting aside the visual implications (as children are shown only inside their parent widget) you're creating an (almost) dangling object - you lose the ability to manipulate and/or delete it as soon as your function goes out of scope. In many cases this isn't a problem for objects that are in actuality expected to persist in memory (i.e. creating a layout for a widget), because naturally the widget takes ownership of the layout and uses it to display itself, unfortunately this is not the case here. Suppose you have that code in a function and that function is called a 100 times, this code leads to 100 QMessageBox objects just waiting in the children list to be deleted some day when the parent has been destroyed. Since most QWidget instances persist through the whole lifetime of your application this simply means that the memory is freed when your application exits. Remember neither Qt nor C++ is Java! Another point is that a QObject is already dragging along a heap allocation for its private object (the PIMPL idiom is used throughout Qt), so there is not really a good reason to use heap allocations for local variables, the stack is faster, more robust and less error-prone. The RAII comment is just plainly wrong, since any local stack variable does not break RAII by design. When the stack is unwinding the local object's destructor will be called and memory freed, it doesn't matter whether the reason was an exception being thrown or the function going out of scope. Since message boxes are mostly modal the best way is to use:

                          QMessageBox messageBox;
                          messageBox.setText("Some text");
                          // ... More initialization
                          
                          messageBox.exec(); //< This waits for the user input and returns when the message box is closed.
                          // .. Handle here the return value of `QMessageBox::exec` 
                          

                          Another option is to use one of the pre-made static functions available for the QMessageBox class, which would be my preferred choice. However, as I said in my previous comment, this is a bit different when you use the message box as a top-level window (no parent, defined in main), because you don't have the QApplication's event loop running when show()/exec() is called.

                          Back to the original issue

                          The lines I cited do look like a stack trace and don't correspond to the actual code provided, hence @raven-worx's frustration that I share. If I had to guess what the problem is, my suggestion is to check your memory allocation/freeing, as this heap problems occur often on double delete or dereferencing dangling pointer, but no one can say for sure without a code to check against, or at least look upon. If your application is crashing, rely on the debugger to provide the relevant information - where and why this occurred, and not memory inspection tools, they will not give you the answer. If you're instead tracing a (possible) memory leak, then you could try them.

                          PS. This got a bit lengthy, but I hope is helpful.

                          Kind regards.

                          Read and abide by the Qt Code of Conduct

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

                            @kshegunov
                            Hello,
                            The report is definitely from the small QMessageBox program. If it's impossible that Qt could be calling these routines from this program, it suggests that the output of Dr Memory is not reliable, at least on my installation.

                            I set the program to run under VLD and this reported no leaks, which also suggests a problem with Dr Memory.

                            Regarding the "smart pointers" issue: if I do not delete the QMessageBox, vld reports it as a memory leak.
                            Best regards
                            Nigel

                            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