macOS Catalina的strip版本异常导致编译的FFmpeg运行被kill

因为近期正在调研&了解SRT协议的相关内容,为了方便,需要打开FFmpeg的--enable-libsrt功能并重新编译FFmpeg,从而保证FFmpeg支持SRT协议。但是重新编译之后却发现启动ffmpeg工具就会被内核杀死,具体如下所示。

利用lldb调试该ffmpeg发现直接提示error: Malformed Mach-o file的错误,具体如下:

编译异常的Mac版本和Xcode版本信息分别如下:

查阅了网上的资料,也查看了brew编译FFmpeg的指令,原因可能是:Xcode11下clang默认开启-fstack-check

同时,在如下图所示的Xcode 10.3版本的Mac上则可编译成功:

因此根据如上信息:./configure时需要增加--host-cflags=-fno-stack-check配置。

但是增加该配置之后,编译出的ffmpeg依然无法正常运行。

发现原因

恰好最近升级了系统和Xcode版本,想着再编译一下看下是否可用,终于有了新的发现。

编译的系统版本和Xcode版本如下所示:

编译命令如下所示:

1
2
3
4
5
6
7
8
9
 ./configure --enable-shared --enable-pthreads --enable-version3 --enable-avresample \
--cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl \
--enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus \
--enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora \
--enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 \
--enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype \
--enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb \
--enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr \
--enable-videotoolbox --disable-libjack --disable-indev=jack

编译之后,惊喜的发现,虽然ffprobe命令依旧异常,但是ffprobe_g命令已经可以使用了。具体如下图所示:

ffprobeffprobe_g的不同就是ffprobe_g会包含调试信息。

回顾编译指令的最后几条指令:

1
2
3
4
5
6
LD ffmpeg_g
LD ffprobe_g
LD ffplay_g
STRIP ffmpeg
STRIP ffprobe
STRIP ffplay

可以发现,在编译的最后,使用strip命令,去掉了ffprobe中的调试信息。那么是否是strip命令有问题呢?

带着这个疑问,写了一段测试代码test.cpp

1
2
3
4
5
6
#include <iostream>

int main() {
std::cout << "Hello World!" << std::endl;
return 0;
}

使用clang++编译并对比利用strip命令去掉调试信息前后的运行结果,终于发现了问题所在:

至此,终于找到原因:strip命令生成的无调试信息的可执行程序,会发生Malformed Mach-o file的现象。

修正strip版本

怀疑机器上的strip版本异常导致去掉调试信息后的可执行文件出现异常。

1
2
3
4
5
6
7
8
9
$ which strip
/usr/local/opt/binutils/bin/strip
$ which clang++
/usr/bin/clang++
$ ls /usr/bin/strip
/usr/bin/strip
$ /usr/bin/strip -x a.out
$ ./a.out
Hello World!

经过如上的过程发现,确实是strip的版本有问题,利用/usr/bin/strip生成的无调试信息的可执行程序是正常的。

问题解决

在编译ffmpeg时,利用--strip选项来指定strip的版本。

1
2
3
4
5
6
7
8
9
10
 ./configure --enable-shared --enable-pthreads --enable-version3 --enable-avresample \
--cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl \
--enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus \
--enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora \
--enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 \
--enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype \
--enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb \
--enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr \
--enable-videotoolbox --disable-libjack --disable-indev=jack \
--strip=/usr/bin/strip

大功告成,问题解决,具体如下所示:

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2020-2024 Wang Wei
  • 本站访问人数: | 本站浏览次数:

请我喝杯咖啡吧~

微信