Opened 12 months ago

Closed 4 months ago

#9331 closed defect (invalid)

invalid writing in libswscale.so

Reported by: chuliang_guo Owned by:
Priority: normal Component: swscale
Version: git-master Keywords:
Cc: chuliang_guo Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description (last modified by chuliang_guo)

I am trying to using the api from libswscale.so to extract one frame from the
sample video.
And the program crashed when process the sample video, see the output of gdb
and valgrind below.

source code for the c code


sample.c

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>

#include <stdio.h>

// compatibility with newer API
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 28, 1)
#define av_frame_alloc avcodec_alloc_frame
#define av_frame_free avcodec_free_frame
#endif

void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
  FILE *pFile;
  char szFilename[32];
  int y;

  // Open file
  sprintf(szFilename, "frame%08d.ppm", iFrame);
  pFile = fopen(szFilename, "wb");
  if (pFile == NULL)
    return;

  // Write header
  fprintf(pFile, "P6\n%d %d\n255\n", width, height);

  // Write pixel data
  for (y = 0; y < height; y++)
    fwrite(pFrame->data[0] + y * pFrame->linesize[0], 1, width * 3, pFile);

  // Close file
  fclose(pFile);
}

int main(int argc, char *argv[]) {
  // Initalizing these to NULL prevents segfaults!
  AVFormatContext *pFormatCtx = NULL;
  int i, videoStream;
  AVCodecContext *pCodecCtxOrig = NULL;
  AVCodecContext *pCodecCtx = NULL;

  AVCodecParameters *pCodePar = NULL;
  AVCodec *pCodec = NULL;

  AVFrame *pFrame = NULL;
  AVFrame *pFrameRGB = NULL;

  AVPacket packet;
  int frameFinished;
  int numBytes;
  uint8_t *buffer = NULL;
  struct SwsContext *sws_ctx = NULL;

  if (argc < 2) {
    printf("Please provide a movie file\n");
    return -1;
  }

  // Open video file
  if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0)
    return -1; // Couldn't open file

  // Retrieve stream information
  if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
    return -1; // Couldn't find stream information

// Dump information about file onto standard error
#ifdef DEBUG
  av_dump_format(pFormatCtx, 0, argv[1], 0);
#endif

  // Find the first video stream
  videoStream = -1;
  for (i = 0; i < pFormatCtx->nb_streams; i++)
    if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
      videoStream = i;
      break;
    }
  if (videoStream == -1) {
    fprintf(stderr, "couldn't find a video stream");
    return -1; // Didn't find a video stream
  }

  // Get a pointer to the codec context parameter for the video stream
  pCodePar = pFormatCtx->streams[videoStream]->codecpar;
  // Find the decoder for the video stream
  pCodec = avcodec_find_decoder(pCodePar->codec_id);
  if (pCodec == NULL) {
    fprintf(stderr, "Unsupported codec!\n");
    return -1; // Codec not found
  }
  // Copy context
  pCodecCtx = avcodec_alloc_context3(pCodec);
  if (avcodec_parameters_to_context(pCodecCtx, pCodePar) < 0) {
    fprintf(stderr, "Couldn't copy codec context");
    return -1; // Error copying codec context
  }

  // Open codec
  if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
    return -1; // Could not open codec

  // Allocate video frame
  pFrame = av_frame_alloc();

  // Allocate an AVFrame structure
  pFrameRGB = av_frame_alloc();
  if (pFrameRGB == NULL)
    return -1;

  // int width = (pCodecCtx->width/16+1)*16;
  // Determine required buffer size and allocate buffer
  // numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, width, pCodecCtx->height, 1);
  numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 1);
  buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));

  // Assign appropriate parts of buffer to image planes in pFrameRGB
  // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
  // of AVPicture
  av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, buffer,
                       AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height,
                       1);
  // initialize SWS context for software scaling
  sws_ctx = sws_getContext(
      pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,
      pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BILINEAR, NULL, NULL, NULL);

  // Read frames and save first five frames to disk
  i = 0;
  while (av_read_frame(pFormatCtx, &packet) >= 0) {
    // Is this a packet from the video stream?
    if (packet.stream_index == videoStream) {
      // Decode video frame
      int ret = avcodec_send_packet(pCodecCtx, &packet);
      if (ret < 0) {
        fprintf(stderr, "video error sending a packet");
        break;
      }
      while (ret >= 0) {
        ret = avcodec_receive_frame(pCodecCtx, pFrame);
        if (ret == AVERROR_EOF) {
          break;
        } else if (ret == AVERROR(EAGAIN)) {
          break;
        } else if (ret < 0) {
          fprintf(stderr, "Error during decoding\n");
          break;
        }

        // Convert the image from its native format to RGB
        sws_scale(sws_ctx, (uint8_t const *const *)pFrame->data,
                  pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data,
                  pFrameRGB->linesize);

        // Save the frame to disk
        // if(++i<=5)
        SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);
        i++;
      }
      if(i==1) break;
    }

    // Free the packet that was allocated by av_read_frame
    av_packet_unref(&packet);
  }

  sws_freeContext(sws_ctx);

  // Free the RGB image
  av_free(buffer);
  av_frame_free(&pFrameRGB);

  // Free the YUV frame
  av_frame_free(&pFrame);

  // Close the codecs
  avcodec_close(pCodecCtx);
  avcodec_close(pCodecCtxOrig);

  // Close the video file
  avformat_close_input(&pFormatCtx);

  return 0;
}

Makefile


all:sample
sample:sample.o
    gcc sample.o -o sample -L${HOME}/.local/lib -lswscale -lavformat -lavcodec
-lavutil -lswscale -lswresample
sample.o:sample.c
    gcc sample.c -g -c -o sample.o -I ${HOME}/.local/include
run:sample
    LD_LIBRARY_PATH=${HOME}/.local/lib ./sample crash.mp4
clean:
    rm *.o *.ppm -f
debug:
    LD_LIBRARY_PATH=${HOME}/.local/lib gdb --args ./sample crash.mp4

note: I compile the ffmpeg with following command

./configure --disable-static --disable-avdevice --disable-avfilter \
--disable-bzlib --enable-shared --enable-libvpx --enable-debug=3 \
--disable-stripping --prefix=$HOME/.local
make
make install

the commands for compiling the code are:

make
make run

the output of the program is:


LD_LIBRARY_PATH=/home/u/.local/lib ./sample crash.mp4
* Error in `./sample': corrupted double-linked list: 0x00000000010bfae0 *
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777f5)[0x7f82e0eb77f5]
/lib/x86_64-linux-gnu/libc.so.6(+0x80c81)[0x7f82e0ec0c81]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f82e0ec458c]
/home/u/.local/lib/libswscale.so.6(sws_freeContext+0x49)[0x7f82e1260889]
./sample[0x4015cc]
/lib/x86_64-linux-gnu/libc.so.6(libc_start_main+0xf0)[0x7f82e0e60840]
./sample[0x400ee9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:01 3945328 /home/u/source/sample
00601000-00602000 r--p 00001000 08:01 3945328 /home/u/source/sample
00602000-00603000 rw-p 00002000 08:01 3945328 /home/u/source/sample
01072000-011ea000 rw-p 00000000 00:00 0 [heap]
7f82d8000000-7f82d8021000 rw-p 00000000 00:00 0
7f82d8021000-7f82dc000000 ---p 00000000 00:00 0
7f82dfa83000-7f82dfa99000 r-xp 00000000 08:01 4067980 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f82dfa99000-7f82dfc98000 ---p 00016000 08:01 4067980 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f82dfc98000-7f82dfc99000 rw-p 00015000 08:01 4067980 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f82dfc99000-7f82dfc9c000 r-xp 00000000 08:01 4063318 /lib/x86_64-linux-gnu/libdl-2.23.so
7f82dfc9c000-7f82dfe9b000 ---p 00003000 08:01 4063318 /lib/x86_64-linux-gnu/libdl-2.23.so
7f82dfe9b000-7f82dfe9c000 r--p 00002000 08:01 4063318 /lib/x86_64-linux-gnu/libdl-2.23.so
7f82dfe9c000-7f82dfe9d000 rw-p 00003000 08:01 4063318 /lib/x86_64-linux-gnu/libdl-2.23.so
7f82dfe9d000-7f82dfebe000 r-xp 00000000 08:01 4068009 /lib/x86_64-linux-gnu/liblzma.so.5.0.0
7f82dfebe000-7f82e00bd000 ---p 00021000 08:01 4068009 /lib/x86_64-linux-gnu/liblzma.so.5.0.0
7f82e00bd000-7f82e00be000 r--p 00020000 08:01 4068009 /lib/x86_64-linux-gnu/liblzma.so.5.0.0
7f82e00be000-7f82e00bf000 rw-p 00021000 08:01 4068009 /lib/x86_64-linux-gnu/liblzma.so.5.0.0
7f82e00bf000-7f82e02de000 r-xp 00000000 08:01 5776643 /usr/lib/x86_64-linux-gnu/libvpx.so.3.0.0
7f82e02de000-7f82e04dd000 ---p 0021f000 08:01 5776643 /usr/lib/x86_64-linux-gnu/libvpx.so.3.0.0
7f82e04dd000-7f82e04df000 r--p 0021e000 08:01 5776643 /usr/lib/x86_64-linux-gnu/libvpx.so.3.0.0
7f82e04df000-7f82e04e0000 rw-p 00220000 08:01 5776643 /usr/lib/x86_64-linux-gnu/libvpx.so.3.0.0
7f82e04e0000-7f82e04e3000 rw-p 00000000 00:00 0
7f82e04e3000-7f82e04fd000 r-xp 00000000 08:01 4463252 /home/u/.local/lib/libswresample.so.4.0.100
7f82e04fd000-7f82e06fd000 ---p 0001a000 08:01 4463252 /home/u/.local/lib/libswresample.so.4.0.100
7f82e06fd000-7f82e06ff000 r--p 0001a000 08:01 4463252 /home/u/.local/lib/libswresample.so.4.0.100
7f82e06ff000-7f82e0700000 rw-p 0001c000 08:01 4463252 /home/u/.local/lib/libswresample.so.4.0.100
7f82e0700000-7f82e0718000 r-xp 00000000 08:01 4063257 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f82e0718000-7f82e0917000 ---p 00018000 08:01 4063257 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f82e0917000-7f82e0918000 r--p 00017000 08:01 4063257 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f82e0918000-7f82e0919000 rw-p 00018000 08:01 4063257 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f82e0919000-7f82e091d000 rw-p 00000000 00:00 0
7f82e091d000-7f82e0936000 r-xp 00000000 08:01 4068133 /lib/x86_64-linux-gnu/libz.so.1.2.8
7f82e0936000-7f82e0b35000 ---p 00019000 08:01 4068133 /lib/x86_64-linux-gnu/libz.so.1.2.8
7f82e0b35000-7f82e0b36000 r--p 00018000 08:01 4068133 /lib/x86_64-linux-gnu/libz.so.1.2.8
7f82e0b36000-7f82e0b37000 rw-p 00019000 08:01 4068133 /lib/x86_64-linux-gnu/libz.so.1.2.8
7f82e0b37000-7f82e0c3f000 r-xp 00000000 08:01 4063326 /lib/x86_64-linux-gnu/libm-2.23.so
7f82e0c3f000-7f82e0e3e000 ---p 00108000 08:01 4063326 /lib/x86_64-linux-gnu/libm-2.23.so
7f82e0e3e000-7f82e0e3f000 r--p 00107000 08:01 4063326 /lib/x86_64-linux-gnu/libm-2.23.so
7f82e0e3f000-7f82e0e40000 rw-p 00108000 08:01 4063326 /lib/x86_64-linux-gnu/libm-2.23.so
7f82e0e40000-7f82e1000000 r-xp 00000000 08:01 4067959 /lib/x86_64-linux-gnu/libc-2.23.so
7f82e1000000-7f82e1200000 ---p 001c0000 08:01 4067959 /lib/x86_64-linux-gnu/libc-2.23.so
7f82e1200000-7f82e1204000 r--p 001c0000 08:01 4067959 /lib/x86_64-linux-gnu/libc-2.23.so
7f82e1204000-7f82e1206000 rw-p 001c4000 08:01 4067959 /lib/x86_64-linux-gnu/libc-2.23.so
7f82e1206000-7f82e120a000 rw-p 00000000 00:00 0
7f82e120a000-7f82e1292000 r-xp 00000000 08:01 4463254 /home/u/.local/lib/libswscale.so.6.0.100
7f82e1292000-7f82e1492000 ---p 00088000 08:01 4463254 /home/u/.local/lib/libswscale.so.6.0.100
7f82e1492000-7f82e1493000 r--p 00088000 08:01 4463254 /home/u/.local/lib/libswscale.so.6.0.100
7f82e1493000-7f82e1494000 rw-p 00089000 08:01 4463254 /home/u/.local/lib/libswscale.so.6.0.100
7f82e1494000-7f82e149c000 rw-p 00000000 00:00 0
7f82e149c000-7f82e153e000 r-xp 00000000 08:01 4463256 /home/u/.local/lib/libavutil.so.57.0.100
7f82e153e000-7f82e173e000 ---p 000a2000 08:01 4463256 /home/u/.local/lib/libavutil.so.57.0.100
7f82e173e000-7f82e1746000 r--p 000a2000 08:01 4463256 /home/u/.local/lib/libavutil.so.57.0.100
7f82e1746000-7f82e1747000 rw-p 000aa000 08:01 4463256 /home/u/.local/lib/libavutil.so.57.0.100
7f82e1747000-7f82e1856000 rw-p 00000000 00:00 0
7f82e1856000-7f82e252a000 r-xp 00000000 08:01 4463250 /home/u/.local/lib/libavcodec.so.59.3.101
7f82e252a000-7f82e272a000 ---p 00cd4000 08:01 4463250 /home/u/.local/lib/libavcodec.so.59.3.101
7f82e272a000-7f82e2789000 r--p 00cd4000 08:01 4463250 /home/u/.local/lib/libavcodec.so.59.3.101
7f82e2789000-7f82e278c000 rw-p 00d33000 08:01 4463250 /home/u/.local/lib/libavcodec.so.59.3.101
7f82e278c000-7f82e2d5f000 rw-p 00000000 00:00 0
7f82e2d5f000-7f82e2fa5000 r-xp 00000000 08:01 4463247 /home/u/.local/lib/libavformat.so.59.4.100
7f82e2fa5000-7f82e31a5000 ---p 00246000 08:01 4463247 /home/u/.local/lib/libavformat.so.59.4.100
7f82e31a5000-7f82e31d4000 r--p 00246000 08:01 4463247 /home/u/.local/lib/libavformat.so.59.4.100
7f82e31d4000-7f82e31d5000 rw-p 00275000 08:01 4463247 /home/u/.local/lib/libavformat.so.59.4.100
7f82e31d5000-7f82e31d6000 rw-p 00000000 00:00 0
7f82e31d6000-7f82e31fc000 r-xp 00000000 08:01 4063323 /lib/x86_64-linux-gnu/ld-2.23.so
7f82e335d000-7f82e3385000 rw-p 00000000 00:00 0
7f82e33aa000-7f82e33d8000 rw-p 00000000 00:00 0
7f82e33f8000-7f82e33fb000 rw-p 00000000 00:00 0
7f82e33fb000-7f82e33fc000 r--p 00025000 08:01 4063323 /lib/x86_64-linux-gnu/ld-2.23.so
7f82e33fc000-7f82e33fd000 rw-p 00026000 08:01 4063323 /lib/x86_64-linux-gnu/ld-2.23.so
7f82e33fd000-7f82e33fe000 rw-p 00000000 00:00 0
7ffd00323000-7ffd00344000 rw-p 00000000 00:00 0 [stack]
7ffd003f4000-7ffd003f7000 r--p 00000000 00:00 0 [vvar]
7ffd003f7000-7ffd003f9000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted (core dumped)


and the valgrind commands and output is

LD_LIBRARY_PATH=/home/spectre/.local/lib valgrind --tool=memcheck --leak-check=full --num-callers=100 ./sample crash.mp4

==14608== Memcheck, a memory error detector
==14608== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==14608== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==14608== Command: ./sample crash.mp4
==14608==
--14608-- WARNING: Serious error when reading debug info
--14608-- When reading debug info from /home/u/.local/lib/libavcodec.so.59.3.101:
--14608-- get_Form_contents: DW_FORM_strp points outside .debug_str
--14608-- WARNING: Serious error when reading debug info
--14608-- When reading debug info from /home/u/.local/lib/libavutil.so.57.0.100:
--14608-- get_Form_contents: DW_FORM_strp points outside .debug_str
--14608-- WARNING: Serious error when reading debug info
--14608-- When reading debug info from /home/u/.local/lib/libswscale.so.6.0.100:
--14608-- get_Form_contents: DW_FORM_strp points outside .debug_str
--14608-- WARNING: Serious error when reading debug info
--14608-- When reading debug info from /home/u/.local/lib/libswresample.so.4.0.100:
--14608-- get_Form_contents: DW_FORM_strp points outside .debug_str
==14608== Invalid write of size 8
==14608== at 0x6BE4F96: ??? (in /home/u/.local/lib/libswscale.so.6.0.100)
==14608== by 0x6BE3B33: yuv420_rgb24_ssse3 (yuv2rgb_template.c:177)
==14608== by 0x6BB5D90: sws_scale (swscale.c:989)
==14608== by 0x401542: main (sample.c:152)
==14608== Address 0x86b9b5a is 306,714 bytes inside a block of size 306,720 alloc'd
==14608== at 0x4C2FFC6: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x4C300D1: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x67E960F: av_malloc (mem.c:87)
==14608== by 0x40137A: main (sample.c:116)
==14608==
==14608== Invalid write of size 8
==14608== at 0x6BE4F9B: ??? (in /home/u/.local/lib/libswscale.so.6.0.100)
==14608== by 0x6BE3B33: yuv420_rgb24_ssse3 (yuv2rgb_template.c:177)
==14608== by 0x6BB5D90: sws_scale (swscale.c:989)
==14608== by 0x401542: main (sample.c:152)
==14608== Address 0x86b9b62 is 2 bytes after a block of size 306,720 alloc'd
==14608== at 0x4C2FFC6: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x4C300D1: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x67E960F: av_malloc (mem.c:87)
==14608== by 0x40137A: main (sample.c:116)
==14608==
==14608==
==14608== HEAP SUMMARY:
==14608== in use at exit: 3,063 bytes in 5 blocks
==14608== total heap usage: 694 allocs, 689 frees, 4,138,888 bytes allocated
==14608==
==14608== 48 bytes in 1 blocks are indirectly lost in loss record 1 of 5
==14608== at 0x4C2FFC6: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x4C300D1: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x67E960F: av_malloc (mem.c:87)
==14608== by 0x67E96DD: av_mallocz (mem.c:246)
==14608== by 0x67D3ADC: av_buffer_create (buffer.c:36)
==14608== by 0x67D3BC6: av_buffer_alloc (buffer.c:76)
==14608== by 0x543C4F7: av_grow_packet (avpacket.c:148)
==14608== by 0x4FE9ABA: append_packet_chunked (utils.c:260)
==14608== by 0x4F29847: mov_read_packet (mov.c:7897)
==14608== by 0x4FEE6EF: ff_read_packet (utils.c:802)
==14608== by 0x4FEF2D4: read_frame_internal (utils.c:1492)
==14608== by 0x4FF405A: avformat_find_stream_info (utils.c:3746)
==14608== by 0x401180: main (sample.c:65)
==14608==
==14608== 105 bytes in 1 blocks are indirectly lost in loss record 2 of 5
==14608== at 0x4C2FFC6: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x4C300D1: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x67E960F: av_malloc (mem.c:87)
==14608== by 0x67E96DD: av_mallocz (mem.c:246)
==14608== by 0x54B7823: avcodec_parameters_to_context (codec_par.c:194)
==14608== by 0x4012BC: main (sample.c:95)
==14608==
==14608== 1,025 (920 direct, 105 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 5
==14608== at 0x4C2FFC6: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x4C300D1: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x67E960F: av_malloc (mem.c:87)
==14608== by 0x58532F2: avcodec_alloc_context3 (options.c:143)
==14608== by 0x40129F: main (sample.c:94)
==14608==
==14608== 1,966 bytes in 1 blocks are indirectly lost in loss record 4 of 5
==14608== at 0x4C2FFC6: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x4C300D1: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x67E960F: av_malloc (mem.c:87)
==14608== by 0x67D3BA5: av_buffer_alloc (buffer.c:72)
==14608== by 0x543C4F7: av_grow_packet (avpacket.c:148)
==14608== by 0x4FE9ABA: append_packet_chunked (utils.c:260)
==14608== by 0x4F29847: mov_read_packet (mov.c:7897)
==14608== by 0x4FEE6EF: ff_read_packet (utils.c:802)
==14608== by 0x4FEF2D4: read_frame_internal (utils.c:1492)
==14608== by 0x4FF405A: avformat_find_stream_info (utils.c:3746)
==14608== by 0x401180: main (sample.c:65)
==14608==
==14608== 2,038 (24 direct, 2,014 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 5
==14608== at 0x4C2FFC6: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x4C300D1: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14608== by 0x67E960F: av_malloc (mem.c:87)
==14608== by 0x67E96DD: av_mallocz (mem.c:246)
==14608== by 0x67D3B15: av_buffer_create (buffer.c:49)
==14608== by 0x67D3BC6: av_buffer_alloc (buffer.c:76)
==14608== by 0x543C4F7: av_grow_packet (avpacket.c:148)
==14608== by 0x4FE9ABA: append_packet_chunked (utils.c:260)
==14608== by 0x4F29847: mov_read_packet (mov.c:7897)
==14608== by 0x4FEE6EF: ff_read_packet (utils.c:802)
==14608== by 0x4FEF2D4: read_frame_internal (utils.c:1492)
==14608== by 0x4FF405A: avformat_find_stream_info (utils.c:3746)
==14608== by 0x401180: main (sample.c:65)
==14608==
==14608== LEAK SUMMARY:
==14608== definitely lost: 944 bytes in 2 blocks
==14608== indirectly lost: 2,119 bytes in 3 blocks
==14608== possibly lost: 0 bytes in 0 blocks
==14608== still reachable: 0 bytes in 0 blocks
==14608== suppressed: 0 bytes in 0 blocks
==14608==
==14608== For counts of detected and suppressed errors, rerun with: -v
==14608== ERROR SUMMARY: 5 errors from 4 contexts (suppressed: 0 from 0)


I tried to see the c code of libswscale.so.6.0.100 which causes the invalid
writing, so I reconfigure ffmpeg and compiled with following command.

./configure --disable-static --disable-avdevice --disable-avfilter \
--disable-bzlib --enable-shared --enable-libvpx --enable-debug=3 \
--disable-stripping --prefix=$HOME/.local
make
make install

but this time, with the new compiled shared library, the program runs well and
extract the first frame of the video and save it as picture.

So, I started using gdb to debug the assemble code in the function
ff_yuv_420_rgb24_ssse3, and at last I found the code is writen by assembler
language in the file libswscale/x86/yuv_2_rgb.asm, and the invalid writing is
in line 271 and 272 when write the values of m0 and m1 to memory


libswscale/x86/yuv_2_rgb.asm

268     por    m2, m7
269     por    m1, m6          ; g5  b5  r6  g6  b6  r7  g7  b7  r8  g8  b8  r9  g9  b9  r10 g10
270     por    m2, m3          ; b10 r11 g11 b11 r12 g12 b12 r13 g13 b13 r14 g14 b14 r15 g15 b15
271     movu [imageq], m0
272     movu [imageq + 16], m1
273     movu [imageq + 32], m2

gdb output


For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./sample...
(gdb) r
Starting program: /home/u/source/sample crash.mp4
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
* Error in `/home/u/source/sample': corrupted double-linked list: 0x0000000000650ae0 *
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777f5)[0x7ffff5ab87f5]
/lib/x86_64-linux-gnu/libc.so.6(+0x80c81)[0x7ffff5ac1c81]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7ffff5ac558c]
/home/u/.local/lib/libswscale.so.6(sws_freeContext+0x49)[0x7ffff5e61889]
/home/u/source/sample[0x4015cc]
/lib/x86_64-linux-gnu/libc.so.6(libc_start_main+0xf0)[0x7ffff5a61840]
/home/u/source/sample[0x400ee9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:01 3945328 /home/u/source/sample
00601000-00602000 r--p 00001000 08:01 3945328 /home/u/source/sample
00602000-00603000 rw-p 00002000 08:01 3945328 /home/u/source/sample
00603000-0077b000 rw-p 00000000 00:00 0 [heap]
7ffff0000000-7ffff0021000 rw-p 00000000 00:00 0
7ffff0021000-7ffff4000000 ---p 00000000 00:00 0
7ffff4684000-7ffff469a000 r-xp 00000000 08:01 4067980 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff469a000-7ffff4899000 ---p 00016000 08:01 4067980 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff4899000-7ffff489a000 rw-p 00015000 08:01 4067980 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff489a000-7ffff489d000 r-xp 00000000 08:01 4063318 /lib/x86_64-linux-gnu/libdl-2.23.so
7ffff489d000-7ffff4a9c000 ---p 00003000 08:01 4063318 /lib/x86_64-linux-gnu/libdl-2.23.so
7ffff4a9c000-7ffff4a9d000 r--p 00002000 08:01 4063318 /lib/x86_64-linux-gnu/libdl-2.23.so
7ffff4a9d000-7ffff4a9e000 rw-p 00003000 08:01 4063318 /lib/x86_64-linux-gnu/libdl-2.23.so
7ffff4a9e000-7ffff4abf000 r-xp 00000000 08:01 4068009 /lib/x86_64-linux-gnu/liblzma.so.5.0.0
7ffff4abf000-7ffff4cbe000 ---p 00021000 08:01 4068009 /lib/x86_64-linux-gnu/liblzma.so.5.0.0
7ffff4cbe000-7ffff4cbf000 r--p 00020000 08:01 4068009 /lib/x86_64-linux-gnu/liblzma.so.5.0.0
7ffff4cbf000-7ffff4cc0000 rw-p 00021000 08:01 4068009 /lib/x86_64-linux-gnu/liblzma.so.5.0.0
7ffff4cc0000-7ffff4edf000 r-xp 00000000 08:01 5776643 /usr/lib/x86_64-linux-gnu/libvpx.so.3.0.0
7ffff4edf000-7ffff50de000 ---p 0021f000 08:01 5776643 /usr/lib/x86_64-linux-gnu/libvpx.so.3.0.0
7ffff50de000-7ffff50e0000 r--p 0021e000 08:01 5776643 /usr/lib/x86_64-linux-gnu/libvpx.so.3.0.0
7ffff50e0000-7ffff50e1000 rw-p 00220000 08:01 5776643 /usr/lib/x86_64-linux-gnu/libvpx.so.3.0.0
7ffff50e1000-7ffff50e4000 rw-p 00000000 00:00 0
7ffff50e4000-7ffff50fe000 r-xp 00000000 08:01 4463252 /home/u/.local/lib/libswresample.so.4.0.100
7ffff50fe000-7ffff52fe000 ---p 0001a000 08:01 4463252 /home/u/.local/lib/libswresample.so.4.0.100
7ffff52fe000-7ffff5300000 r--p 0001a000 08:01 4463252 /home/u/.local/lib/libswresample.so.4.0.100
7ffff5300000-7ffff5301000 rw-p 0001c000 08:01 4463252 /home/u/.local/lib/libswresample.so.4.0.100
7ffff5301000-7ffff5319000 r-xp 00000000 08:01 4063257 /lib/x86_64-linux-gnu/libpthread-2.23.so
7ffff5319000-7ffff5518000 ---p 00018000 08:01 4063257 /lib/x86_64-linux-gnu/libpthread-2.23.so
7ffff5518000-7ffff5519000 r--p 00017000 08:01 4063257 /lib/x86_64-linux-gnu/libpthread-2.23.so
7ffff5519000-7ffff551a000 rw-p 00018000 08:01 4063257 /lib/x86_64-linux-gnu/libpthread-2.23.so
7ffff551a000-7ffff551e000 rw-p 00000000 00:00 0
7ffff551e000-7ffff5537000 r-xp 00000000 08:01 4068133 /lib/x86_64-linux-gnu/libz.so.1.2.8
7ffff5537000-7ffff5736000 ---p 00019000 08:01 4068133 /lib/x86_64-linux-gnu/libz.so.1.2.8
7ffff5736000-7ffff5737000 r--p 00018000 08:01 4068133 /lib/x86_64-linux-gnu/libz.so.1.2.8
7ffff5737000-7ffff5738000 rw-p 00019000 08:01 4068133 /lib/x86_64-linux-gnu/libz.so.1.2.8
7ffff5738000-7ffff5840000 r-xp 00000000 08:01 4063326 /lib/x86_64-linux-gnu/libm-2.23.so
7ffff5840000-7ffff5a3f000 ---p 00108000 08:01 4063326 /lib/x86_64-linux-gnu/libm-2.23.so
7ffff5a3f000-7ffff5a40000 r--p 00107000 08:01 4063326 /lib/x86_64-linux-gnu/libm-2.23.so
7ffff5a40000-7ffff5a41000 rw-p 00108000 08:01 4063326 /lib/x86_64-linux-gnu/libm-2.23.so
7ffff5a41000-7ffff5c01000 r-xp 00000000 08:01 4067959 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff5c01000-7ffff5e01000 ---p 001c0000 08:01 4067959 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff5e01000-7ffff5e05000 r--p 001c0000 08:01 4067959 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff5e05000-7ffff5e07000 rw-p 001c4000 08:01 4067959 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff5e07000-7ffff5e0b000 rw-p 00000000 00:00 0
7ffff5e0b000-7ffff5e93000 r-xp 00000000 08:01 4463254 /home/u/.local/lib/libswscale.so.6.0.100
7ffff5e93000-7ffff6093000 ---p 00088000 08:01 4463254 /home/u/.local/lib/libswscale.so.6.0.100
7ffff6093000-7ffff6094000 r--p 00088000 08:01 4463254 /home/u/.local/lib/libswscale.so.6.0.100
7ffff6094000-7ffff6095000 rw-p 00089000 08:01 4463254 /home/u/.local/lib/libswscale.so.6.0.100
7ffff6095000-7ffff609d000 rw-p 00000000 00:00 0
7ffff609d000-7ffff613f000 r-xp 00000000 08:01 4463256 /home/u/.local/lib/libavutil.so.57.0.100
7ffff613f000-7ffff633f000 ---p 000a2000 08:01 4463256 /home/u/.local/lib/libavutil.so.57.0.100
7ffff633f000-7ffff6347000 r--p 000a2000 08:01 4463256 /home/u/.local/lib/libavutil.so.57.0.100
7ffff6347000-7ffff6348000 rw-p 000aa000 08:01 4463256 /home/u/.local/lib/libavutil.so.57.0.100
7ffff6348000-7ffff6457000 rw-p 00000000 00:00 0
7ffff6457000-7ffff712b000 r-xp 00000000 08:01 4463250 /home/u/.local/lib/libavcodec.so.59.3.101
7ffff712b000-7ffff732b000 ---p 00cd4000 08:01 4463250 /home/u/.local/lib/libavcodec.so.59.3.101
7ffff732b000-7ffff738a000 r--p 00cd4000 08:01 4463250 /home/u/.local/lib/libavcodec.so.59.3.101
7ffff738a000-7ffff738d000 rw-p 00d33000 08:01 4463250 /home/u/.local/lib/libavcodec.so.59.3.101
7ffff738d000-7ffff7960000 rw-p 00000000 00:00 0
7ffff7960000-7ffff7ba6000 r-xp 00000000 08:01 4463247 /home/u/.local/lib/libavformat.so.59.4.100
7ffff7ba6000-7ffff7da6000 ---p 00246000 08:01 4463247 /home/u/.local/lib/libavformat.so.59.4.100
7ffff7da6000-7ffff7dd5000 r--p 00246000 08:01 4463247 /home/u/.local/lib/libavformat.so.59.4.100
7ffff7dd5000-7ffff7dd6000 rw-p 00275000 08:01 4463247 /home/u/.local/lib/libavformat.so.59.4.100
7ffff7dd6000-7ffff7dd7000 rw-p 00000000 00:00 0
7ffff7dd7000-7ffff7dfd000 r-xp 00000000 08:01 4063323 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7f59000-7ffff7f81000 rw-p 00000000 00:00 0
7ffff7fa6000-7ffff7fd4000 rw-p 00000000 00:00 0
7ffff7ff4000-7ffff7ff7000 rw-p 00000000 00:00 0
7ffff7ff7000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00025000 08:01 4063323 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffd000-7ffff7ffe000 rw-p 00026000 08:01 4063323 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

Program received signal SIGABRT, Aborted.
0x00007ffff5a76438 in raise () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007ffff5a76438 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff5a7803a in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff5ab87fa in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007ffff5ac1c81 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007ffff5ac558c in free () from /lib/x86_64-linux-gnu/libc.so.6
#5 0x00007ffff5e61889 in sws_freeContext (c=0x619680) at libswscale/utils.c:2253
#6 0x00000000004015cc in main (argc=2, argv=0x7fffffffe048) at sample.c:168
(gdb) info registers
rax 0x0 0
rbx 0x5b 91
rcx 0x7ffff5a76438 140737314776120
rdx 0x6 6
rsi 0x3963 14691
rdi 0x3963 14691
rbp 0x7fffffffdd80 0x7fffffffdd80
rsp 0x7fffffffd9e8 0x7fffffffd9e8
r8 0x5 5
r9 0x0 0
r10 0x8 8
r11 0x206 518
r12 0x5b 91
r13 0x7fffffffdb98 140737488346008
r14 0x7fffffffdb98 140737488346008
r15 0x2 2
rip 0x7ffff5a76438 0x7ffff5a76438 <raise+56>
eflags 0x206 [ PF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0


After analysis of the assembly code, I found what is wrong about this code, the
assembly code accelerates the process of convert yuv to rgb by using sse2 register
and write 16 rgb values (48 bytes) to memory once a time, and the resolution of
the crash.mp4 is 426*240, and ff_yuv_420_rgb24_ssse3 process 426 pixels in a
loop, which induces the problem: when the width of video frame is not a multiply
of 16, extra wrong yuv pixel is read from the memory and writing extra rgb value
to the memory allocated for the output image and cause the invalid writing.

and I found the solution to my problem, when I call av_image_get_buffer_size
the width of the image is change to a larger value which is a multiply of 16

int width = (pCodecCtx->width/16+1)*16;
numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, width, pCodecCtx->height, 1);

But I think the change of width should be implemented inside the av_image_get_buffer_size
function, or changing assembly code ff_yuv_420_rgb24_ssse3 to process image without size
limitation.

Attachments (1)

crash.mp4 (212.3 KB ) - added by chuliang_guo 12 months ago.

Download all attachments as: .zip

Change History (4)

by chuliang_guo, 12 months ago

Attachment: crash.mp4 added

comment:1 by chuliang_guo, 12 months ago

Description: modified (diff)

comment:2 by chuliang_guo, 12 months ago

Description: modified (diff)

comment:3 by Elon Musk, 4 months ago

Resolution: invalid
Status: newclosed

Your buffer is not properly aligned for swscale library, this is even mentioned in documentation.

Use av_cpu_max_align() as last parameter to av_image_get_buffer_size() instead of no-alignment at all which is value of 1.

Note: See TracTickets for help on using tickets.