SynoCommunity / spksrc

Cross compilation framework to create native packages for the Synology's NAS
https://synocommunity.com
Other
3.01k stars 1.23k forks source link

ffmpeg6 segmentation fault on Marvell PJ4Bv7 Processor rev 1 (v7l) for h264 (libx264) #6176

Open icegood opened 1 month ago

icegood commented 1 month ago

Is this a new Bug?

Package Name

ffmpeg6

Package Version

6.0.1-3

Device Model

DS414slim

Device Architecture

ARMv7

Firmware Version

Version: 7.1.1-42962 Update 6

What happened?

transformation fails with segmentation fault from mpg to mp4

Reproduction steps

OK to transform to avi. Output is:

root@ice_home_nas:/volume1/backup_hdd/video_test# /var/packages/ffmpeg6/target/bin/ffmpeg -i /volume1/backup_hdd/video_test/out1.mpg /volume1/backup_hdd/video_test/out5.avi
ffmpeg version 6.0.1-3 Copyright (c) 2000-2023 the FFmpeg developers
  built with gcc 8.5.0 (GCC)
  configuration: --target-os=linux --cross-prefix=/github/workspace/toolchain/syno-armv7-7.1/work/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- --prefix=/var/packages/ffmpeg6/target --extra-cflags=-I/github/workspace/spk/ffmpeg6/work-armv7-7.1/install/var/packages/ffmpeg6/target/include --extra-ldflags=-L/github/workspace/spk/ffmpeg6/work-armv7-7.1/install/var/packages/ffmpeg6/target/lib --extra-libs='-lxml2 -ldl -lm' --pkg-config=/usr/bin/pkg-config --ranlib=/github/workspace/toolchain/syno-armv7-7.1/work/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-ranlib --enable-cross-compile --enable-rpath --enable-pic --enable-shared --enable-gpl --enable-version3 --disable-debug --disable-static --disable-doc --extra-version=3 --extra-cflags=-DSYNO_VIDEOSTATION --extra-cflags=-fno-if-conversion --extra-cflags=-O3 --extra-cflags=-Wno-deprecated-declarations --disable-asm --enable-libcodec2 --enable-libxml2 --enable-demuxer=dash --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libopenjpeg --enable-libmp3lame --enable-libbluray --enable-libspeex --enable-libtheora --enable-libcaca --enable-libdc1394 --enable-libvorbis --enable-libwebp --enable-libzmq --enable-gnutls --enable-libopenh264 --enable-libopus --enable-libsoxr --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-librabbitmq --enable-libtwolame --enable-libzvbi --enable-libx264 --enable-libx265 --enable-libvpx --enable-libshine --enable-chromaprint --enable-libdav1d --enable-librist --enable-libzimg --enable-libfdk-aac --enable-nonfree --arch=arm --enable-neon --enable-thumb --disable-armv6 --disable-armv6t2 --disable-vfp --disable-armv5te --extra-cflags=-DSYNO_ALPINE_NEON --enable-libass --enable-frei0r
  libavutil      58.  2.100 / 58.  2.100
  libavcodec     60.  3.100 / 60.  3.100
  libavformat    60.  3.100 / 60.  3.100
  libavdevice    60.  1.100 / 60.  1.100
  libavfilter     9.  3.100 /  9.  3.100
  libswscale      7.  1.100 /  7.  1.100
  libswresample   4. 10.100 /  4. 10.100
  libpostproc    57.  1.100 / 57.  1.100
Input #0, mpeg, from '/volume1/backup_hdd/video_test/out1.mpg':
  Duration: 00:00:12.26, start: 0.524967, bitrate: 1030 kb/s
  Stream #0:0[0x1e0]: Video: mpeg1video, yuv420p(tv), 640x480 [SAR 1:1 DAR 4:3], 104857 kb/s, 25 fps, 25 tbr, 90k tbn
  Stream #0:1[0x1c0]: Audio: mp2, 32000 Hz, mono, s16p, 384 kb/s
File '/volume1/backup_hdd/video_test/out5.avi' already exists. Overwrite? [y/N] y
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg1video (native) -> mpeg4 (native))
  Stream #0:1 -> #0:1 (mp2 (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, avi, to '/volume1/backup_hdd/video_test/out5.avi':
  Metadata:
    ISFT            : Lavf60.3.100
  Stream #0:0: Video: mpeg4 (FMP4 / 0x34504D46), yuv420p(tv, progressive), 640x480 [SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn
    Metadata:
      encoder         : Lavc60.3.100 mpeg4
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: N/A
  Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 32000 Hz, mono, s16p
    Metadata:
      encoder         : Lavc60.3.100 libmp3lame
frame=  306 fps= 15 q=31.0 Lsize=     880kB time=00:00:12.20 bitrate= 590.6kbits/s speed=0.604x    
video:783kB audio:72kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 2.939389%

NOT OK to transform to mp4. Output is:

root@ice_home_nas:/volume1/backup_hdd/video_test# /var/packages/ffmpeg6/target/bin/ffmpeg -i /volume1/backup_hdd/video_test/out1.mpg /volume1/backup_hdd/video_test/out5.mp4
ffmpeg version 6.0.1-3 Copyright (c) 2000-2023 the FFmpeg developers
  built with gcc 8.5.0 (GCC)
  configuration: --target-os=linux --cross-prefix=/github/workspace/toolchain/syno-armv7-7.1/work/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- --prefix=/var/packages/ffmpeg6/target --extra-cflags=-I/github/workspace/spk/ffmpeg6/work-armv7-7.1/install/var/packages/ffmpeg6/target/include --extra-ldflags=-L/github/workspace/spk/ffmpeg6/work-armv7-7.1/install/var/packages/ffmpeg6/target/lib --extra-libs='-lxml2 -ldl -lm' --pkg-config=/usr/bin/pkg-config --ranlib=/github/workspace/toolchain/syno-armv7-7.1/work/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-ranlib --enable-cross-compile --enable-rpath --enable-pic --enable-shared --enable-gpl --enable-version3 --disable-debug --disable-static --disable-doc --extra-version=3 --extra-cflags=-DSYNO_VIDEOSTATION --extra-cflags=-fno-if-conversion --extra-cflags=-O3 --extra-cflags=-Wno-deprecated-declarations --disable-asm --enable-libcodec2 --enable-libxml2 --enable-demuxer=dash --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libopenjpeg --enable-libmp3lame --enable-libbluray --enable-libspeex --enable-libtheora --enable-libcaca --enable-libdc1394 --enable-libvorbis --enable-libwebp --enable-libzmq --enable-gnutls --enable-libopenh264 --enable-libopus --enable-libsoxr --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-librabbitmq --enable-libtwolame --enable-libzvbi --enable-libx264 --enable-libx265 --enable-libvpx --enable-libshine --enable-chromaprint --enable-libdav1d --enable-librist --enable-libzimg --enable-libfdk-aac --enable-nonfree --arch=arm --enable-neon --enable-thumb --disable-armv6 --disable-armv6t2 --disable-vfp --disable-armv5te --extra-cflags=-DSYNO_ALPINE_NEON --enable-libass --enable-frei0r
  libavutil      58.  2.100 / 58.  2.100
  libavcodec     60.  3.100 / 60.  3.100
  libavformat    60.  3.100 / 60.  3.100
  libavdevice    60.  1.100 / 60.  1.100
  libavfilter     9.  3.100 /  9.  3.100
  libswscale      7.  1.100 /  7.  1.100
  libswresample   4. 10.100 /  4. 10.100
  libpostproc    57.  1.100 / 57.  1.100
Input #0, mpeg, from '/volume1/backup_hdd/video_test/out1.mpg':
  Duration: 00:00:12.26, start: 0.524967, bitrate: 1030 kb/s
  Stream #0:0[0x1e0]: Video: mpeg1video, yuv420p(tv), 640x480 [SAR 1:1 DAR 4:3], 104857 kb/s, 25 fps, 25 tbr, 90k tbn
  Stream #0:1[0x1c0]: Audio: mp2, 32000 Hz, mono, s16p, 384 kb/s
File '/volume1/backup_hdd/video_test/out5.mp4' already exists. Overwrite? [y/N] y
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg1video (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (mp2 (native) -> aac (native))
Press [q] to stop, [?] for help
[libx264 @ 0x45138720] using SAR=1/1
[libx264 @ 0x45138720] using cpu capabilities: none!
[libx264 @ 0x45138720] profile High, level 3.0, 4:2:0, 8-bit
[libx264 @ 0x45138720] 264 - core 164 - H.264/MPEG-4 AVC codec - Copyleft 2003-2023 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=1 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to '/volume1/backup_hdd/video_test/out5.mp4':
  Metadata:
    encoder         : Lavf60.3.100
  Stream #0:0: Video: h264 (avc1 / 0x31637661), yuv420p(tv, progressive), 640x480 [SAR 1:1 DAR 4:3], q=2-31, 25 fps, 12800 tbn
    Metadata:
      encoder         : Lavc60.3.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
  Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 32000 Hz, mono, fltp, 69 kb/s
    Metadata:
      encoder         : Lavc60.3.100 aac
Segmentation fault (core dumped)      0kB time=-577014:32:22.77 bitrate=  -0.0kbits/s speed=N/A

Install Log

not useful

Service Log

not useful

Other Logs

not useful
icegood commented 1 month ago

As i understand the issue is with x264 sublibrary. will try to upgtade it and let you know about result

th0ma7 commented 1 month ago

it seems the github mirror for x264 is no longer in sync with the official repository. I've switched back to https://code.videolan.org/videolan/x264 using latest commit.

Once test builds complete you should be able to test out the resulting ffmpeg packages at https://github.com/SynoCommunity/spksrc/pull/6177

th0ma7 commented 1 month ago

Builds almost complete, you'll find a package for your arch here: https://github.com/SynoCommunity/spksrc/actions/runs/10021281364

icegood commented 1 month ago

Sorry, @th0ma7 . It will not help :( Already checked against debug versions of latest x264 and still old ffmpeg6. Obtained the same with the stacktrace:

 #0  0x40688b26 in psy_3gpp_analyze_channel () at libavcodec/aacpsy.c:682
#1  0x40689738 in psy_3gpp_analyze () at libavcodec/aacpsy.c:855
#2  0x4067d372 in aac_encode_frame () at libavcodec/aacenc.c:991
#3  0x407b0d60 in ff_encode_encode_cb () from /home/ice/external/synology/analysis/exec/lib/libavcodec.so.60
#4  0x407b0fc8 in encode_receive_packet_internal () from /home/ice/external/synology/analysis/exec/lib/libavcodec.so.60
#5  0x407b11a8 in avcodec_send_frame () from /home/ice/external/synology/analysis/exec/lib/libavcodec.so.60
#6  0x4011a3a6 in encode_frame () at fftools/ffmpeg.c:910
#7  0x4011be5c in reap_filters () at fftools/ffmpeg.c:1052
#8  0x4011d404 in transcode () at fftools/ffmpeg.c:4039
#9  0x400fef24 in main () at fftools/ffmpeg.c:4220
> 

will continue investigation. Let's go to discord to and discuss build-related stuff....

icegood commented 1 month ago

The things getting worse. I debugged against eligible gdb in https://global.synologydownload.com/download/ToolChain/toolchain/7.1-42661/Marvell%20Armada%20370%20Linux%203.2.101/armada370-gcc445_glibc211_softfp_armada370-GPL.txz

however our packages are compiled against https://global.synologydownload.com/download/ToolChain/toolchain/7.1-42661/Marvell%20Armada%20370%20Linux%203.2.101/armada370-gcc850_glibc226_hard-GPL.txz and it doesn't have gdb.

So, stacktrace above is not true.

I wonder, why they miss gdb. Additionally will ask community to compile gdbserver for platform. It would be even better....

th0ma7 commented 1 month ago

As mentionned here https://github.com/SynoCommunity/spksrc/issues/6188#issuecomment-2267103887 we do provide our own gdb as we faced this issue a few times and ended-up building our own. Hope this helps.

icegood commented 3 weeks ago

Ok, so I'm ready to explain what went wrong and how to fix it. In the attachment, you may find a 'buggy' session (not from the beginning) with a segfault. The code was compiled with everything for debugging (-fsanitize=address -fsanitize=undefined -fstack-protector-all -ggdb3 -g3) but all of the utilities/sanitizers don't help much.

It happens because right after step 8 (segfault) we have:

pc 0x4a5fe540 and the issue is that instruction under this address is not supposed to be executed at all. It is meaningless in a given context. Everything was fine in step 6 => 0x4a5fe1b0 <psy_3gpp_init+83052>: add.w r3, sp, #1744 @ 0x6d0 and accordingly to listing in step 10 (as a continuation for 6) instructions to execute nearby 0x4a5fe540 should be 0x4a5fe53e <psy_3gpp_init+83962>: add.w r3, sp, #1872 @ 0x750 0x4a5fe542 <psy_3gpp_init+83966>: subs r3, #60 @ 0x3c Not i wonder, why the processor in the initial code was supposed to execute instructions on 2-byte-aligned addresses. And seems, it is the purpose of thumb And i don't know, at which stage the program decides to align ip to 4byte boundary back (we have suspicious 0x4a5fe4c6 <psy_3gpp_init+83842>: blx 0x4a810b38 <____addvsi3_from_thumb>) or it happens after thread re-scheduling (from another thread that executes smth in non-thumb mode, e.g. under x264 library that was compiled w/o thumb). Whenever it happens, it shouldn't happen. I compiled the program w/o thumb in ffmpeg itself and no segfault anymore. Now I'm trying to find out a proper way to leave thumb mode for my cpu which supports it.

gdb.txt

Action Items so far: 1) From all bunch of stuff I did locally I will probably apply only changes in the build system that allow easy and properly built debug packages.

2) Regarding the bug itself.... In my opinion, all CPU-depended stuff shouldn't be resolved on package level. If some package decides to do something about it, then it should be disabled in the configure level but everything we need should be applied in the toolchain level instead. Like (regarding thumb flag) already done in https://github.com/SynoCommunity/spksrc/blob/master/toolchain/syno-alpine4k-7.2/Makefile#L11 Of course, some options should still be present on the package level as well (like ignoring assembler units or adding precompiler flags), but that stuff should be minimized.

3) My error occured in many different places. Firstly under gbb it occurs in code with many fpu instructions nearby and then i realized that something wrong with ABI. But on that moment i only found inconsistency for fpu setting. My proc has toolchain settings here while toolchain itself was compiled against: [DEBUG] CT_ARCH_ARCH="armv7-a+mp+sec" [DEBUG] CT_ARCH_FPU="vfpv2" Could someone raise a question to synology to recompile toolchain properly?

Should be [DEBUG] CT_ARCH_ARCH="armv7-a+mp+sec+fp" [DEBUG] CT_ARCH_FPU="vfpv3-d16"

for my cpu: Architecture: armv7l Byte Order: Little Endian CPU(s): 1 On-line CPU(s) list: 0 Vendor ID: Marvell Model name: PJ4/PJ4b Model: 1 Thread(s) per core: 0 Core(s) per socket: 0 Socket(s): 0 Stepping: 0x1 BogoMIPS: 1196.85 Flags: swp half thumb fastmult vfp edsp vfpv3 vfpv3d16 tls , Hadn't found issues regarding this ABI inconsistency thought. I expect only some optimizations in, probably, math units. However, somewhere found an inconsistency with neon support and it definitely must be removed.

Hope, it helps to someone if they decide to optimize them NASes

th0ma7 commented 3 weeks ago

I wonder, your NAS DS414slim runs with armada370 which is no longer supported with DSM 7.2. So related to your third point I doubt Synology will ever rework this out, further as it runs a 3.2 kernel.

Still, currently your arch is being built with armv7 grouping, while clearly it is of a armv7l type from your CPU output. Two things comes to mind:

  1. Have you tried rebuilding an arch specific ffmpeg (make arch-armada370-7.1)? or was it a generic armv7 (make arch-armv7-7.1)? If it was generic then I suggest you rebuild with the specific.
  2. Also wonder, as your NAS clearly identify itslef as an armv7l, shouldn't it maked as such? We had to create an exception for the hi3535 arch which is armv7l. Wondering what would be the effect of switching your arch to go udner the ARMv7L_ARCHS definition, rebuilding and check if it works out?

... further looking, there isn't much ARMv7 nor ARMv7l specific enablement under the cross/ffmpeg6/Makefile so impact may be somewhat limited. Although one thing in particular caught my attention, the --disable-vfp which may need to not be set, or changed to be -cpuflags vfpv3 (from https://www.ffmpeg.org/ffmpeg.html).

icegood commented 3 weeks ago

I usually build only via: make V=1 arch-armada370-7.1 And the issue in is that the line https://github.com/SynoCommunity/spksrc/blob/master/cross/ffmpeg6/Makefile#L216 twice buggy for me: 1) I don't have neon 2) I have thumb, but it is buggy for me due, probably, toolchain issues...

th0ma7 commented 3 weeks ago

Have a look at line 216 of cross/ffmpeg6/Makefile. Play with those relatively to neon and vfp. Also much earlier there is another switch for asm. Maybe you'll be able to find a working configuration that we can create proper ifeq calls later on.

icegood commented 3 weeks ago

I already found a working configuration by eliminating -mthumb. And it works fine. Moreover, I narrowed issue to instructions only (it is neither related to some calls or thread scheduling). Please, find attachment: broken_context.txt In 0x40768c5a everything is fine and it somehow got to 0x40768c68 and failed there. Interesting fact, issue happens at 5041th occurrence of given code.

Next, from Thumb2 Standard:

Most Thumb 32-bit instructions cannot use the PC as a source or destination register. Instead, if a register
is specified as 0b1111 in an instruction encoding, the instruction is a special case instruction. If an
instruction definition does not specify otherwise, the instruction is UNPREDICTABLE if a register is specified
as 0b1111. See Usage of 0b1111 as a register specifier in 32-bit encodings on page 3-38 for more
information.

And this is what happens. So , GCC from toolchain is buggy. And if before I hesitated to leave '-mthumb' on toolchain level or not, now I know: it MUST be disabled at all.