【问题标题】:Stepping Over in Emacs GDB跨过 Emacs GDB
【发布时间】:2010-05-18 19:00:27
【问题描述】:

我在 GDB 中跨步时遇到了一些问题。我已经从 ffmpeg 库中构建了一个示例程序,其中调试符号打开并剥离。尽管我将 ffmpeg 库配置为静态并明确禁用共享,但看起来我正在调试的程序正在动态链接,因为它的文件大小只有 99kB。我不知道这是问题,但想提一下。

在 av_seek_frame 中设置并命中断点后,我使用“下一步”命令跳过。但是,这会进入 av_seek_frame() 中的第一个函数,如下所示。此外,如果 a 执行第二个“下一步”,则回溯会丢失它所在的位置。我设置错了吗?我怎么能跨过去?我应该注意我仔细检查了'set step-mode off'是否默认关闭(因为我相信这会在没有调试信息的第一段代码处中断。)

Breakpoint 1, av_seek_frame (s=0x16429000, stream_index=0, timestamp=29727438, flags=0) at l
(gdb) list
1648
1649        return 0;
1650    }
1651
1652    int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags
1653    {
1654        int ret;
1655        AVStream *st;
1656
1657        ff_read_frame_flush(s);
(gdb) next
ff_read_frame_flush (s=0x16429000) at libavformat/utils.c:1248
(gdb) list
1243
1244    /**
1245     * Flush the frame reader.
1246     **/
1247    void ff_read_frame_flush(AVFormatContext *s)
1248    {
1249        AVStream *st;
1250        int i, j;
1251
1252        flush_packet_queue(s);
(gdb) next
ff_read_frame_flush (s=0x16429000) at libavformat/utils.c:1252
(gdb) where
#0  ff_read_frame_flush (s=0x16429000) at libavformat/utils.c:1252
#1  0x00000000 in ?? ()

【问题讨论】:

  • 你是用-fomit-frame-pointer构建的吗?
  • 我不这么认为,但这是可能的,因为我对基于 unix 风格配置的构建不太满意。我的配置选项(构建 ffmpeg 库和我正在调试的 ffplay 示例是:) ./configure --enable-libmp3lame --enable-static --enable-pthreads --enable-ffplay --disable-shared --禁用优化 --disable-mmx --disable-stripping --enable-debug
  • 尝试检查 show step-mode - 我不使用 emacs,所以不确定它的默认值是什么。
  • 你确定你的二进制文件和源代码是同步的吗?
  • 就是这样,谢谢。我只使用'make'进行重建。做一个'make clean'然后'make'再次修复了一切。如果您想发布答案,我会接受。

标签: c debugging emacs gdb ffmpeg


【解决方案1】:

如果您不确定您的二进制文件是否是静态链接的,您可以使用 ldd 检查它并看到如下消息:

% ldd ffmpeg
        not a dynamic executable

接下来,确保您为 gdb 提供了可执行文件的完整路径,这样您就不会意外拾取安装在系统其他地方的二进制文件,而该二进制文件恰好位于您的 PATH 中。

您很可能加载了错误的二进制文件。即使 没有 使用 --disable-stripping 和 --disable-optimizations 我也可以使用 stepnext 命令很好地使用 gdb。您不需要使用 --disable-stripping,因为在 gdb 中您可以使用 ffmpeg_g 二进制文件(或者如果您碰巧运行 ffmpeg 二进制文件,您可以使用 file ffmpeg_g 从其中加载符号)。

出于调试目的,最好使用 --disable-optimizations 以便在检查变量时不会得到value optimized out,但严格来说,您不需要使用该选项来获取 emacs/gdb 的行为... 使用优化时,我在单步执行代码时没有问题。

但是,在 Emacs 中使用 gud/gdb 设置断点时,需要记住一件事,这可能会导致混淆:gud-break 命令仅使用文件名的基本部分来设置断点,而不是绝对它的路径,在 ffmpeg 的情况下,这意味着例如,如果您在 utils.c 中设置断点,它可能无法正常工作,具体取决于您在 gdb 中设置的源代码搜索路径的值,因为 ffmpeg 有多个不同路径下名为 utils.c 的文件(其实一共有 5 个 utils.c 文件,每个 lib* 子目录一个)。默认情况下,搜索路径设置为 $cdir:$cwd,但如果您将其设置为 /path/to/ffmpeg:$cdir:$cwd 之类的内容,并且您尝试在 libavformat 的 utils.c 中设置断点,它可能会在 libavutil 中找到那个——在这种情况下,如果你很幸运,它会抱怨你要设置断点的行不存在(因为 libavutil 中的那个更短),或者它可能会在你想要的行,但是在错误的 utils.c 中。

gud/gdb 的这个问题应该被认为是一个错误。当我有时间时,我会为 gud-break/gud-format-command 提交一个补丁来解决这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多