Menu

#1638 Crash when resizing segment

None
closed
matrix (65)
5
2022-06-14
2022-05-24
No

Crash when resizing segment in main window, but only if Matrix Editor is open with velocity (or other?) ruler shown. Seems to be similar to ancient Bug#655 but stacktrace is different. Because crash requires a very specific set of conditions to trigger I doubt if there's much point in addressing it this late in the 2022.06 release cycle, but am filing this report for future reference. Note also that crash is very consistent across a wide span of code versions, including pre-2022.06 [329ab4] and [52c2f9], 2021.12, and my own repo's pre-merge-request branch with significant changes in src/gui/editors/*.{cpp,h}.

Steps to recreate:
1. New RG document.
2. Create one measure long segment.
3. Open in Matrix Editor (does not crash if no editor, or only Notation Editor is open).
4. Show Velocity Ruler (no crash if not).
5. Set grid to 1/4 notes.
6. Create two 1/4 notes, one each on first and fourth beat of measure (pitch unimportant).
7. Return to main window leaving Matrix Editor open.
8. Resize tool. Resize segment from end by one beat so is 3 beats long.
9. Resize segment from beginning so is 2 beats long.
10. Crash. (Resizing must be done in steps 8 and 9 order as described.)

Stack trace:

(gdb) where 10
#0  0x00007ffff36ac3d6 in __dynamic_cast () at /usr/lib64/libstdc++.so.6
#1  0x00000000009ffac0 in Rosegarden::PropertyControlItem::update() ()
#2  0x00000000007a25bc in Rosegarden::ControlRuler::notationLayoutUpdated(long, long) ()
#3  0x00000000007b0683 in Rosegarden::ControlRulerWidget::slotUpdateRulers(long, long) ()
#4  0x00007ffff57b1d1f in QMetaObject::activate(QObject*, int, int, void**) ()
    at /usr/lib64/libQt5Core.so.5
#5  0x00000000004a580b in Rosegarden::Segment::contentsChanged(long, long) ()
#6  0x00000000004d65fa in Rosegarden::BasicCommand::execute() ()
#7  0x0000000000959b9d in Rosegarden::MacroCommand::execute() ()
#8  0x00000000004ebea8 in Rosegarden::CommandHistory::addCommand(Rosegarden::Command*) ()
#9  0x00000000006d8fab in Rosegarden::SegmentResizer::mouseReleaseEvent(QMouseEvent*) ()
(More stack frames follow...)

Code:

void PropertyControlItem::update()
{
    if (!m_element) return;
    // RulerScale *rulerScale = m_controlRuler->getRulerScale();    
    double x0,x1;

    long val = 0;    
    MatrixElement *matrixelement = dynamic_cast<MatrixElement*>(m_element);
    if (matrixelement) {
       ...

On crashing, m_elementis not nullptr but is pointing to a non-MatrixElement* memory location, thus crashes trying to find the vtable for the dynamic_cast. This is one of the many areas of the RG codebase I'm not familiar with, so hoping someone with more knowledge can look into it at some point. On casual inspection it's curious that a method named "notationLayoutUpdated" is calling code which casts to a MatrixElement, but that's probably not the problem.

Related

Commit: [329ab4]
Commit: [52c2f9]

Discussion

  • Yves Guillemot

    Yves Guillemot - 2022-05-24

    This crash seems related to velocity ruler and not to matrix.
    It can be reproduced with a notation editor window as well:
    1. New RG document.
    2. Create four bars long segment.
    3. Open in Notation Editor.
    4. Show Velocity Ruler.
    5. Create one quarter note on first beat of bar 4.
    6. Return to main window leaving Notation Editor open.
    7. Resize tool. Resize segment from end by one bar.
    8. Crash.

    (gdb) bt
    #0  0x00007f73494df444 in __dynamic_cast () from /lib64/libstdc++.so.6
    #1  0x00007f734bb05a7f in Rosegarden::PropertyControlItem::update (this=0x15f9740) at /home/home.mg6/yves/workspace/rosegarden-yg.git/src/gui/rulers/PropertyControlItem.cpp:55
    #2  0x00007f734badefd0 in Rosegarden::ControlRuler::notationLayoutUpdated (this=0x15e16f0, startTime=0)
        at /home/home.mg6/yves/workspace/rosegarden-yg.git/src/gui/rulers/ControlRuler.cpp:461
    #3  0x00007f734baf8d47 in Rosegarden::ControlRulerWidget::slotUpdateRulers (this=0x11f17d0, startTime=0, endTime=11520)
        at /home/home.mg6/yves/workspace/rosegarden-yg.git/src/gui/rulers/ControlRulerWidget.cpp:585
    #4  0x00007f734b8d3084 in QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1>, QtPrivate::List<long, long>, void, void (Rosegarden::ControlRulerWidget::*)(long, long)>::call (
        f=
        (void (Rosegarden::ControlRulerWidget::*)(Rosegarden::ControlRulerWidget * const, long, long)) 0x7f734baf8cb8 <Rosegarden::ControlRulerWidget::slotUpdateRulers(long, long)>, o=0x11f17d0, arg=0x7fffd0718a20) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:152
    #5  0x00007f734b8d27e4 in QtPrivate::FunctionPointer<void (Rosegarden::ControlRulerWidget::*)(long, long)>::call<QtPrivate::List<long, long>, void> (f=
        (void (Rosegarden::ControlRulerWidget::*)(Rosegarden::ControlRulerWidget * const, long, long)) 0x7f734baf8cb8 <Rosegarden::ControlRulerWidget::slotUpdateRulers(long, long)>, o=0x11f17d0, arg=0x7fffd0718a20) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:185
    #6  0x00007f734b8d1ef4 in QtPrivate::QSlotObject<void (Rosegarden::ControlRulerWidget::*)(long, long), QtPrivate::List<long, long>, void>::impl (which=1, this_=0x1259c90, 
        r=0x11f17d0, a=0x7fffd0718a20, ret=0x0) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:418
    #7  0x00007f7349eada74 in void doActivate<false>(QObject*, int, void**) () from /lib64/libQt5Core.so.5
    #8  0x00007f734b6311fd in Rosegarden::NotationScene::layoutUpdated (this=0x1205900, _t1=0, _t2=11520)
        at /home/home.mg6/yves/workspace/rosegarden-yg.git/BUILD.debug/src/rosegardenprivate_autogen/XVAGPESQ7F/moc_NotationScene.cpp:268
    #9  0x00007f734b93f370 in Rosegarden::NotationScene::layout (this=0x1205900, singleStaff=0x0, startTime=0, endTime=11520)
        at /home/home.mg6/yves/workspace/rosegarden-yg.git/src/gui/editors/notation/NotationScene.cpp:1877
    #10 0x00007f734b93ebf3 in Rosegarden::NotationScene::layoutAll (this=0x1205900)
        at /home/home.mg6/yves/workspace/rosegarden-yg.git/src/gui/editors/notation/NotationScene.cpp:1763
    #11 0x00007f734b93bebc in Rosegarden::NotationScene::checkUpdate (this=0x1205900)
        at /home/home.mg6/yves/workspace/rosegarden-yg.git/src/gui/editors/notation/NotationScene.cpp:1221
    (...)
    
     
  • Philip Leishman

    Philip Leishman - 2022-05-24

    It seems that if a segment is resized (made smaller) Notes after the (new) end of the segment are not erased ! If you resize back to the original size the note is still there.
    This seems to be very odd behavior. Surely the note must be deleted ????

     
  • Philip Leishman

    Philip Leishman - 2022-05-24

    Well maybe that is just the way it works!!
    However the observers were not being informed about the items disappearing. If I add a notifyRemove call for these elements in ViewSegment::endMarkerTimeChanged I believe the crash disappears. However on lengthening again the Velocity items do not come back.
    I can work on this one !

     
  • Philip Leishman

    Philip Leishman - 2022-05-24
    • assigned_to: Philip Leishman
     
  • Yves Guillemot

    Yves Guillemot - 2022-05-24

    It seems that if a segment is resized (made smaller) Notes after the (new) end of the segment are not erased ! If you resize back to the original size the note is still there.

    It's how it works.
    Similarly entire segments can be hidden if the duration of the composition is reduced then recovered when it is reset to its initial value.

    Nevertheless I just discover there is an asymmetry when a segment is resized:
    Resizing a segment by its end doesn't remove events.
    Resizing a segment by its start removes events.

    This is certainly related to the existence of an end marker in each segment while there is no start marker. We are living with it since years and this is not a real problem, but it would be better to have a more symmetrical behaviour.

     
  • Philip Leishman

    Philip Leishman - 2022-05-24

    So I have a fix which tells the ViewSegmentObservers the notes are deleted or created when the segment is resized (although they are not really deleted and created) !
    I think the events after the end marker are effectively gone so this should not cause any problems.
    See merge request.

     
  • Philip Leishman

    Philip Leishman - 2022-05-25

    Right. I was always a bit unsure what EndTime and EndMarkerTime really mean. Thanks for the explanation Yves. Actually reading the comments for the methods helps too ;)
    The asymmetry is maybe a little annoying but, as you say, we are living with it and I wouldn't change that !

     
  • Ted Felix

    Ted Felix - 2022-05-30
    • labels: --> matrix
    • status: open --> feedback
     
  • Ted Felix

    Ted Felix - 2022-05-30

    Pushed as [30de58]. Please test latest git.

    I fixed what appears to be a memory leak:

    ViewElement* newEl = makeViewElement(*j);
    m_viewElementList->insert(makeViewElement(*j));
    notifyAdd(newEl);
    

    The ViewElement created by the first call to makeViewElement() is lost. Fixed version:

    // Create a new ViewElement and add.
    ViewElement *newElement = makeViewElement(*j);
    m_viewElementList->insert(newElement);
    notifyAdd(newElement);
    

    Let me know if that is wrong. Thanks.

     

    Related

    Commit: [30de58]


    Last edit: Ted Felix 2022-05-30
  • Philip Leishman

    Philip Leishman - 2022-05-30

    Yes, sorry, that was what I intended !!
    Thanks for catching that

     
    👍
    1
  • Ted Felix

    Ted Felix - 2022-06-14
    • status: feedback --> closed
     

Log in to post a comment.