[FFmpeg-devel] [PATCH 3/3] Replace atexit usage with do_exit function in ffmpeg.c

Stephen Hutchinson qyot27 at gmail.com
Thu Feb 28 03:36:24 CET 2013


On Wed, Feb 27, 2013 at 4:09 AM, Nicolas George
<nicolas.george at normalesup.org> wrote:
> L'octidi 8 ventôse, an CCXXI, Stephen Hutchinson a écrit :
>> From: d s <avxsynth.testing at gmail.com>
>>
>> Resolves segfault-at-exit when using the new AviSynth demuxer.
>
> Can you explain this one? If freeing all structures becomes mandatory, that
> constitutes an ABI change, this is not at all benign.

It has to do with how atexit and dlopen are interacting.  The
explanation I got from avxsynth-testing was:
"More details about the segfault on exit problem:
In ffmpeg.c, exit_program is registered with atexit. C++ static global
objects are also (secretly) registered with a C++ atexit equivalent.
The ScriptEnvironment destructor in Avxsynth has been modified from
the Avisynth version to access some global structures, namely the (now
vector instead of array) list of built-in functions and the log4cpp
service. Normally, this would not be an issue because constructed
static objects are guaranteed by the C++ standard to be destroyed
after user atexit handlers run. However, because Avxsynth is being
dynamically loaded, the global objects are actually constructed upon
calling dlopen through avformat_read_header, which occurs after
exit_program is registered. As a consequence, the Avxsynth global
structures are destroyed before calling exit_program, and
avs_delete_script_environment accesses freed memory when calling the
ScriptEnvironment destructor."

This then led to them posting the original version of the patch that
replaced 6 instances of atexit with the do_exit function.

Forwarding the suggestion given here:
http://ffmpeg.org/pipermail/ffmpeg-devel/2013-February/139714.html

Their response was:
"What michaelni suggests is feasible. It would involve creating a
global linked list of AvisynthContexts and a global atexit_called
flag. Calling avisynth_read_header will add an element to the list of
contexts and a avisynth_read_close will remove it. The first call to
avisynth_read_header will register with atexit a function to destroy
the list of contexts.

Edit:
I just realized that using atexit in avisynth.c would also mean that
the Avisynth DLL could never be unloaded (e.g. when a file is closed).
It must remain until the end of the program lifetime."

Is that acceptable behavior?



Previous attempts at 'solving' it were:
Turning the avs_delete_script_environment call in read_close into a NOP.
Just disabling the avs_delete_script_environment call in read_close
entirely (for non-Windows).


More information about the ffmpeg-devel mailing list