Crash on opening a score with a staff type change and multimeasure rests enabled

• Feb 25, 2022 - 17:51
Reported version
3.6
Type
Functional
Frequency
Once
Severity
S2 - Critical
Reproducibility
Always
Status
closed
Regression
No
Workaround
Yes
Project
  1. Take score staff-type-change.mscx
  2. Enable multimeasure rests

> CRASH

If not there then:
3. Save
4. Close
5. Reopen

> CRASH

Or

  1. Open staff-type-change+multimeasure-rests.mscx

> CRASH

Difference between the two scores:
diff.png

Workaround: before enabling multi measure rests add a staff text (or anything that prevents it from becomming part of the multimeasure rest) at the staff type change.

Stack trace:
1 ntdll!RtlIsZeroMemory 0x7fff0b9cc033
2 ntdll!.misaligned_access 0x7fff0b9d4e92
3 ntdll!.misaligned_access 0x7fff0b9d517a
4 ntdll!.misaligned_access 0x7fff0b9df665
5 ntdll!RtlGetCurrentServiceSessionId 0x7fff0b8e8365
6 ntdll!RtlFreeHeap 0x7fff0b8e7631
7 msvcrt!free 0x7fff0a7dc6ac
8 Ms::StaffType::~StaffType stafftype.h 277 0xf5767e
9 Ms::Measure::add measure.cpp 943 0xa29ce8
10 Ms::Score::createMMRest layout.cpp 2273 0x9fee99
11 Ms::Score::getNextMeasure layout.cpp 3010 0xa02ec8
12 Ms::Score::collectSystem layout.cpp 3937 0xa08b1d
13 Ms::Score::doLayoutRange layout.cpp 5167 0xa107a5
14 Ms::Score::update cmd.cpp 302 0x536fa8
15 Ms::Score::update score.h 756 0xf3a58a
16 Ms::readScore file.cpp 2437 0x4cd181
17 Ms::MuseScore::readScore file.cpp 474 0x4bd4cc
18 Ms::MuseScore::openScore file.cpp 416 0x4bcf8c
19 Ms::MuseScore::doLoadFiles file.cpp 349 0x4bc6d3
20 Ms::MuseScore::openFiles file.cpp 314 0x4bc31c

That is in the destructor for that Staff Type change (virtual ~StaffType() {}) and during the handling of multi measure rests (in void Score::createMMRest(Measure m, Measure lm, const Fraction& len))

Crashes MuseScore 4 too BTW.


Comments

Very simple fix:

diff --git a/libmscore/measure.cpp b/libmscore/measure.cpp
index c2405df305..12b2a848b1 100644
--- a/libmscore/measure.cpp
+++ b/libmscore/measure.cpp
@@ -940,7 +940,6 @@ void Measure::add(Element* e)
                         // we won't need the original after that
                         // this requires that st was allocated via new to begin with!
                         nst = staff->setStaffType(tick(), *st);
-                        delete st;
                         }
                   else {
                         // executed on add from palette

but probably over-simplistic and possibly causing a memory leak?

Fix version
4.0.0