Musescore 3.5.2 crashes when creating parts if a vertical frame includes a horizontal frame with text

• Nov 28, 2020 - 14:34
Reported version
3.5
Priority
P1 - High
Type
Functional
Frequency
Once
Severity
S2 - Critical
Reproducibility
Always
Status
closed
Regression
Yes
Workaround
No
Project

Steps to reproduce the issue:
1) Create a new score with at least two instruments (e.g. Voice + Piano) and default settings;
2) Select the last measure and add a vertical frame after the last bar;
3) Select the vertical frame and add a horizontal frame inside the vertical frame;
4) Select the horizontal frame and add any text inside the horizontal frame;
5) (not required) Save the work;
6) Select File | Parts...
7) Click on "All parts" and "OK";
the application crashes.

Verified with MuseScore 3.5.2 AppImage for Linux (Ubuntu 18.04).
I could not check, but I doubt this happened with 3.5.1 or 3.5.0 because I frequently have this case in my scores.

Attachment Size
bugCreateParts.mscz 8.16 KB

Comments

Crashes without any stack trace, even under Debug. Famos last words:

Debug: no sys staff (...\libmscore\system.cpp:1459, int Ms::System::lastVisibleSysStaff() const)
Debug:  + Add part :  "Voice" (...\mscore\excerptsdialog.cpp:688, void Ms::ExcerptsDialog::createNewExcerpt(Ms::ExcerptItem*))
pure virtual method called

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
terminate called without an active exception

Seem it crashes at
cloneStaves(oscore, score, srcStaves, excerpt->tracks());
when dealing with that last argument
<QMultiMap<int, int>& tracks()                  { return _tracks;    }
At least that's where I got stuck for now

It looked a bit different for me, but also confusing. My best read is the problem wasn't where the crash occurred, but in how the data got to the state it was in. At one point, the crash appeared to be in some MeasureBase functions that were not overridden by any Box or Measure function but should have been - like a pure virtual function being called. But the data I saw just didn't make sense.

My guess is this somehow broke with my fix for #307841: Bad behavior of text added in a horizontal frame included in a vertical frame that can lead to a crash - which is to say, at 3.5.1. But I would also guess it only "accidentally" worked before, because really, the state of things with horizontal frames inside vertical frames was quite messed up.

Thanks for the confirmation! So it pretty much has to be connected to the fix I referred to above - previously horizontal frames were not correctly being added to the score data structure, now they are, and somehow there must be coding relying on the old error, or something wrong with how some of this is implemented. I'm not having much luck understanding what the debugger is telling me, unfortunately. So I'm trying to enlist some help on this.

Status PR created fixed

Fixed in branch 3.x, commit 20c2ad1bb6

_fix #313704: crash generating parts with text/hbo/vbox

Resolves: https://musescore.org/en/node/313704

Crash happens if you have a text within an hbox within a vbox,
and then you create parts.
The crash appears to happen because while cloning the hbox,
(so within the copy constructor), we call triggerLlayout,
but the hbox isn't fully constructed.
It's actually more complex than that -
it turns out we are within the MeasureBase constructor
and as far as the compiler knows that's the object type -
it doesn't realize we actually are trying to construct an HBox.
Probably there is some more clever C++-ism to solve this.
But, my solution here is not so esteric.

In MeasureBase::triggerLayout(), we are already checking top()
to get the top-level measure base so we can check
that it has been added to the measurebase list for the score.
In this case, that is the Vbox containing the HBox.
And luckily, that seems to be fully constructed -
or at least, constructed enough that we don't crash.

So the fix is simply to send "mb" instead of "this"
as the third parameter to Score::setLayout()
from withing MeasureBase::triggerLayout().

It's totally safe and seems to fix the problem.
I can't swear that means I totally understand all the intricacies
or guarantee there aren't other problems lurking.
But I'm pretty sure this improves the situation._

Fix version
3.6.0