Part1: Overcome the ‘Access Violation Exception’ in the FFMPEG

Part1: Overcome the ‘Access Violation Exception’ in the FFMPEG

 

It is painful when the ‘Access Violation Exception’ is thrown in the FFMPEG, because the debugging process is hard and boring. However, programmers must be faced with the challenge and get ride of this obstacle.

By VC IDE, this exception is caught and the information likes “Unhandled exception at 0x6b0dd484 in ffplay.exe: 0xC0000005: Access violation reading location 0xffffffff .” After clicking “Show Disassembly” button, the block of ASM codes is listed as below. The red sentence marked is the correct position leads to throw exception.

6B0DD47C  shufps      xmm5,xmm7,88h

6B0DD480  shufps      xmm0,xmm7,0DDh

6B0DD484  movaps      xmm7,xmmword ptr ds:[6B6CA4D8h]

6B0DD48B  movaps      xmm1,xmm4

6B0DD48E  movaps      xmm2,xmmword ptr ds:[6B6CA4E8h]

6B0DD495  movaps      xmm3,xmm6

Obviously, the un-aligning address of memory raises the fault of movaps(SSE instruction) because ds equals zero in the runtime.

 

Herein, we have found the root cause, and the next step is how to locate the function including the above block of source codes. Ok, let’s go!

 

1) Find which module it belongs to.

Check ‘Call Stack’ in VC IDE, and the information likes

>          avcodec-52.dll!6b0dd484()     

             [Frames below may be incorrect and/or missing, no symbols loaded for avcodec-52.dll]           

             avcodec-52.dll!6b0ddcb5()     

             avcodec-52.dll!6b0ddce5()     

             avcodec-52.dll!6b0ddd15()     

             avcodec-52.dll!6b0ddf46()      

             avcodec-52.dll!6b0df644()      

             avcodec-52.dll!6adb5efc()      

             kernel32.dll!7c810693()

 

Great! It is avcodec-52 module.

 

2) Find which function it belongs to.

Disassembly the avcodec-52.dll, and find this block of source codes. The disassembly command is shown in the following content.

$ objdump.exe -m i386:intel -D ./avcodec-52.dll > avcodec-52.dll.asm

After that, please search ‘6B6CA4D8 ’ string in the avcodec-52.dll.asm. It is easy to know the function is fft16_sse in the fft_mmx.asm(Line number is the 311th).

 

3) Design the bugfix.

Before designing the bugfix, we must analyze the building way in the FFMPEG.

    a) *.asm is built by yasm

b) *.c is built by gcc

c) *.o is linked by gcc

As a result, which step does raise this issue?

No way, we must investigate them all!

 

Step 1) Investigate fft_mmx.o

After linkage

Before linkage

movaps xmm7,xmmword ptr ds:[6B6CA4D8h]

movaps xmm7,XMMWORD PTR ds:0x0

No problems for fft_mmx.o. PASS !

 

Step 2) Investigate fft.c

DECLARE_ALIGNED_16(FFTSample, ff_cos_16[8]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_32[16]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_64[32]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_128[64]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_256[128]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_512[256]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_1024[512]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_2048[1024]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_4096[2048]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_8192[4096]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_16384[8192]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_32768[16384]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_65536[32768]);

It is asked to align 16bytes. PASS !

 

Step 3) Investigate fft.o

00000800 C _ff_cos_1024

00000100 C _ff_cos_128

00000020 C _ff_cos_16

00008000 C _ff_cos_16384

00001000 C _ff_cos_2048

00000200 C _ff_cos_256

00000040 C _ff_cos_32

00010000 C _ff_cos_32768

00002000 C _ff_cos_4096

00000400 C _ff_cos_512

00000080 C _ff_cos_64

00020000 C _ff_cos_65536

00004000 C _ff_cos_8192

00000000 D _ff_cos_tabs

Match the requirement. PASS !

 

Step 4) Investigate linker

$ nm ./avcodec-52.dll | egrep 'ff_cos'

6af87fb0 T _ff_cos

6b68c618 B _ff_cos_1024

6b6cc4f8 B _ff_cos_128

6b6ca4d8 B _ff_cos_16

6b68ce18 B _ff_cos_16384

6b694ed8 B _ff_cos_2048

6b6962d8 B _ff_cos_256

6b694e98 B _ff_cos_32

6b6964d8 B _ff_cos_32768

6b6ca4f8 B _ff_cos_4096

6b695ed8 B _ff_cos_512

6b694e18 B _ff_cos_64

6b6a64d8 B _ff_cos_65536

6b6c64d8 B _ff_cos_8192

6b223020 D _ff_cos_tabs

WOW, it is here! FAIL !

 

It is a bug of linker of GCC! By searching bugs in the bugzilla of GCC, the #11203 describes this bug. O, My God!!!

 

How to do?!

As mentioned before, GCC and YASM build the related source codes respectively, and then link together. The issue is caused by the linker not caring the dependence among these *.o files. The simple train of thinking is how to build source codes by using same compiler. Ok, following the clue, let’s check the configure file of FFMPEG.

$ ./configure –help

  --disable-neon           disable neon optimizations

  --disable-vis            disable VIS optimizations

  --disable-yasm           disable use of yasm assembler

It is lucky, and ‘--disable-yasm ’ can handle this issue.

$ ./configure --enable-memalign-hack --enable-shared –disable-static –disable-yasm && make && make install

For the detailed HOWTO, please refer to FFmpeg Understand(3. How to compile FFMPEG in Windows?) .

 

Ok, can you enjoy your video now - ?!

 

[Summerization]

1) It is an exploration to solve crash issue of FFMPEG, and the method can be referred for other cases.

2) The simple solution takes heavy performance side-effects. Only FFT module has un-aligning case, but others are implicated by disabling YASM.

3) The better solution should be probed later, and share them in the next articles.

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值