[FFmpeg-devel] [PATCHv2] avformat/mp3dec, rmdec: check return value of ffio_ensure_seekback
Ganesh Ajjanagadde
gajjanag at mit.edu
Fri Nov 20 14:42:10 CET 2015
On Wed, Nov 18, 2015 at 8:26 AM, Ganesh Ajjanagadde <gajjanag at mit.edu> wrote:
> On Wed, Nov 18, 2015 at 7:31 AM, wm4 <nfxjfg at gmail.com> wrote:
>> On Tue, 17 Nov 2015 17:39:31 -0500
>> Ganesh Ajjanagadde <gajjanagadde at gmail.com> wrote:
>>
>>> ffio_ensure_seekback can fail due to e.g ENOMEM. This return value is
>>> checked here and a diagnostic is logged.
>>>
>>> All usage of ffio_ensure_seekback in the codebase now has the return value checked.
>>>
>>> Signed-off-by: Ganesh Ajjanagadde <gajjanagadde at gmail.com>
>>> ---
>>> libavformat/mp3dec.c | 6 ++++--
>>> libavformat/rmdec.c | 3 ++-
>>> 2 files changed, 6 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
>>> index 32ca00c..a14bccd 100644
>>> --- a/libavformat/mp3dec.c
>>> +++ b/libavformat/mp3dec.c
>>> @@ -380,11 +380,13 @@ static int mp3_read_header(AVFormatContext *s)
>>> uint32_t header, header2;
>>> int frame_size;
>>> if (!(i&1023))
>>> - ffio_ensure_seekback(s->pb, i + 1024 + 4);
>>> + if ((ret = ffio_ensure_seekback(s->pb, i + 1024 + 4)) < 0)
>>> + av_log(s, AV_LOG_WARNING, "ffio_ensure_seekback(): %s\n", av_err2str(ret));
>>> frame_size = check(s->pb, off + i, &header);
>>> if (frame_size > 0) {
>>> avio_seek(s->pb, off, SEEK_SET);
>>> - ffio_ensure_seekback(s->pb, i + 1024 + frame_size + 4);
>>> + if ((ret = ffio_ensure_seekback(s->pb, i + 1024 + frame_size + 4)) < 0)
>>> + av_log(s, AV_LOG_WARNING, "ffio_ensure_seekback(): %s\n", av_err2str(ret));
>>> if (check(s->pb, off + i + frame_size, &header2) >= 0 &&
>>> (header & SAME_HEADER_MASK) == (header2 & SAME_HEADER_MASK))
>>> {
>>> diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
>>> index 4ec78ef..1cf0548 100644
>>> --- a/libavformat/rmdec.c
>>> +++ b/libavformat/rmdec.c
>>> @@ -576,7 +576,8 @@ static int rm_read_header(AVFormatContext *s)
>>> size = avio_rb32(pb);
>>> codec_pos = avio_tell(pb);
>>>
>>> - ffio_ensure_seekback(pb, 4);
>>> + if ((ret = ffio_ensure_seekback(pb, 4)) < 0)
>>> + av_log(s, AV_LOG_WARNING, "ffio_ensure_seekback(): %s\n", av_err2str(ret));
>>> v = avio_rb32(pb);
>>> if (v == MKBETAG('M', 'L', 'T', 'I')) {
>>> int number_of_streams = avio_rb16(pb);
>>
>> So why do you not just add the message to the function itself?
>
> Because a client may not like the generic message, see e.g the message
> printed in avformat/apngdec. Handling of the error may vary from
> context to context, again see the apngdec example where the client
> does something else in addition to error printing.
>
>>
>> I also question the usefulness of the message. In such cases of OOM
>> everything goes to hell anyway. No reason to bloat the code with error
>> printing.
>
> Taking that logic a bit further, why bother returning ENOMEM? If the
> ENOMEM being returned by ensure_seekback is not checked, the
> information is just silently discarded or garbled with further errors
> down the road.
>
> Anyway, I do not consider it a bloat: the buffer allocated can be big
> (see in mp3dec > 1024 bytes). A user has a right to know when things
> "go to hell". Envisioning what may happen, ffmpeg crashes due to OOM,
> upon which a coredump takes place. That crash happens in a somewhat
> random location, since OOM handling is a heuristic and determining
> which process should be killed is an intractable problem. Thus at the
> time when the core dump is written out, it is not guaranteed that the
> context is the one where the allocation failed first. Then there are
> issues of overcommit where malloc may return a non-NULL pointer but
> OOM happens upon a dereference. Such issues are beyond the scope of
> error handling, as nothing can be done in such cases anyway.
>
> Warning the user when a reasonably large allocation failed in my view
> is not bloat. It is giving them as much information as we can. Also
> think of it from a debugging perspective: it can help us find places
> where the alloc size was unreasonable.
Another reason related to the randomness of the process killed for
OOM: ffmpeg/some other client may not be the process killed when OOM
occurs, and the malloc's here fail. Thus, seek back, something a user
does care about, fails, but without the error message, there is no
information whatsoever that such a thing failed and why. We should
make a "best effort" in such cases, especially since the alloc may be
non-trivial in size and has sufficient client impact.
Anyway, I by no means claim above patch is great, but I strongly
disagree with wm4 here.
>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel at ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
More information about the ffmpeg-devel
mailing list