[Issue #4755] Copying a section view segfaults

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

[Issue #4755] Copying a section view segfaults

Post by SIXe »

When trying to copy a section view to another page, FC segfaults. Steps to reproduce:

- create simple graphic
- create TD page
- create section view
- create another TD page
- create another section view
- drag and drop the view to the ProjGroup of the 2nd page

Code: Select all

Program received signal SIGSEGV, Segmentation fault.
  /tmp/.mount_FreeCAMuoQyh/AppRun: line 41: 354130 Segmentation fault      ${MAIN} "$@"
I don't know if this is not supported, but even in case it's not, FC should not segfault. Example file and screencast attached.

OS: Debian GNU/Linux 11 (bullseye) (X-Cinnamon/lightdm-xsession)
Word size of FreeCAD: 64-bit
Version: 0.20.25645 (Git) AppImage
Build type: Release
Branch: master
Hash: 37d9757399b4c2ec30318eb88d7cd7c508246345
Python version: 3.9.7
Qt version: 5.12.9
Coin version: 4.0.0
OCC version: 7.5.2
Locale: English/United Kingdom (en_GB)
Attachments
section_view_segfault.webm
(771.86 KiB) Downloaded 41 times
copy_section_view.FCStd
(16.1 KiB) Downloaded 41 times
Last edited by SIXe on Mon Sep 27, 2021 7:24 pm, edited 1 time in total.
wmayer
Founder
Posts: 20242
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Copying a section view segfaults

Post by wmayer »

Confirmed. It crashes inside the function TechDrawGui::QGVPage::removeQView at line 288:

Code: Select all

int QGVPage::removeQView(QGIView *view)
{
    if (view != nullptr) {
        removeQViewFromScene(view);
        delete view; // <<<=========  BOOM!!!
    }
    return 0;
}
view might be a dangling pointer.
SIXe
Posts: 153
Joined: Sat Mar 16, 2019 3:10 pm

Re: Copying a section view segfaults

Post by SIXe »

Thanks for confirming.

issue #4755

edit: change tag
Last edited by SIXe on Mon Sep 27, 2021 7:23 pm, edited 1 time in total.
openBrain
Veteran
Posts: 9034
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: Copying a section view segfaults

Post by openBrain »

SIXe wrote: Mon Sep 27, 2021 7:02 pm Thanks for confirming.

https://tracker.freecadweb.org/view.php?id=4755
Could you please :
* Use the <bug> tag instead of hard link
* Prepend the title of the thread with "[Issue #4755]"
Thx
SIXe
Posts: 153
Joined: Sat Mar 16, 2019 3:10 pm

Re: Copying a section view segfaults

Post by SIXe »

openBrain wrote: Mon Sep 27, 2021 7:20 pm * Use the <bug> tag instead of hard link
* Prepend the title of the thread with "[Issue #4755]"
done
openBrain
Veteran
Posts: 9034
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: Copying a section view segfaults

Post by openBrain »

SIXe wrote: Mon Sep 27, 2021 7:25 pm done
Thanks
wmayer
Founder
Posts: 20242
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: [Issue #4755] Copying a section view segfaults

Post by wmayer »

This change seems to fix the crash:

Code: Select all


//this is time consuming. should only be used when there is a problem.
void MDIViewPage::fixOrphans(bool force)
{
    if(!force) {
        m_timer->start(100);
        return;
    }
    m_timer->stop();

    // get all the DrawViews for this page, including the second level ones
    // if we ever have collections of collections, we'll need to revisit this
    TechDraw::DrawPage* thisPage = m_vpPage->getDrawPage();

    if(!thisPage->getNameInDocument())
        return;

    std::vector<App::DocumentObject*> pChildren  = thisPage->getAllViews();

    // if dv doesn't have a graphic, make one
    for (auto& dv: pChildren) {
        if (dv->isRemoving()) {
            continue;
        }
        QGIView* qv = m_view->findQViewForDocObj(dv);
        if (qv == nullptr) {
            attachView(dv);
        }
    }

    // if qView doesn't have a Feature on this Page, delete it
    std::vector<QGIView*> qvss = m_view->getViews();
    std::vector<QPointer<QGIView>> qvs;
    std::for_each(qvss.begin(), qvss.end(), [&](QGIView* v){ qvs.emplace_back(v); });
    App::Document* doc = getAppDocument();
    for (auto& qv: qvs) {
        if (!qv)
            continue; // already deleted?
        App::DocumentObject* obj = doc->getObject(qv->getViewName());
        if (obj == nullptr) {
            m_view->removeQView(qv);
        } else {
            TechDraw::DrawPage* pp = qv->getViewObject()->findParentPage();
            /** avoid crash where a view might have more than one parent page
             * if the user duplicated the page without duplicating dependencies
             */
            int numParentPages = qv->getViewObject()->countParentPages();
            if (thisPage != pp && numParentPages == 0) {
               m_view->removeQView(qv);
            }
        }
    }
}
The problem is that qvss contains several items and when deleting one of them it could cause to delete a child item that is also inside qvss and this leads to the double-deletion. To fix it a QPointer is needed because it gets notified when the handled object is deleted.
wmayer
Founder
Posts: 20242
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: [Issue #4755] Copying a section view segfaults

Post by wmayer »

git commit 83ac792fb4 fixes the crash.

However, there is a second problem: when drag and drop the Section object to the ProjGroup001 then it suddenly jumps out of the Page001.
chrisb
Veteran
Posts: 53920
Joined: Tue Mar 17, 2015 9:14 am

Re: [Issue #4755] Copying a section view segfaults

Post by chrisb »

Drag and drop with pages behaves similar to jobs: weird things happen.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
Post Reply