FS#68527 - [mkvtoolnix-cli] (51.0.0-2) mkvinfo crashes with a segfault when reading an audio track

Attached to Project: Arch Linux
Opened by Ben Kerman (Ben Kerman) - Wednesday, 04 November 2020, 18:57 GMT
Last edited by Maxime Gauduin (Alucryd) - Monday, 23 November 2020, 09:20 GMT
Task Type Bug Report
Category Packages: Extra
Status Closed
Assigned To Maxime Gauduin (Alucryd)
Architecture All
Severity High
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 5
Private No

Details

Whenever I try to query a Matroska file with mkvinfo, it crashes with the old "segmentation fault (core dumped)" right after printing most of the first audio track's information.
I have the latest version available from Arch repos (51.0.0-2) installed.
The problem occurs on two separate (and very different) machines running Arch and with at least AAC, Opus and FLAC audio, so I suspect it affects all audio tracks.
Iirc mkvinfo worked until I upgraded from 51.0.0-1 to 51.0.0-2, and manually downgrading to 51.0.0-1 does solve the issue.

Steps to reproduce: Run mkvinfo on any file containing an audio track.

I attached an invocation of mkvinfo with maximum verbosity, just in case it's helpful.
This task depends upon

Closed by  Maxime Gauduin (Alucryd)
Monday, 23 November 2020, 09:20 GMT
Reason for closing:  Fixed
Additional comments about closing:  51.0.0-3
Comment by Stefan Zwanenburg (psYchotic) - Wednesday, 04 November 2020, 23:24 GMT
I was about to submit a bugreport myself, when I ran into this. So I can reproduce this.
In case it's useful, I built mkvtoolnix with debugging symbols and captured a backtrace. Here it is:

#0 0x00007ffff7f81f1f in std::back_insert_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > fmt::v7::detail::write<char, std::back_insert_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, double, 0>(std::back_insert_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, double) () from /usr/lib/libfmt.so.7
#1 0x00007ffff7f766a9 in fmt::v7::detail::vformat[abi:cxx11](fmt::v7::basic_string_view<char>, fmt::v7::format_args) () from /usr/lib/libfmt.so.7
#2 0x00005555555c9a0a in fmt::v7::format<char [3], double&, char> (format_str=...) at /usr/include/c++/10.2.0/bits/char_traits.h:357
#3 (anonymous namespace)::normalize_fmt_double_output<double> (value=48000) at src/common/kax_info.cpp:98
#4 0x00005555555c9d47 in operator() (__closure=<optimized out>, __closure=<optimized out>, e=...) at src/common/kax_info.cpp:607
#5 std::__invoke_impl<void, mtx::kax_info_c::init_custom_element_value_formatters_and_processors()::<lambda(libebml::EbmlElement&)>&, libebml::EbmlElement&> (__f=...)
at /usr/include/c++/10.2.0/bits/invoke.h:60
#6 std::__invoke_r<void, mtx::kax_info_c::init_custom_element_value_formatters_and_processors()::<lambda(libebml::EbmlElement&)>&, libebml::EbmlElement&> (__fn=...)
at /usr/include/c++/10.2.0/bits/invoke.h:110
#7 std::_Function_handler<void(libebml::EbmlElement&), mtx::kax_info_c::init_custom_element_value_formatters_and_processors()::<lambda(libebml::EbmlElement&)> >::_M_invoke(const std::_Any_data &, libebml::EbmlElement &) (__functor=..., __args#0=...) at /usr/include/c++/10.2.0/bits/std_function.h:291
#8 0x00005555555c472a in mtx::kax_info_c::handle_elements_generic (this=0x7fffffffe7d0, e=...) at src/common/kax_info.cpp:1156
#9 0x00005555555c472a in mtx::kax_info_c::handle_elements_generic (this=0x7fffffffe7d0, e=...) at src/common/kax_info.cpp:1156
#10 0x00005555555c472a in mtx::kax_info_c::handle_elements_generic (this=0x7fffffffe7d0, e=...) at src/common/kax_info.cpp:1156
#11 0x00005555555c77fe in mtx::kax_info_c::handle_segment (this=0x7fffffffe7d0, l0=0x5555556efbf0) at /usr/include/c++/10.2.0/bits/shared_ptr_base.h:1324
#12 0x00005555555c94b8 in mtx::kax_info_c::process_file (this=0x7fffffffe7d0) at /usr/include/c++/10.2.0/bits/shared_ptr_base.h:1324
#13 0x00005555555c59bd in mtx::kax_info_c::open_and_process_file (this=0x7fffffffe7d0) at src/common/kax_info.cpp:1298
#14 0x000055555557a9d1 in main (argc=-6160, argv=0x7fffffffe830) at src/info/mkvinfo.cpp:55
Comment by Gereon Schomber (IncredibleLaser) - Tuesday, 10 November 2020, 17:23 GMT
To add to this: When using mkvmerge 51.0.0-2, wrong bitrate information is written to the output files. 51.0.0-1 is unaffected.
Comment by Kyle Brady (Shasta) - Thursday, 12 November 2020, 08:07 GMT
Just a guess, but this may be caused by:

[fmt] Incorrect printing of float/double in 7.1.1
https://github.com/fmtlib/fmt/issues/1976

This was bug was resolved with fmt 7.1.2
Comment by Ben Kerman (Ben Kerman) - Friday, 13 November 2020, 01:19 GMT
I upgraded my system and now I get a different error message from mkvinfo, also while audio track information is being printed:
(MKVInfo) Caught exception: std::bad_alloc
So at least it isn't crashing from an unhandled segfault anymore, I guess.

I also tried building the package myself, but that just brings back the previous error.
Comment by Ben Kerman (Ben Kerman) - Friday, 13 November 2020, 19:23 GMT
I found yet another issue, which is that mkvmerge breaks SSA/ASS subtitles while muxing since (I think) the libfmt update. Extracting SSA sub tracks using mkvextract from files muxed before that point works fine, but extracting from any file I muxed recently causes warnings and results in an extracted file with missing and out-of-order lines. The error message is 'Warning: Invalid format for a SSA line ([...]) at timestamp [...]: The first field is not an integer. This entry will be skipped.'

This is not an issue with mkvextract, since mpv is unable to properly play the affected files as well.

Manually rebuilding the package using the official PKGBUILD and installing that fixes the muxing issue, but the mkvinfo segfault still persists.
Comment by Moritz Bunkus (mbunkus) - Saturday, 21 November 2020, 15:24 GMT
MKVToolNix author here. I've spent a bit of time building & re-building things. It looks like there are at least a couple of issues left in the fmt 7.1.2 package that Arch provides that totally break things.

For those who want a working MKVToolNix package, I suggest you re-build with the fmt version bundled in MKVToolNix's source archive. You'll have to modify the PKGBUILD a bit for that to work, though:

1. Remove "fmt" from "makepends".
2. Remove "libfmt.so" from "depends" set in "package_mkvtoolnix-cli".
3. In "prepare" add "git submodule init ; git submodule update" after "cd mkvtoolnix".
4. In "build" after the "configure …" line and before the "rake" line, insert the following line: sed -i -e 's/FMT_INTERNAL.*/FMT_INTERNAL=yes/' build-config
5. Run "makepkg"

Unfortunately there's no option to configure for forcing the use of the bundled version; hence the need to fiddle with the results of the library detection after configure has run.

The issue does not seem to be with fmt 7.1.2 per se. If I do the aforementioned modification of PKGBUILD but add some more steps to pull fmt 7.1.2 from git instead of the currently bundled one, run makepkg, install the package, the resulting binaries run just fine without segfaulting, without missing digits in number outputs, and MKVToolNix GUI doesn't complain about mkvmerge having a different version.

Here's the modified PKGBUILD that fetches fmt 7.1.2 from GitHub & uses that one instead of Arch's packaged fmt:

https://mkvtoolnix.download/misc/20201121-PKGBUILD-bundled-fmt712

To me all of this looks like a problem with Arch's fmt package.

From an upstream perspective there isn't anything I can do (safe for modifying configure to always use the bundled fmt, but distros rightfully frown on that).
Comment by Moritz Bunkus (mbunkus) - Saturday, 21 November 2020, 19:17 GMT
One thing I forgot to add is: the main difference between building against Arch's fmt package and using the version bundled with MKVToolNix is that the bundled version will be linked statically whereas Arch's fmt package comes with a shared library. Maybe that makes a difference for whatever reason.
Comment by Maxime Gauduin (Alucryd) - Monday, 23 November 2020, 08:36 GMT
fmt releases have been hit and miss lately, they broke ABI again without a soname bump when they published 7.1.0. The current mkvtoolnix was built against fmt 7.1.0 and I do get the `(MKVInfo) Caught exception: std::bad_alloc` error with 7.1.2. Also experiencing  FS#68581 .

Rebuilding mkvtoolnix against 7.1.2 does get rid of  FS#68581 , but I'm back to a segfault in mkvinfo. Nothing fancy in how fmt is built, but yeah it's a shared lib, here's an strace: https://paste.xinu.at/9AQV6aDZ3feSEXwy/

Will keep investigating.
Comment by Maxime Gauduin (Alucryd) - Monday, 23 November 2020, 08:53 GMT
This commit fixes our issue: https://github.com/fmtlib/fmt/commit/f81c14aa1edd48919d452da872b425c9368cf782

Will backport it into our fmt package.

Loading...