Half duration shortcut crashes musescore when time signature is 5/4

• Jun 18, 2022 - 08:31
Reported version
3.6
Type
Functional
Frequency
Once
Severity
S2 - Critical
Reproducibility
Always
Status
closed
Regression
No
Workaround
No
Project

1) Open musescore and use default empty score
2) Change time signature to 5/4
3) click on the rest note in any bar
4) press Q

in console output you will see:
unknown:unknown: failed to create compose table
/build/musescore/src/MuseScore/libmscore/durationtype.cpp:unknown: ASSERT: "truncate || (fraction() - l).numerator() == 0" in file /build/musescore/src/MuseScore/libmscore/durationtype.cpp, line 438


Comments

Frequency Few Once
Severity S3 - Major S2 - Critical
Status active needs info

(you're all but one, and crashes are critical)
I can't reproduce in 3.6.2 in Windows 11

Status needs info active

I can in a Debug build though. But that is nothing a mere mortal user would/should ever use. The released version os MuseScore, as available from this site's download page, should not have that issue (being build in Release mode, asserts disabled), so I guess you'd need to bring this up with whoever you got your version from.

Easy fix might be to just remove that Q_ASSERT()?

Code:

// Longest TDuration that fits into Fraction. Must fit exactly if truncate = false.
TDuration::TDuration(const Fraction& l, bool truncate, int maxDots, DurationType maxType)
      {
#ifdef NDEBUG
      Q_UNUSED(truncate);
#endif
      setType(maxType); // use maxType to avoid testing all types if you know that l is smaller than a certain DurationType
      setDots(maxDots);
      truncateToFraction(l, maxDots);
      Q_ASSERT(truncate || (fraction() - l).numerator() == 0); // check for exact fit
      }

Possible fix:

$ git diff
diff --git a/libmscore/cmd.cpp b/libmscore/cmd.cpp
index f06d59eeed..e43140643d 100644
--- a/libmscore/cmd.cpp
+++ b/libmscore/cmd.cpp
@@ -2693,7 +2693,7 @@ void Score::cmdIncDecDuration(int nSteps, bool stepDotted)
 
       // if measure rest is selected as input, then the correct initialDuration will be the
       // duration of the measure's time signature, else is just the input state's duration
-      TDuration initialDuration = (cr->durationType() == TDuration::DurationType::V_MEASURE) ? TDuration(cr->measure()->timesig()) : _is.duration();
+      TDuration initialDuration = (cr->durationType() == TDuration::DurationType::V_MEASURE) ? TDuration(cr->measure()->timesig(), true) : _is.duration();
       TDuration d = initialDuration.shiftRetainDots(nSteps, stepDotted);
       if (!d.isValid())
             return;

I have no idea about any possible negative consequences though

But meanwhile, best to skip those unofficial third-party builds and instead download the official version of MuseScore directly from this site (see Download link above). For Linux, the AppImage is the supported build. The versions individual distribution maintainers build themselves are generally not tested and often contain errors like this.

Unless the maintaine did some further changes, a "Release" build does #define NDEBUG which in turn disables the abort() inside the assert() marco (which is used by Q_ASSERT()), so it won't crash (not there at least). But "release" is not neccessarily the same as "RELEASE" or "Release".
Whatever: just use the AppImage, this is provided by the MuseScore developers and the only supported version for Linux. And it won't crash in this situation

Fix version
4.1.0