[solved]Program crashing when calling QSGGeometryNode::setMaterial()



  • EDIT: The program was crashing because I used the compiler option "-fshort-enums", which doesn't play nice with some component in the QSG part of Qt. When I removed the option, things started working again.

    I'm trying to modify the QSGGeomteryNode bezier curve example to support a custom color for the curve.

    http://qt-project.org/doc/qt-5/qtquick-scenegraph-customgeometry-example.html

    @QSGNode *BezierCurve::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
    {
    QSGGeometryNode *node = 0;
    QSGGeometry *geometry = 0;

    if (!oldNode) {
        node = new QSGGeometryNode;
        geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), m_segmentCount);
        geometry->setLineWidth(2);
        geometry->setDrawingMode(GL_LINE_STRIP);
        node->setGeometry(geometry);
        node->setFlag(QSGNode::OwnsGeometry);
        auto material = new QSGFlatColorMaterial;
        material->setColor(m_strokeColor);
        node->setMaterial(material);
        node->setFlag(QSGNode::OwnsMaterial);
    } else {
        node = static_cast<QSGGeometryNode *>(oldNode);
        geometry = node->geometry();
        geometry->allocate(m_segmentCount);
        QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
        material->setColor(m_strokeColor);
        node->setMaterial(material); //crash here
        node->markDirty(QSGNode::DirtyMaterial);
    }
    
    QRectF bounds = boundingRect();
    QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
    for (int i = 0; i < m_segmentCount; ++i) {
        qreal t = i / qreal(m_segmentCount - 1);
        qreal invt = 1 - t;
    
        QPointF pos = invt * invt * invt * m_p1
                    + 3 * invt * invt * t * m_p2
                    + 3 * invt * t * t * m_p3
                    + t * t * t * m_p4;
    
        float x = bounds.x() + pos.x();// * bounds.width();
        float y = bounds.y() + pos.y();// * bounds.height();
    
        vertices[i].set(x, y);
    }
    node->markDirty(QSGNode::DirtyGeometry);
    
    return node;
    

    }@

    I've added the lines 21-24, which cause the application to crash.

    The debugger shows this:

    @HEAP[nmgui.exe]:
    Heap block at 26058DC8 modified at 26058DE8 past requested size of 18
    HEAP[nmgui.exe]:
    Invalid address specified to RtlFreeHeap( 18740000, 26058DD0 )@

    First stacktrace:
    @0 ntdll!TpWaitForAlpcCompletion C:\Windows\system32\ntdll.dll 0x77af0575
    1 ?? 0x28d2e0
    2 ntdll!RtlLargeIntegerDivide C:\Windows\system32\ntdll.dll 0x77ad57c2
    3 ?? 0x2607dcc8
    4 ntdll!RtlCopyExtendedContext C:\Windows\system32\ntdll.dll 0x77ab2a8a
    5 ?? @

    If I hit continue in the debugger, I get this stacktrace:
    @0 ntdll!TpWaitForAlpcCompletion C:\Windows\system32\ntdll.dll 0x77af0575
    1 ?? 0x28d300
    2 ntdll!RtlCopyExtendedContext C:\Windows\system32\ntdll.dll 0x77ab2aba
    3 ?? 0x26058dc8
    4 ntdll!TpQueryPoolStackInformation C:\Windows\system32\ntdll.dll 0x77af15cf
    5 ?? 0x26058dc8
    6 ntdll!AlpcMaxAllowedMessageLength C:\Windows\system32\ntdll.dll 0x77aaac29
    7 ?? 0x18740000
    8 ntdll!LdrLoadAlternateResourceModuleEx C:\Windows\system32\ntdll.dll 0x77a534a2
    9 ?? 0x26058dc8
    10 msvcrt!free C:\Windows\syswow64\msvcrt.dll 0x774898cd
    11 ?? 0x18740000
    12 QSGFlatColorMaterial::~QSGFlatColorMaterial qsgflatcolormaterial.h 50 0x126a54fe
    13 QSGGeometryNode::setMaterial qsgnode.cpp 946 0x12509a8f
    14 BezierCurve::updatePaintNode beziercurve.cpp 152 0x40928d
    15 QQuickWindowPrivate::updateDirtyNode qquickwindow.cpp 2535 0x12552234
    16 QQuickWindowPrivate::updateDirtyNodes qquickwindow.cpp 2360 0x125514a4
    17 QQuickWindowPrivate::syncSceneGraph qquickwindow.cpp 334 0x1254a690
    18 QSGWindowsRenderLoop::renderWindow qsgwindowsrenderloop.cpp 452 0x1253192d
    19 QSGWindowsRenderLoop::render qsgwindowsrenderloop.cpp 395 0x12531670
    20 QSGWindowsRenderLoop::event qsgwindowsrenderloop.cpp 375 0x12531610
    ... <More> @

    Am I doing something wrong? How can I change material of the line without crashing the application?


  • Lifetime Qt Champion

    Hi,

    @node = static_cast<QSGGeometryNode *>(oldNode);@

    That's dangerous, are you sur oldNode contains somethign valid ?
    You should rather use dynamic_cast plus a null check.

    Hope it helps



  • Yes, this was what I though as well, but it's what's done in the example.

    There is a null check for oldNode, because it will only enter that branch if !oldNode (line 6), which means it's not null.

    I Tried doing a dynamic cast instead, but it didn't make a difference.

    EDIT: The problem seems to be something else. It's still crashing with the original example code, although after I close the window.



  • After hours of commenting out and replacing code in my own project to find what was causing the bug, I think I've finally found it.

    I was using C++11, and apparently some part of Qt doesn't really like that (might also be a compiler bug, but this probably unlikely).

    Having
    @QMAKE_CXXFLAGS += -std=c++11@
    In the .pro file is the only difference between a working and a crashing program.

    EDIT:
    Nope, made a fool of myself again (probably forgot to run qmake or clean when i verified the offending line). std-c++11 was not the problem.

    It is the compiler option -fshort-enums, which tells the compiler to allocate as many bytes as needed for enumerated types. Apparently Qt is not happy with that.


  • Lifetime Qt Champion

    I can't comment about the short-enums problem, but the interest mailing list would be a good starting point for that one.

    On a side note, if you want to use C++11, you can simply add

    @CONFIG += c++11@

    to your pro file


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.