diff mbox series

[FFmpeg-devel] Adding av_abort() : adding custom handlers for abort().

Message ID DM4PR18MB4128E0CD67C12B8A85727C40B8979@DM4PR18MB4128.namprd18.prod.outlook.com
State New
Headers show
Series [FFmpeg-devel] Adding av_abort() : adding custom handlers for abort(). | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_fate_x86 success Make fate finished
andriy/make_x86 warning New warnings during build

Commit Message

Julien Vary July 27, 2022, 2:02 p.m. UTC
Replaced all abort() by av_abort() in the code.
On production systems, when dealing with malformed data,
avcodec was sometime aborting, with no core/memory dump
available to troubleshoot after-the-fact.
Adding av_abort_set_callback to register a custom
function (instead of the default straight abort()
behavior), to allow dumping before the actual abort().
Also 'av_logging' the av_abort() location.

Signed-off-by: Julien Vary <jvary@genetec.com>
---
 fftools/ffmpeg.c             |  2 +-
 fftools/ffmpeg_opt.c         |  2 +-
 libavcodec/mpegpicture.c     |  2 +-
 libavcodec/ppc/hevcdsp.c     |  4 ++--
 libavcodec/vlc.c             |  2 +-
 libavcodec/vp8.c             |  2 +-
 libavformat/avformat.h       | 10 ++++-----
 libavutil/Makefile           |  6 ++++--
 libavutil/aarch64/neontest.h |  2 +-
 libavutil/abort.c            | 39 ++++++++++++++++++++++++++++++++++++
 libavutil/abort.h            | 36 +++++++++++++++++++++++++++++++++
 libavutil/arm/neontest.h     |  2 +-
 libavutil/avassert.h         |  3 ++-
 libavutil/avutil.h           |  1 +
 libavutil/common.h           |  9 +++++----
 libavutil/internal.h         |  3 ++-
 libavutil/softfloat.h        |  2 +-
 libavutil/thread.h           |  3 ++-
 libavutil/version.c          |  3 ++-
 libavutil/x86/intmath.h      |  9 +++++----
 libavutil/x86/w64xmmtest.h   |  2 +-
 21 files changed, 114 insertions(+), 30 deletions(-)
 create mode 100644 libavutil/abort.c
 create mode 100644 libavutil/abort.h

Comments

Nicolas George July 27, 2022, 3:28 p.m. UTC | #1
Julien Vary (12022-07-27):
> Replaced all abort() by av_abort() in the code.
> On production systems, when dealing with malformed data,
> avcodec was sometime aborting, with no core/memory dump
> available to troubleshoot after-the-fact.
> Adding av_abort_set_callback to register a custom
> function (instead of the default straight abort()
> behavior), to allow dumping before the actual abort().
> Also 'av_logging' the av_abort() location.

I think it is a very bad idea. The point of abort() is that it is
immediate, so that backtraces are clean and bugs cannot be compounded by
further processing.

A program that terminates on abort() does leave a core dump, I just
checked.
Hendrik Leppkes July 27, 2022, 4:01 p.m. UTC | #2
On Wed, Jul 27, 2022 at 4:03 PM Julien Vary <jvary@genetec.com> wrote:
>
> Replaced all abort() by av_abort() in the code.
> On production systems, when dealing with malformed data,
> avcodec was sometime aborting, with no core/memory dump
> available to troubleshoot after-the-fact.
> Adding av_abort_set_callback to register a custom
> function (instead of the default straight abort()
> behavior), to allow dumping before the actual abort().
> Also 'av_logging' the av_abort() location.
>
> Signed-off-by: Julien Vary <jvary@genetec.com>

abort() should generally not be in a reachable part of the code - not
inside any of the libraries anyway, ffmpeg.c is a different topic.
If it is reachable with any input files, and not just present to shut
up compilers, this is a bug and should be addressed to return an error
instead.

Therefore, we should address those cases, and just leave abort as-is
otherwise. Nevermind that av_abort would need to be a public function,
which sounds like a really bad idea.

- Hendrik
Julien Vary July 27, 2022, 4:52 p.m. UTC | #3
> abort() should generally not be in a reachable part of the code - not inside any of the libraries anyway, ffmpeg.c is a different topic.
> If it is reachable with any input files, and not just present to shut up compilers, this is a bug and should be addressed to return an error instead.
> 
> Therefore, we should address those cases, and just leave abort as-is otherwise. Nevermind that av_abort would need to be a public function, which sounds like a really bad idea.
> 
> - Hendrik

Historically, we had issues with the abort() within libavcodec/vlc.c  alloc_table(), but possibly those are now fixed.


> A program that terminates on abort() does leave a core dump, I just checked.
> 
> Nicolas George
  

We had a different behavior on Windows back then.
Now that we can compile ffmpeg with VisualStudio (instead of cross-compiling with gcc on Linux), we will try to re-go the route of SIGABRT signal handler, and see if we got more success now that we have the same C runtime.
(We had a custom handler to create a "full mini-dump" with dbghelp.dll)

Thanks to make me realize our problem (and solution) is now potentially obsolete.

Julien
Andreas Rheinhardt July 27, 2022, 4:57 p.m. UTC | #4
Julien Vary:
> 
>> abort() should generally not be in a reachable part of the code - not inside any of the libraries anyway, ffmpeg.c is a different topic.
>> If it is reachable with any input files, and not just present to shut up compilers, this is a bug and should be addressed to return an error instead.
>>
>> Therefore, we should address those cases, and just leave abort as-is otherwise. Nevermind that av_abort would need to be a public function, which sounds like a really bad idea.
>>
>> - Hendrik
> 
> Historically, we had issues with the abort() within libavcodec/vlc.c  alloc_table(), but possibly those are now fixed.
> 

Did you ever open tickets for these issues?

- Andreas
Marton Balint July 27, 2022, 5:39 p.m. UTC | #5
On Wed, 27 Jul 2022, Hendrik Leppkes wrote:

> On Wed, Jul 27, 2022 at 4:03 PM Julien Vary <jvary@genetec.com> wrote:
>>
>> Replaced all abort() by av_abort() in the code.
>> On production systems, when dealing with malformed data,
>> avcodec was sometime aborting, with no core/memory dump
>> available to troubleshoot after-the-fact.
>> Adding av_abort_set_callback to register a custom
>> function (instead of the default straight abort()
>> behavior), to allow dumping before the actual abort().
>> Also 'av_logging' the av_abort() location.
>>
>> Signed-off-by: Julien Vary <jvary@genetec.com>
>
> abort() should generally not be in a reachable part of the code - not
> inside any of the libraries anyway, ffmpeg.c is a different topic.
> If it is reachable with any input files, and not just present to shut
> up compilers, this is a bug and should be addressed to return an error
> instead.
>
> Therefore, we should address those cases, and just leave abort as-is
> otherwise. Nevermind that av_abort would need to be a public function,
> which sounds like a really bad idea.

IMHO abort() calls should all be converted to av_assert0(0). Or is 
there a use case for using abort() directly? I don't think so.

Or maybe we could add av_abort() as an alias to av_assert0(0), which 
eventually just calls abort()...

Regards,
Marton
Julien Vary July 27, 2022, 6:13 p.m. UTC | #6
>> abort() should generally not be in a reachable part of the code - not 
>> inside any of the libraries anyway, ffmpeg.c is a different topic.
>> If it is reachable with any input files, and not just present to shut 
>> up compilers, this is a bug and should be addressed to return an error 
>> instead.
>>
>> Therefore, we should address those cases, and just leave abort as-is 
>> otherwise. Nevermind that av_abort would need to be a public function, 
>> which sounds like a really bad idea.
>
>IMHO abort() calls should all be converted to av_assert0(0). Or is there a use case for using abort() directly? I don't think so.
>
>Or maybe we could add av_abort() as an alias to av_assert0(0), which eventually just calls abort()...

I agree that if the goal is to bail-out on 'should-not-be-reachable' code, something that alias av_assert0(0) seems a great idea.
Shall we then give a more descriptive name than plain "av_abort()" for those situations?

Nicolas George & Hendrik Leppkes ? Your thoughts ?
Nicolas George July 27, 2022, 6:40 p.m. UTC | #7
Julien Vary (12022-07-27):
> >Or maybe we could add av_abort() as an alias to av_assert0(0), which
> >eventually just calls abort()...
> 
> I agree that if the goal is to bail-out on 'should-not-be-reachable'
> code, something that alias av_assert0(0) seems a great idea.
> Shall we then give a more descriptive name than plain "av_abort()" for those situations?
> 
> Nicolas George & Hendrik Leppkes ? Your thoughts ?

I like “av_assert0(!"reason");” better than a blanket 0.

It can be a good habit to take from now on, but I do not think it is
worth changing the whole code.

av_assert0() calls av_log(), which can call user callbacks or allocate
memory: for dangerous cases, a real immediate abort() is still better.

Regards,
diff mbox series

Patch

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index b03f18cfea..99abf9672b 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -3136,7 +3136,7 @@  static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
     case AVMEDIA_TYPE_DATA:
         break;
     default:
-        abort();
+        av_abort();
         break;
     }
 
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 8ac73c0efc..b24ab4df0b 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -1061,7 +1061,7 @@  static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
         case AVMEDIA_TYPE_UNKNOWN:
             break;
         default:
-            abort();
+            av_abort();
         }
 
         ret = avcodec_parameters_from_context(par, ist->dec_ctx);
diff --git a/libavcodec/mpegpicture.c b/libavcodec/mpegpicture.c
index aaa1df0bd8..c505bff820 100644
--- a/libavcodec/mpegpicture.c
+++ b/libavcodec/mpegpicture.c
@@ -455,7 +455,7 @@  static int find_unused_picture(AVCodecContext *avctx, Picture *picture, int shar
      * all. Similarly, missing reference frames have to be replaced by
      * interpolated/MC frames, anything else is a bug in the codec ...
      */
-    abort();
+    av_abort();
     return -1;
 }
 
diff --git a/libavcodec/ppc/hevcdsp.c b/libavcodec/ppc/hevcdsp.c
index c1d562a409..2b36327b1e 100644
--- a/libavcodec/ppc/hevcdsp.c
+++ b/libavcodec/ppc/hevcdsp.c
@@ -62,7 +62,7 @@  static av_always_inline void transform4x4(vec_s16 src_01, vec_s16 src_23,
     case  7: add = vec_sl(vec_splat_s32(1), vec_splat_u32( 7 - 1)); break;
     case 10: add = vec_sl(vec_splat_s32(1), vec_splat_u32(10 - 1)); break;
     case 12: add = vec_sl(vec_splat_s32(1), vec_splat_u32(12 - 1)); break;
-    default: abort();
+    default: av_abort();
     }
 
     e0 = vec_add(e0, add);
@@ -84,7 +84,7 @@  static av_always_inline void scale(vec_s32 res[4], vec_s16 res_packed[2],
     case  7: v_shift = vec_splat_u32(7) ; break;
     case 10: v_shift = vec_splat_u32(10); break;
     case 12: v_shift = vec_splat_u32(12); break;
-    default: abort();
+    default: av_abort();
     }
 
     for (i = 0; i < 4; i++)
diff --git a/libavcodec/vlc.c b/libavcodec/vlc.c
index 96f2b28c7e..adf0c18d81 100644
--- a/libavcodec/vlc.c
+++ b/libavcodec/vlc.c
@@ -63,7 +63,7 @@  static int alloc_table(VLC *vlc, int size, int use_static)
     vlc->table_size += size;
     if (vlc->table_size > vlc->table_allocated) {
         if (use_static)
-            abort(); // cannot do anything, init_vlc() is used with too little memory
+            av_abort(); // cannot do anything, init_vlc() is used with too little memory
         vlc->table_allocated += (1 << vlc->bits);
         vlc->table = av_realloc_f(vlc->table, vlc->table_allocated, sizeof(*vlc->table));
         if (!vlc->table) {
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 10de962118..30cbbd7458 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -164,7 +164,7 @@  static VP8Frame *vp8_find_free_buffer(VP8Context *s)
         }
     if (i == 5) {
         av_log(s->avctx, AV_LOG_FATAL, "Ran out of free frames!\n");
-        abort();
+        av_abort();
     }
     if (frame->tf.f->buf[0])
         vp8_release_frame(s, frame);
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index f12fa7d904..24d1469be8 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -107,7 +107,7 @@ 
  * AVFormatContext *s = NULL;
  * int ret = avformat_open_input(&s, url, NULL, NULL);
  * if (ret < 0)
- *     abort();
+ *     av_abort();
  * @endcode
  * The above code attempts to allocate an AVFormatContext, open the
  * specified file (autodetecting the format) and read the header, exporting the
@@ -134,7 +134,7 @@ 
  * av_dict_set(&options, "pixel_format", "rgb24", 0);
  *
  * if (avformat_open_input(&s, url, NULL, &options) < 0)
- *     abort();
+ *     av_abort();
  * av_dict_free(&options);
  * @endcode
  * This code passes the private options 'video_size' and 'pixel_format' to the
@@ -149,7 +149,7 @@ 
  * AVDictionaryEntry *e;
  * if (e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX)) {
  *     fprintf(stderr, "Option %s not recognized by the demuxer.\n", e->key);
- *     abort();
+ *     av_abort();
  * }
  * @endcode
  *
@@ -258,7 +258,7 @@ 
  * AVIODirContext *ctx = NULL;
  * if (avio_open_dir(&ctx, "smb://example.com/some_dir", NULL) < 0) {
  *     fprintf(stderr, "Cannot open directory.\n");
- *     abort();
+ *     av_abort();
  * }
  * @endcode
  *
@@ -279,7 +279,7 @@ 
  * for (;;) {
  *     if (avio_read_dir(ctx, &entry) < 0) {
  *         fprintf(stderr, "Cannot list directory.\n");
- *         abort();
+ *         av_abort();
  *     }
  *     if (!entry)
  *         break;
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 9435a0bfb0..230f5996ef 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -1,7 +1,8 @@ 
 NAME = avutil
 DESC = FFmpeg utility library
 
-HEADERS = adler32.h                                                     \
+HEADERS = abort.h                                                       \
+          adler32.h                                                     \
           aes.h                                                         \
           aes_ctr.h                                                     \
           attributes.h                                                  \
@@ -99,7 +100,8 @@  ARCH_HEADERS = bswap.h                                                  \
 BUILT_HEADERS = avconfig.h                                              \
                 ffversion.h
 
-OBJS = adler32.o                                                        \
+OBJS = abort.o                                                          \
+       adler32.o                                                        \
        aes.o                                                            \
        aes_ctr.o                                                        \
        audio_fifo.o                                                     \
diff --git a/libavutil/aarch64/neontest.h b/libavutil/aarch64/neontest.h
index 2d0fc19994..b53c688a28 100644
--- a/libavutil/aarch64/neontest.h
+++ b/libavutil/aarch64/neontest.h
@@ -58,7 +58,7 @@ 
                        "   -> %016"PRIx64"\n",                  \
                        av_bswap64(neon[1][i]));                 \
             }                                                   \
-        abort();                                                \
+        av_abort();                                             \
     }                                                           \
     return ret
 
diff --git a/libavutil/abort.c b/libavutil/abort.c
new file mode 100644
index 0000000000..12974d23bf
--- /dev/null
+++ b/libavutil/abort.c
@@ -0,0 +1,39 @@ 
+/*
+ * copyright (c) 2022 Genetec inc.
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include "abort.h"
+
+void av_abort_default_callback(void)
+{
+    abort();
+}
+
+static void (*av_abort_callback)(void) = av_abort_default_callback;
+
+void av_abort_internal(void)
+{
+    av_abort_callback();
+}
+
+void av_abort_set_callback(void (*callback)(void))
+{
+    av_abort_callback = callback;
+}
diff --git a/libavutil/abort.h b/libavutil/abort.h
new file mode 100644
index 0000000000..1a00e81794
--- /dev/null
+++ b/libavutil/abort.h
@@ -0,0 +1,36 @@ 
+/*
+ * copyright (c) 2022 Genetec inc.
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_ABORT_H
+#define AVUTIL_ABORT_H
+
+/**
+ * Causes abnormal program termination. By default, av_abort_callback calls
+ * abort() from the stdlib. This behavior can be altered by setting a
+ * different av_abort callback function.
+ */
+
+void av_abort_internal(void);
+void av_abort_set_callback(void (*)(void));
+void av_abort_default_callback(void);
+
+#define av_abort()    do { av_log(NULL, AV_LOG_ERROR, "Abort at %s:%d\n", __FILE__, __LINE__); av_abort_internal(); } while(0)
+
+#endif /* AVUTIL_ABORT_H */
diff --git a/libavutil/arm/neontest.h b/libavutil/arm/neontest.h
index d75ab8380b..603c68a5a1 100644
--- a/libavutil/arm/neontest.h
+++ b/libavutil/arm/neontest.h
@@ -55,7 +55,7 @@ 
                        "   -> %016"PRIx64"\n",                  \
                        av_bswap64(neon[1][i]));                 \
             }                                                   \
-        abort();                                                \
+        av_abort();                                             \
     }                                                           \
     return ret
 
diff --git a/libavutil/avassert.h b/libavutil/avassert.h
index 51e462bbae..6d528b4555 100644
--- a/libavutil/avassert.h
+++ b/libavutil/avassert.h
@@ -28,6 +28,7 @@ 
 #define AVUTIL_AVASSERT_H
 
 #include <stdlib.h>
+#include "abort.h"
 #include "log.h"
 #include "macros.h"
 
@@ -38,7 +39,7 @@ 
     if (!(cond)) {                                                      \
         av_log(NULL, AV_LOG_PANIC, "Assertion %s failed at %s:%d\n",    \
                AV_STRINGIFY(cond), __FILE__, __LINE__);                 \
-        abort();                                                        \
+        av_abort_internal();                                            \
     }                                                                   \
 } while (0)
 
diff --git a/libavutil/avutil.h b/libavutil/avutil.h
index 64b68bdbd3..2f9f83b960 100644
--- a/libavutil/avutil.h
+++ b/libavutil/avutil.h
@@ -301,6 +301,7 @@  char av_get_picture_type_char(enum AVPictureType pict_type);
 #include "mathematics.h"
 #include "log.h"
 #include "pixfmt.h"
+#include "abort.h"
 
 /**
  * Return x default pointer in case p is NULL.
diff --git a/libavutil/common.h b/libavutil/common.h
index fd1404be6c..16a83bc798 100644
--- a/libavutil/common.h
+++ b/libavutil/common.h
@@ -41,6 +41,7 @@ 
 
 #include "attributes.h"
 #include "macros.h"
+#include "abort.h"
 
 //rounded division & shift
 #define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
@@ -173,7 +174,7 @@  av_const int av_log2_16bit(unsigned v);
 static av_always_inline av_const int av_clip_c(int a, int amin, int amax)
 {
 #if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
-    if (amin > amax) abort();
+    if (amin > amax) av_abort();
 #endif
     if      (a < amin) return amin;
     else if (a > amax) return amax;
@@ -190,7 +191,7 @@  static av_always_inline av_const int av_clip_c(int a, int amin, int amax)
 static av_always_inline av_const int64_t av_clip64_c(int64_t a, int64_t amin, int64_t amax)
 {
 #if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
-    if (amin > amax) abort();
+    if (amin > amax) av_abort();
 #endif
     if      (a < amin) return amin;
     else if (a > amax) return amax;
@@ -388,7 +389,7 @@  static av_always_inline int64_t av_sat_sub64_c(int64_t a, int64_t b) {
 static av_always_inline av_const float av_clipf_c(float a, float amin, float amax)
 {
 #if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
-    if (amin > amax) abort();
+    if (amin > amax) av_abort();
 #endif
     return FFMIN(FFMAX(a, amin), amax);
 }
@@ -405,7 +406,7 @@  static av_always_inline av_const float av_clipf_c(float a, float amin, float ama
 static av_always_inline av_const double av_clipd_c(double a, double amin, double amax)
 {
 #if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
-    if (amin > amax) abort();
+    if (amin > amax) av_abort();
 #endif
     return FFMIN(FFMAX(a, amin), amax);
 }
diff --git a/libavutil/internal.h b/libavutil/internal.h
index b44cbaaa7b..5b85d52176 100644
--- a/libavutil/internal.h
+++ b/libavutil/internal.h
@@ -38,6 +38,7 @@ 
 #include <stddef.h>
 #include <assert.h>
 #include <stdio.h>
+#include "abort.h"
 #include "config.h"
 #include "attributes.h"
 #include "timer.h"
@@ -235,7 +236,7 @@  static av_always_inline av_const int64_t ff_rint64_clip(double a, int64_t amin,
 {
     int64_t res;
 #if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
-    if (amin > amax) abort();
+    if (amin > amax) av_abort();
 #endif
     // INT64_MAX+1,INT64_MIN are exactly representable as IEEE doubles
     // do range checks first
diff --git a/libavutil/softfloat.h b/libavutil/softfloat.h
index a651406f74..f220e69bfb 100644
--- a/libavutil/softfloat.h
+++ b/libavutil/softfloat.h
@@ -211,7 +211,7 @@  static av_always_inline SoftFloat av_sqrt_sf(SoftFloat val)
     if (val.mant == 0)
         val.exp = MIN_EXP;
     else if (val.mant < 0)
-        abort();
+        av_abort();
     else
     {
         tabIndex = (val.mant - 0x20000000) >> 20;
diff --git a/libavutil/thread.h b/libavutil/thread.h
index 7106fd0d47..464fbe6996 100644
--- a/libavutil/thread.h
+++ b/libavutil/thread.h
@@ -33,6 +33,7 @@ 
 
 #include <stdlib.h>
 
+#include "abort.h"
 #include "error.h"
 #include "log.h"
 #include "macros.h"
@@ -43,7 +44,7 @@ 
            " failed with error: %s\n",                                  \
            av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE,       \
                                 AVERROR(ret)));                         \
-    abort();                                                            \
+    av_abort_internal();                                                            \
 } while (0)
 
 #define ASSERT_PTHREAD_NORET(func, ...) do {                            \
diff --git a/libavutil/version.c b/libavutil/version.c
index b0f4f94a7a..971335a779 100644
--- a/libavutil/version.c
+++ b/libavutil/version.c
@@ -20,6 +20,7 @@ 
 
 #include <stdlib.h>
 
+#include "abort.h"
 #include "config.h"
 #include "avassert.h"
 #include "avutil.h"
@@ -49,7 +50,7 @@  unsigned avutil_version(void)
 
     if (av_sat_dadd32(1, 2) != 5) {
         av_log(NULL, AV_LOG_FATAL, "Libavutil has been built with a broken binutils, please upgrade binutils and rebuild\n");
-        abort();
+        av_abort();
     }
 
     if (llrint(1LL<<60) != 1LL<<60) {
diff --git a/libavutil/x86/intmath.h b/libavutil/x86/intmath.h
index 8a6b5ae261..d729c3c800 100644
--- a/libavutil/x86/intmath.h
+++ b/libavutil/x86/intmath.h
@@ -30,6 +30,7 @@ 
 #include <immintrin.h>
 #endif
 #endif
+#include "../abort.h"
 #include "config.h"
 
 #if HAVE_FAST_CLZ
@@ -108,7 +109,7 @@  static av_always_inline av_const unsigned av_mod_uintp2_bmi2(unsigned a, unsigne
 static av_always_inline av_const double av_clipd_sse2(double a, double amin, double amax)
 {
 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
-    if (amin > amax) abort();
+    if (amin > amax) av_abort();
 #endif
     __asm__ ("maxsd %1, %0 \n\t"
              "minsd %2, %0 \n\t"
@@ -124,7 +125,7 @@  static av_always_inline av_const double av_clipd_sse2(double a, double amin, dou
 static av_always_inline av_const float av_clipf_sse(float a, float amin, float amax)
 {
 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
-    if (amin > amax) abort();
+    if (amin > amax) av_abort();
 #endif
     __asm__ ("maxss %1, %0 \n\t"
              "minss %2, %0 \n\t"
@@ -141,7 +142,7 @@  static av_always_inline av_const float av_clipf_sse(float a, float amin, float a
 static av_always_inline av_const double av_clipd_avx(double a, double amin, double amax)
 {
 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
-    if (amin > amax) abort();
+    if (amin > amax) av_abort();
 #endif
     __asm__ ("vmaxsd %1, %0, %0 \n\t"
              "vminsd %2, %0, %0 \n\t"
@@ -154,7 +155,7 @@  static av_always_inline av_const double av_clipd_avx(double a, double amin, doub
 static av_always_inline av_const float av_clipf_avx(float a, float amin, float amax)
 {
 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
-    if (amin > amax) abort();
+    if (amin > amax) av_abort();
 #endif
     __asm__ ("vmaxss %1, %0, %0 \n\t"
              "vminss %2, %0, %0 \n\t"
diff --git a/libavutil/x86/w64xmmtest.h b/libavutil/x86/w64xmmtest.h
index a4a05b0419..8171baaff5 100644
--- a/libavutil/x86/w64xmmtest.h
+++ b/libavutil/x86/w64xmmtest.h
@@ -66,7 +66,7 @@ 
                        av_bswap64(xmm[1][i][0]),                \
                        av_bswap64(xmm[1][i][1]));               \
             }                                                   \
-        abort();                                                \
+        av_abort();                                             \
     }                                                           \
     return ret