以调试ffmpeg为例,演示gdb如何定位内存被修改

本文演示了使用gdb定位avformat_find_stream_info函数破坏codecpar变量的问题

1.查看音频或视频stream index【以下以视频为例】

./ffprobe demo.avi 2>&1 | grep Stream
Stream #0:0: Video: h264 (High) (H264 / 0x34363248), yuv420p(progressive), 1920x1080, 4021 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc

以上视频的stream index=0

2.修改ffmpeg,在avformat_find_stream_info中将codecpar置NULL

vim libavformat/utils.c -> avformat_find_stream_info

av_opt_set(ic, "skip_clear", "1", AV_OPT_SEARCH_CHILDREN);
ic->streams[0]->codecpar=NULL;  //*破坏 codecpar
max_stream_analyze_duration = max_analyze_duration;

3.编译ffmpeg debug版本

./configure --enable-debug
make -j

4.启动gdb

gdb --args ./ffmpeg_g -i demo.avi  -qp 10  out.avi -y

5.在avformat_find_stream_info下断点

(gdb) b avformat_find_stream_info
Breakpoint 1 at 0x7ce180: file libavformat/utils.c, line 3623.

6.运行

(gdb) r
Starting program: ./ffmpeg_g -i demo.avi -qp 10 out.avi -y
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
ffmpeg version n4.3.4 Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-44)
  configuration: --enable-debug
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100

Breakpoint 1, avformat_find_stream_info (ic=0x22ca500, options=0x22cc500) at libavformat/utils.c:3623
warning: Source file is more recent than executable.
3623    {
Missing separate debuginfos, use: debuginfo-install bzip2-libs-1.0.6-13.el7.x86_64 glibc-2.17-326.el7_9.x86_64 libXau-1.0.8-2.1.el7.x86_64 libdrm-2.4.91-3.el7.x86_64 libva-1.8.3-1.el7.x86_64 libxcb-1.13-1.el7.x86_64 zlib-1.2.7-19.el7_9.x86_64

7.查看变量

 (gdb) print(*(AVFormatContext*)ic)
$1 = {av_class = 0x128d300 <av_format_context_class>, iformat = 0x1892fe0 <ff_avi_demuxer>, oformat = 0x0, priv_data = 0x22cb040, pb = 0x22d31c0, ctx_flags = 0, nb_streams = 1, streams = 0x22cb100,
  filename = "demo.avi", '\000' <repeats 1009 times>, url = 0x22cacc0 "demo.avi", start_time = -9223372036854775808, duration = -9223372036854775808, bit_rate = 0, packet_size = 0, max_delay = -1, flags = 2097156,
  probesize = 5000000, max_analyze_duration = 0, key = 0x0, keylen = 0, nb_programs = 0, programs = 0x0, video_codec_id = AV_CODEC_ID_NONE, audio_codec_id = AV_CODEC_ID_NONE, subtitle_codec_id = AV_CODEC_ID_NONE,
  max_index_size = 1048576, max_picture_buffer = 3041280, nb_chapters = 0, chapters = 0x0, metadata = 0x22cc440, start_time_realtime = -9223372036854775808, fps_probe_size = -1, error_recognition = 1, interrupt_callback = {
    callback = 0x4a5fa0 <decode_interrupt_cb>, opaque = 0x0}, debug = 0, max_interleave_delta = 10000000, strict_std_compliance = 0, event_flags = 0, max_ts_probe = 50, avoid_negative_ts = -1, ts_id = 0, audio_preload = 0,
  max_chunk_duration = 0, max_chunk_size = 0, use_wallclock_as_timestamps = 0, avio_flags = 0, duration_estimation_method = AVFMT_DURATION_FROM_PTS, skip_initial_bytes = 0, correct_ts_overflow = 1, seek2any = 0,
  flush_packets = -1, probe_score = 100, format_probesize = 1048576, codec_whitelist = 0x0, format_whitelist = 0x0, internal = 0x22cab80, io_repositioned = 0, video_codec = 0x0, audio_codec = 0x0, subtitle_codec = 0x0,
  data_codec = 0x0, metadata_header_padding = -1, opaque = 0x0, control_message_cb = 0x0, output_ts_offset = 0, dump_separator = 0x22ca010 ", ", data_codec_id = AV_CODEC_ID_NONE, open_cb = 0x0,
  protocol_whitelist = 0x22ca2b0 "file,crypto,data", io_open = 0x77bdf0 <io_open_default>, io_close = 0x77bde0 <io_close_default>, protocol_blacklist = 0x0, max_streams = 1000, skip_estimate_duration_from_pts = 0,
  max_probe_packets = 2500}
(gdb) print(*(AVStream *)((*(AVFormatContext*)ic)->streams[0]))
$2 = {index = 0, id = 0, codec = 0x22cb580, priv_data = 0x22cbf00, time_base = {num = 1, den = 25}, start_time = 0, duration = 1656, nb_frames = 1656, disposition = 0, discard = AVDISCARD_DEFAULT, sample_aspect_ratio = {num = 0,
    den = 1}, metadata = 0x0, avg_frame_rate = {num = 25, den = 1}, attached_pic = {buf = 0x0, pts = 0, dts = 0, data = 0x0, size = 0, stream_index = 0, flags = 0, side_data = 0x0, side_data_elems = 0, duration = 0, pos = 0,
    convergence_duration = 0}, side_data = 0x0, nb_side_data = 0, event_flags = 0, r_frame_rate = {num = 0, den = 0}, recommended_encoder_configuration = 0x0, codecpar = 0x22cba00, info = 0x22cb4c0, pts_wrap_bits = 64,
  first_dts = -9223372036854775808, cur_dts = 9223090561878065151, last_IP_pts = -9223372036854775808, last_IP_duration = 0, probe_packets = 2500, codec_info_nb_frames = 0, need_parsing = AVSTREAM_PARSE_HEADERS, parser = 0x0,
  last_in_packet_buffer = 0x0, probe_data = {filename = 0x0, buf = 0x0, buf_size = 0, mime_type = 0x0}, pts_buffer = {-9223372036854775808 <repeats 17 times>}, index_entries = 0x22db2e0, nb_index_entries = 1656,
  index_entries_allocated_size = 41495, stream_identifier = 0, program_num = 0, pmt_version = 0, pmt_stream_idx = 0, interleaver_chunk_size = 0, interleaver_chunk_duration = 0, request_probe = 0, skip_to_keyframe = 0,
  skip_samples = 0, start_skip_samples = 0, first_discard_sample = 0, last_discard_sample = 0, nb_decoded_frames = 0, mux_ts_offset = 0, pts_wrap_reference = -9223372036854775808, pts_wrap_behavior = 0,
  update_initial_durations_done = 0, pts_reorder_error = {0 <repeats 17 times>}, pts_reorder_error_count = '\000' <repeats 16 times>, last_dts_for_order_check = -9223372036854775808, dts_ordered = 0 '\000',
  dts_misordered = 0 '\000', inject_global_side_data = 0, display_aspect_ratio = {num = 0, den = 0}, internal = 0x22cad00}
(gdb) print ((*(AVStream *)((*(AVFormatContext*)ic)->streams[0]))->codecpar)
$3 = (AVCodecParameters *) 0x22cba00
(gdb) print *(AVCodecParameters*)((*(AVStream *)((*(AVFormatContext*)ic)->streams[0]))->codecpar)
$4 = {codec_type = AVMEDIA_TYPE_VIDEO, codec_id = AV_CODEC_ID_H264, codec_tag = 875967048, extradata = 0x0, extradata_size = 0, format = -1, bit_rate = 4021700, bits_per_coded_sample = 24, bits_per_raw_sample = 0, profile = -99,
  level = -99, width = 1920, height = 1080, sample_aspect_ratio = {num = 0, den = 1}, field_order = AV_FIELD_UNKNOWN, color_range = AVCOL_RANGE_UNSPECIFIED, color_primaries = AVCOL_PRI_UNSPECIFIED,
  color_trc = AVCOL_TRC_UNSPECIFIED, color_space = AVCOL_SPC_UNSPECIFIED, chroma_location = AVCHROMA_LOC_UNSPECIFIED, video_delay = 0, channel_layout = 0, channels = 0, sample_rate = 0, block_align = 0, frame_size = 0,
  initial_padding = 0, trailing_padding = 0, seek_preroll = 0}

8.监控 codecpar 变量

(gdb) watch ((*(AVStream *)((*(AVFormatContext*)ic)->streams[0]))->codecpar)
Watchpoint 2: ((*(AVStream *)((*(AVFormatContext*)ic)->streams[0]))->codecpar)

9.继续运行【如果变量被修改,程序会停住】

(gdb) c
Continuing.
Watchpoint 2: ((*(AVStream *)((*(AVFormatContext*)ic)->streams[0]))->codecpar)

Old value = (AVCodecParameters *) 0x22cba00
New value = (AVCodecParameters *) 0x0
avformat_find_stream_info (ic=0x22ca500, options=0x22cc500) at libavformat/utils.c:3646
3646        if (!max_analyze_duration) {

10.查看调用栈

(gdb) bt
#0  avformat_find_stream_info (ic=0x22ca500, options=0x22cc500) at libavformat/utils.c:3646
#1  0x0000000000496e7b in open_input_file (o=o@entry=0x7fffffffe0a0, filename=<optimized out>) at fftools/ffmpeg_opt.c:1184
#2  0x000000000049b9cf in open_files (inout=0x1298fb1 "input", open_file=0x496290 <open_input_file>, l=<optimized out>, l=<optimized out>) at fftools/ffmpeg_opt.c:3299
#3  ffmpeg_parse_options (argc=argc@entry=7, argv=argv@entry=0x7fffffffe5a8) at fftools/ffmpeg_opt.c:3339
#4  0x000000000048f5fd in main (argc=7, argv=0x7fffffffe5a8) at fftools/ffmpeg.c:4849

10.查看代码上下文

(gdb) list
3641
3642        av_opt_set(ic, "skip_clear", "1", AV_OPT_SEARCH_CHILDREN);
3643        ic->streams[0]->codecpar=NULL;
3644        max_stream_analyze_duration = max_analyze_duration;
3645        max_subtitle_analyze_duration = max_analyze_duration;
3646        if (!max_analyze_duration) {
3647            max_stream_analyze_duration =
3648            max_analyze_duration        = 5*AV_TIME_BASE;
3649            max_subtitle_analyze_duration = 30*AV_TIME_BASE;
3650            if (!strcmp(ic->iformat->name, "flv"))

11.修复BUG

相关推荐

  1. 调试ffmpeg,演示gdb如何定位内存修改

    2024-03-17 07:10:03       40 阅读
  2. GDB调试技巧实战--release程序引入结构体定义

    2024-03-17 07:10:03       57 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-17 07:10:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-17 07:10:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-17 07:10:03       82 阅读
  4. Python语言-面向对象

    2024-03-17 07:10:03       91 阅读

热门阅读

  1. Python网络爬虫内容介绍

    2024-03-17 07:10:03       36 阅读
  2. k8s编排系统

    2024-03-17 07:10:03       38 阅读
  3. Github Gitlab SSH 密钥配置

    2024-03-17 07:10:03       43 阅读
  4. Elasticsearch快速检索的法宝: 倒排索引

    2024-03-17 07:10:03       41 阅读
  5. 数据挖掘与大数据的结合

    2024-03-17 07:10:03       40 阅读
  6. 记录一次业务遇到的sql问题

    2024-03-17 07:10:03       36 阅读
  7. 获取ArcGISPro中conda信息详情

    2024-03-17 07:10:03       41 阅读
  8. 指定函数为内置函数——个人练习

    2024-03-17 07:10:03       42 阅读
  9. unity-unity2d tilemap的基本使用笔记0.5.4000

    2024-03-17 07:10:03       36 阅读