Stepping Over in Emacs GDB
I'm having some trouble stepping over in GDB. I've built an example program from the ffmpeg library with debug symbols on and stripping off. Although I configured the ffmpeg library to static and explicitly disabled shared, it looks like the program I'm debugging is linking dynamically, since its file size is only 99kB. I don't know that this is the issue but thought to mention it.
After I set and hit a breakpoint in av_seek_frame, I use the 'next' command to step over. However, this steps into the first function within av_seek_frame(), as you can see below. Furthermore if a do a second 'next', the backtrace looses track of where it is. Am I set up wrong? How can I step over? I should note I double checked that 'set step-mode off' is off as the default (as I believe this will break at the first pi开发者_StackOverflowece of code without debug info.)
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 ?? ()
If you're not sure whether or not your binary is statically linked, you can check it with ldd and see a message like this:
% ldd ffmpeg
not a dynamic executable
Next, make sure that you give gdb the full path to the executable so that you're not accidentally picking up a binary installed elsewhere on the system that happens to be in your PATH.
Most likely you're loading the wrong binary. Even without using --disable-stripping and --disable-optimizations I can use gdb fine using both step
and next
commands. You don't need to use --disable-stripping because inside gdb you can use the ffmpeg_g binary (or if you happen to run the ffmpeg binary you can load the symbols from it using file ffmpeg_g
).
For debugging purposes it is nice to use the --disable-optimizations so that you don't get value optimized out
when inspecting variables, but strictly speaking you don't need to use the option to get emacs/gdb to behave... I have no problems stepping through the code when optimizations are used.
There is one things to keep in mind, though, when setting breakpoints with gud/gdb inside of Emacs that might lead to confusion: the gud-break
command uses only the base part of the filename for setting breakpoints, not the absolute path to it, which in the case of ffmpeg means that if, for example, you set a breakpoint in utils.c it might not work correctly depending on the value of the source code search paths that you have set in gdb because ffmpeg has multiple files named utils.c in different paths (in fact, there are a total of 5 utils.c files, one in each of the lib* subdirectories) . By default the search path is set to $cdir:$cwd, but if you have it set to something like /path/to/ffmpeg:$cdir:$cwd and you try to set a breakpoint in the utils.c of libavformat, it might find the one in libavutil-- in which case if you're lucky it will complain that the line where you want to set a breakpoint does not exist (because the one in libavutil is shorter), or it might set a breakpoint on the line you want, but in the wrong utils.c.
This issue with gud/gdb should be considered a bug. When I get a moment I'll submit a patch for gud-break/gud-format-command to fix the problem.
精彩评论