[FIXED] Section view causes segfault

Discussions about the development of the TechDraw workbench
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
SIXe
Posts: 160
Joined: Sat Mar 16, 2019 3:10 pm

[FIXED] Section view causes segfault

Post by SIXe »

Hi,

FreeCAD reproducibly crashes when using the TechDraw workbench. Steps to reproduce:

- open attached file
- select TD workbench
- Edit → Preferences → TechDraw → HLR → Show Hard Lines (ticked)
- select bottom view
- insert section view
- click first cut (horizontal)
- click on the “down” arrow on the “Scale” parameter
→ segfault

screenshot.png
screenshot.png (222.48 KiB) Viewed 1435 times

Code: Select all

Program received signal SIGSEGV, Segmentation fault.
#0  /lib/x86_64-linux-gnu/libc.so.6(+0x37840) [0x7f48b505e840]
#1  0x7f48421dd93a in TechDrawGui::QGIViewPart::drawFace(TechDraw::Face*, int) from /tmp/.mount_FreeCA4I9FXC/usr/lib/TechDrawGui.so+0x14a
#2  0x7f48421e147b in TechDrawGui::QGIViewSection::drawSectionFace() from /tmp/.mount_FreeCA4I9FXC/usr/lib/TechDrawGui.so+0x31b
#3  0x7f48421e1b09 in TechDrawGui::QGIViewSection::updateView(bool) from /tmp/.mount_FreeCA4I9FXC/usr/lib/TechDrawGui.so+0x69
#4  /tmp/.mount_FreeCA4I9FXC/usr/lib/./TechDraw.so(+0x116d6a) [0x7f4840666d6a]
#5  0x7f48406686c7 in TechDraw::DrawView::execute() from /tmp/.mount_FreeCA4I9FXC/usr/lib/./TechDraw.so+0x27
#6  0x7f48406b0351 in TechDraw::DrawViewSection::execute() from /tmp/.mount_FreeCA4I9FXC/usr/lib/./TechDraw.so+0x1e1
#7  0x7f48b6e12ea2 in App::DocumentObject::recompute() from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libFreeCADApp.so+0xf2
#8  0x7f48b6da506c in App::Document::_recomputeFeature(App::DocumentObject*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libFreeCADApp.so+0x31c
#9  0x7f48b6dff58c in App::Document::recomputeFeature(App::DocumentObject*, bool) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libFreeCADApp.so+0xdc
#10  0x7f4842156793 in TechDrawGui::TaskSectionView::applyQuick(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) from /tmp/.mount_FreeCA4I9FXC/usr/lib/TechDrawGui.so+0x73
#11  0x7f4842156d4e in TechDrawGui::TaskSectionView::apply() from /tmp/.mount_FreeCA4I9FXC/usr/lib/TechDrawGui.so+0xae
#12  0x7f48b55720d2 in QMetaObject::activate(QObject*, int, int, void**) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Core.so.5+0x780
#13  0x7f48b7cb3af4 in Gui::QuantitySpinBox::valueChanged(double) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libFreeCADGui.so+0x44
#14  0x7f48b7cb5227 in Gui::QuantitySpinBox::updateFromCache(bool) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libFreeCADGui.so+0xb7
#15  0x7f48b7cb6a0d in Gui::QuantitySpinBox::stepBy(int) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libFreeCADGui.so+0x14d
#16  /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Widgets.so.5(+0x27b74e) [0x7f48b5e8d74e]
#17  0x7f48b5e8d923 in QAbstractSpinBox::mousePressEvent(QMouseEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Widgets.so.5+0x9d
#18  0x7f48b5db1c0f in QWidget::event(QEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Widgets.so.5+0x121
#19  0x7f48b5e90457 in QAbstractSpinBox::event(QEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Widgets.so.5+0xc9
#20  0x7f48b5d8683a in QApplicationPrivate::notify_helper(QObject*, QEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Widgets.so.5+0xde
#21  0x7f48b5d8b0a9 in QApplication::notify(QObject*, QEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Widgets.so.5+0x79d
#22  0x7f48b789d0c9 in Gui::GUIApplication::notify(QObject*, QEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libFreeCADGui.so+0x89
#23  0x7f48b555ba9c in QCoreApplication::notifyInternal2(QObject*, QEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Core.so.5+0x88
#24  0x7f48b5d8a553 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Widgets.so.5+0x283
#25  /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Widgets.so.5(+0x1af580) [0x7f48b5dc1580]
#26  /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Widgets.so.5(+0x1b03d2) [0x7f48b5dc23d2]
#27  0x7f48b5d8683a in QApplicationPrivate::notify_helper(QObject*, QEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Widgets.so.5+0xde
#28  0x7f48b5d8c405 in QApplication::notify(QObject*, QEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Widgets.so.5+0x1af9
#29  0x7f48b789d0c9 in Gui::GUIApplication::notify(QObject*, QEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libFreeCADGui.so+0x89
#30  0x7f48b555ba9c in QCoreApplication::notifyInternal2(QObject*, QEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Core.so.5+0x88
#31  0x7f48b5902724 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Gui.so.5+0x684
#32  0x7f48b59032f7 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Gui.so.5+0x175
#33  0x7f48b58f0020 in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Gui.so.5+0x64
#34  /tmp/.mount_FreeCA4I9FXC/usr/plugins/platforms/../../lib/libQt5XcbQpa.so.5(+0x5b1ea) [0x7f48b127f1ea]
#35  /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/./libglib-2.0.so.0(g_main_context_dispatch+0x2cb) [0x7f48b24d2dab]
#36  /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/./libglib-2.0.so.0(+0x54ff1) [0x7f48b24d2ff1]
#37  /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/./libglib-2.0.so.0(g_main_context_iteration+0x2e) [0x7f48b24d307e]
#38  0x7f48b558ad23 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Core.so.5+0x63
#39  0x7f48b55584d7 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Core.so.5+0x187
#40  0x7f48b555c34f in QCoreApplication::exec() from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libQt5Core.so.5+0x105
#41  0x7f48b78134f2 in Gui::Application::runApplication() from /tmp/.mount_FreeCA4I9FXC/usr/bin/../lib/libFreeCADGui.so+0x15a2
#42  /tmp/.mount_FreeCA4I9FXC/usr/bin/freecad(+0x37cd) [0x55a8fcd537cd]
#43  /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xeb) [0x7f48b504b09b]
#44  /tmp/.mount_FreeCA4I9FXC/usr/bin/freecad(+0x4521) [0x55a8fcd54521]

Code: Select all

OS: Debian GNU/Linux 10 (buster) (X-Cinnamon/lightdm-xsession)
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19.22665 (Git) AppImage
Build type: Release
Branch: master
Hash: b0d7850406e046f3b7a8cd5da261e7d54df6bd99
Python version: 3.8.6
Qt version: 5.12.9
Coin version: 4.0.0
OCC version: 7.4.0
Locale: English/Ireland (en_IE)
Attachments
segfault-section-view.FCStd
(139.72 KiB) Downloaded 51 times
Last edited by Kunda1 on Thu Oct 15, 2020 1:28 pm, edited 2 times in total.
Reason: Added [Fixed] to thread title
chrisb
Veteran
Posts: 54313
Joined: Tue Mar 17, 2015 9:14 am

Re: Section view causes segfault

Post by chrisb »

It works here (using OSX). The view collapses as expected, because the scale is 0. As it is not sensible to have a scale of zero this could - if possible - be prohibited thus probably avoiding the crash. It is already now impossible to enter negative values.

OS: macOS 10.15
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19.22611 (Git)
Build type: Release
Branch: master
Hash: 7eeec7a5990cc786723225ca8de16ca3186545b3
Python version: 3.8.5
Qt version: 5.12.9
Coin version: 4.0.0
OCC version: 7.4.0
Locale: C/Default (C)
Attachments
Snip macro screenshot-c542e9.png
Snip macro screenshot-c542e9.png (8.21 KiB) Viewed 1425 times
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
wmayer
Founder
Posts: 20324
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Section view causes segfault

Post by wmayer »

wandererfan wrote: ping
I don't get this crash either but when looking at the code of QGIViewPart::drawFace() there are several places where it can crash.

Code: Select all


QGIFace* QGIViewPart::drawFace(TechDraw::Face* f, int idx)
{
//    Base::Console().Message("QGIVP::drawFace - %d\n", idx);
    std::vector<TechDraw::Wire *> fWires = f->wires; /// <<<<<<<<< f could be a null pointer but this situation might be excluded by the program logic
    QPainterPath facePath;
    for(std::vector<TechDraw::Wire *>::iterator wire = fWires.begin(); wire != fWires.end(); ++wire) {
        QPainterPath wirePath;
        std::vector<TechDraw::BaseGeom*> geoms = (*wire)->geoms; // <<<< same here
        TechDraw::BaseGeom* firstGeom = geoms.front(); // <<<<<<<<<<<<<<<<<<<< Is it guaranteed that the vector is not empty? If not this causes a crash
        //QPointF startPoint(firstGeom->getStartPoint().x, firstGeom->getStartPoint().y);
        //wirePath.moveTo(startPoint);
        QPainterPath firstSeg = drawPainterPath(firstGeom);
        wirePath.connectPath(firstSeg);
        for(std::vector<TechDraw::BaseGeom *>::iterator edge = ((*wire)->geoms.begin()) + 1; edge != (*wire)->geoms.end(); ++edge) {
            QPainterPath edgePath = drawPainterPath(*edge);
            //handle section faces differently
            if (idx == -1) {
                    QPointF wEnd = wirePath.currentPosition();
                    auto element = edgePath.elementAt(0);
                    QPointF eStart(element.x, element.y);
                    QPointF eEnd = edgePath.currentPosition();
                    QPointF sVec = wEnd - eStart;
                    QPointF eVec = wEnd - eEnd;
                    double sDist2 = sVec.x() * sVec.x() + sVec.y() * sVec.y();
                    double eDist2 = eVec.x() * eVec.x() + eVec.y() * eVec.y();
                    if (sDist2 > eDist2) {
                        edgePath = edgePath.toReversed();
                    }
           }
            wirePath.connectPath(edgePath);
        }
//        dumpPath("wirePath:",wirePath);
        facePath.addPath(wirePath);
    }
    facePath.setFillRule(Qt::OddEvenFill);

    QGIFace* gFace = new QGIFace(idx);  /// <<<<<<<< this function is called from QGIViewPart::drawViewPart() but it never deletes the QGIFace object. See below...
    addToGroup(gFace);
    gFace->setPos(0.0,0.0);
    gFace->setOutline(facePath);
    //debug a path
    //std::stringstream faceId;
    //faceId << "facePath " << idx;
    //dumpPath(faceId.str().c_str(),facePath);

    return gFace;
}
Creating and not destroying the QGIFace causes a serious memory leak. Please change the interface of the method to return a std::unique_ptr instead of raw pointer. This automatically destroys the instance when leaving the calling scope -- even if an exception is raised somewhere.
In case you call this function elsewhere and you want to keep the object alive then use the release() method of std::unique_ptr
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Section view causes segfault

Post by vocx »

SIXe wrote: Fri Oct 09, 2020 9:31 am ...
- click on the “down” arrow on the “Scale” parameter
→ segfault
I cannot reproduce either.

Code: Select all

OS: Ubuntu 18.04.5 LTS (ubuntu:GNOME/ubuntu)
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19.22668 (Git)
Build type: Debug
Branch: master
Hash: 11afaaea68b0795c72c0f2515058b188574a92c1
Python version: 3.6.9
Qt version: 5.9.5
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: English/UnitedStates (en_US)
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
chrisb
Veteran
Posts: 54313
Joined: Tue Mar 17, 2015 9:14 am

Re: Section view causes segfault

Post by chrisb »

SIXe wrote: Fri Oct 09, 2020 9:31 am ping
Your error report is very clear and doesn't leave much room for interpretation (thanks for that). I don't think we had any recent changes in TechDraw, so could you please try to reset the configuration with the button in the preferences. Another possibility is to delete your config files or to move them in case you want to restore them.

If that doesn't help, then vocx could retry with exactly the same version also using a plain vanilla config.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
SIXe
Posts: 160
Joined: Sat Mar 16, 2019 3:10 pm

Re: Section view causes segfault

Post by SIXe »

You're right, I could not reproduce it with a default config. I missed a crucial step in the OP (edited now). To trigger the segfault you'll have to configure:

Edit → Preferences → TechDraw → HLR → Show Hard Lines (ticked)
wmayer
Founder
Posts: 20324
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Section view causes segfault

Post by wmayer »

git commit d75299143 fixes the crash.
Post Reply