交叉编译-13:ffmpeg swr_init Illegal instruction错误分析解决

将ffmpeg库集成到我们项目代码中在板子上跑时候报错:Illegal instruction,通过定位是在代码中Init位置崩溃,写了个demo来验证具体崩在哪部分代码,以下代码的Init调用的是ffmpeg中的swr_init 接口,所以确定是ffmpeg编译问题。

// main.cpp : 定义控制台应用程序的入口点。
//


#include <stdio.h>
#include <stdlib.h>


#include "Swscale/IAVXSwscale.h"

int main(int argc, char * argv[])
{
	int32_t avx_success = 0;
	static const int32_t kAudioChannels = 1;
	static const int32_t kAudioSampleRate = 16000;

	IAVXSwscale * kImplSwscale = CreateSwscale(AVXSWSCALE_ID_FLTP2S16);
	if (kImplSwscale == NULL)
	{
		printf("OpenALAudioDecoder|Init: CreateSwscale is failure\n");
		return -1;
	}

	AVXSwscaleInfo avx_swscale_info;
	avx_swscale_info.src_codec_fmt = AVXCODEC_FMT_FLT;
	avx_swscale_info.src_dimension.nb_channel = kAudioChannels;//2;//lpSliceInfo->codec.channels;
	avx_swscale_info.src_dimension.nb_samples = 1024 * 1;
	avx_swscale_info.src_dimension.sample_rate = kAudioSampleRate;//44100;//lpSliceInfo->codec.sample_rate;
	avx_swscale_info.src_dimension.channel_layout = 4;//lpSliceInfo->codec.channel_layout;
	avx_swscale_info.des_codec_fmt = AVXCODEC_FMT_S16;
	avx_swscale_info.des_dimension.nb_channel = kAudioChannels;
	avx_swscale_info.des_dimension.sample_rate = kAudioSampleRate;
	avx_swscale_info.des_dimension.nb_samples = avx_swscale_info.src_dimension.nb_samples * (avx_swscale_info.des_dimension.sample_rate * 1.0 / avx_swscale_info.src_dimension.sample_rate);
	avx_swscale_info.des_dimension.nb_samples = ((avx_swscale_info.des_dimension.nb_samples + 31) / 32) * 32;
	avx_swscale_info.des_dimension.channel_layout = 4;
	avx_swscale_info.opt_flip = 0;
	
	printf("OpenALAudioDecoder|Init: before\n");
	avx_success = kImplSwscale->Init(avx_swscale_info);
	
	printf("OpenALAudioDecoder|Init: after\n");

}

报错:

查询资料发现程序崩溃原因:很多编译器都在O2或者O3中开了自动向量化,这就导致很多在新体系结构中编译的可执行程序,在老机器上运行时会有Illegal instruction问题。

解决方法:在编译ffmpeg时,执行完./configure生成config.mak,修改config.mak的以下部分,删除-O3,再执行make和make install命令。

CFLAGS=  -fPIC -I/home/Archive/ffmpeg-2.5.3/x264/include -I/home//Archive/ffmpeg-2.5.3/faac/include -std=c99 -fomit-frame-pointer -fPIC -mips32r2 -mdsp -mdspr2 -mhard-float -pthread -Wdeclaration-after-statement -Wall -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -Wmissing-prototypes -Wno-pointer-to-int-cast -Wstrict-prototypes -Wempty-body -Wno-parentheses -Wno-switch -Wno-format-zero-length -Wno-pointer-sign -O3 -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=format-security -Werror=implicit-function-declaration -Werror=missing-prototypes -Werror=return-type -Werror=vla -Wformat -Wno-maybe-uninitialized

扩展:

造成SIGILL的原因

1 将不正确的数据写入代码段
进程在代码段中的数据是要被作为一个指令执行的。 若不小心覆盖了已有的代码段,可能会得到错误格式的指令。 这种错误尤其在Just-In-Time即时编译器中最可能出现。

同样,如果不小心覆盖了栈上活跃记录中的返回地址,程序就可能根据这个错误地址,执行没有意义的内存中的数据,进而操作。

进一步可以认为,任何导致数据错误的问题都可能带来illegal instruction问题。比如硬盘发生故障。

2 指令集的演进
比如SIMD指令,自从奔腾4开始有MMX,X86的芯片就开始不停的增加和拓宽SIMD支持,SSE、SSE2、SSE3、SSE42、AVX、AVX2。 默认情况下,很多编译器都在O2或者O3中开了自动向量化,这就导致很多在新体系结构中编译的可执行程序,在老机器上运行时会有illegal instruction问题。

3 工具链bug
对于普通C语言通过编译器生成的可执行程序。一般都已经通过严格的测试,不会随便发生这种问题。 所以如果你遇到这种错,并且试过了静态链,而且程序中没有嵌入式汇编,基本可以断定是工具链出了问题。 编译器?汇编器或者链接器。

4 访存对齐或浮点数格式问题
根据经验,请注意出现错误的指令可能和访存地址指令有关。 另外,浮点数的格式是否符合IEEE的标准也可能会有影响。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值