ffmpeg : av_free段錯誤

https://ffmpeg.org/pipermail/libav-user/2012-December/003257.html

I get a double free or corruption problem, should really do a bug
report but don't have time to decipher the FFmpeg bug reporting page.
I'll post it here in case anyone is interested, feel free to ignore.

When using custom IO for reading involves  something like the
following when creating a context:

buffer = (uint8_t*)av_malloc( BUFFER_SIZE );
ctxt = avio_alloc_context( buffer, BUFFER_SIZE, 0, this,
read_function, NULL, NULL );

and then to free it:

av_free( ctxt );
av_free( buffer );

However, if BUFFER_SIZE > 32768 bytes then av_free( buffer ) results
in a crash due to invalid free/delete (which can also be detected by
valgrind).
Not calling av_free( buffer ) leads to a memory leak (reported by valgrind).

In the case of calling av_free() Valgrind reports the buffer as
already being free'd in:

==5471==  Address 0x9181680 is 0 bytes inside a block of size 32,784 free'd
==5471==    at 0x4C2A82E: free (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5471==    by 0x712EC6F: av_free (mem.c:186)
==5471==    by 0x6DBEFC4: ffio_set_buf_size (aviobuf.c:707)
==5471==    by 0x6DBE1E5: fill_buffer (aviobuf.c:408)
==5471==    by 0x6DBE570: avio_read (aviobuf.c:495)
==5471==    by 0x6DE8971: ff_id3v2_read (id3v2.c:748)
==5471==    by 0x6EA4F42: avformat_open_input (utils.c:638)

which if you follow the call in a debugger leads to the culprit at
aviobuf.c:408:

    /* make buffer smaller in case it ended up large after probing */
    if (s->read_packet && s->buffer_size > max_buffer_size) {
        ffio_set_buf_size(s, max_buffer_size);

        s->checksum_ptr = dst = s->buffer;
        len = s->buffer_size;
    }

This only gets called when we are reading. So in the case of using
custom input libav takes it upon itself to tinker with the user
supplied buffer. The crash only occurs if the buffer size is larger
than 32KB
which in my case it was because I was trying to follow some examples
which show allocating (32768 + FF_INPUT_BUFFER_PADDING_SIZE) bytes.

I don't know if the bug is that libav is supposed to give an error if
the buffer is larger than 32KB, or not tinker with user supplied
buffers, or avio_alloc_context should take a ** to the buffer so it
can reallocate properly and clients don't have
to choose between a double free or a memory leak, but its definitely
wrong one way or another. I actually do not understand why the user
needs to pass in the buffer at all as it seems avio_alloc_context
could do it internally if it is going to
reallocate it on a whim anyway.

regards,
Mark

從這段描述中可以看出,當使用自定義輸入的時候,如果iobuffer大於32KB就會在av_free(iobuffer)時導致段錯誤。這個問題甚是詭異啊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章