From e79f7307a0f71f50f06e9a0ea9f2dffbcf53a996 Mon Sep 17 00:00:00 2001 From: Kevin Buettner Date: Nov 11 2021 20:28:51 +0000 Subject: Backport upstream fix and test case for a dprintf bug (RHBZ 2022177) --- diff --git a/.gitignore b/.gitignore index 8ad67cd..e8a3ba8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/binutils-gdb +/new-fedora-release /gdb-libstdc++-v3-python-8.1.1-20180626.tar.xz /v2.0.4.tar.gz -/gdb-10.2.tar.xz +/gdb-11.1.tar.xz diff --git a/_gdb.spec.Patch.include b/_gdb.spec.Patch.include index 52da288..4884f06 100644 --- a/_gdb.spec.Patch.include +++ b/_gdb.spec.Patch.include @@ -326,5 +326,11 @@ Patch077: gdb-test-for-rhbz1976887.patch Patch078: gdb-rhbz2012976-paper-over-fortran-lex-problems.patch # Backport manpage update -Patch079: gdb-rhbz853071-update-manpages.patch +Patch079: gdb-rhbz-853071-update-manpages.patch + +# Backport fix for dprintf bug (RH BZ 2022177). +Patch080: gdb-rhbz2022177-dprintf-1.patch + +# Backport test case for dprintf bug (RH BZ 2022177). +Patch081: gdb-rhbz2022177-dprintf-2.patch diff --git a/_gdb.spec.patch.include b/_gdb.spec.patch.include index 0e32f14..8a8acc8 100644 --- a/_gdb.spec.patch.include +++ b/_gdb.spec.patch.include @@ -77,3 +77,5 @@ %patch077 -p1 %patch078 -p1 %patch079 -p1 +%patch080 -p1 +%patch081 -p1 diff --git a/_patch_order b/_patch_order index 203d8d9..863ee71 100644 --- a/_patch_order +++ b/_patch_order @@ -76,4 +76,6 @@ gdb-rhbz1553104-s390x-arch12-test.patch gdb-rhbz1976887-field-location-kind.patch gdb-test-for-rhbz1976887.patch gdb-rhbz2012976-paper-over-fortran-lex-problems.patch -gdb-rhbz853071-update-manpages.patch +gdb-rhbz-853071-update-manpages.patch +gdb-rhbz2022177-dprintf-1.patch +gdb-rhbz2022177-dprintf-2.patch diff --git a/gdb-rhbz-853071-update-manpages.patch b/gdb-rhbz-853071-update-manpages.patch new file mode 100644 index 0000000..7ceb67e --- /dev/null +++ b/gdb-rhbz-853071-update-manpages.patch @@ -0,0 +1,258 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Bruno Larsen +Date: Tue, 9 Nov 2021 14:07:26 -0300 +Subject: gdb-rhbz-853071-update-manpages.patch + +;; Backport manpage update + +[gdb/doc]: Updated manpages to be consistent with help + +Updated manpages to be consistent with help information provided by the +binary. The main changes are: + +* Making all long-form options have '--', instead of a single '-'; +* added most of the missing options to the manpage; +* removed the information about using '+' instead of '-', since it + doesn't seem to be supported anymore. + +This also fixes 2 upstream bugs: +* https://sourceware.org/bugzilla/show_bug.cgi?id=23965; by adding +--args to the manpage +* https://sourceware.org/bugzilla/show_bug.cgi?id=10619; by adding the +double dashes + +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -47030,14 +47030,7 @@ switch (die->tag) + @c man title gdb The GNU Debugger + + @c man begin SYNOPSIS gdb +-gdb [@option{-help}] [@option{-nh}] [@option{-nx}] [@option{-q}] +-[@option{-batch}] [@option{-cd=}@var{dir}] [@option{-f}] +-[@option{-b}@w{ }@var{bps}] +- [@option{-tty=}@var{dev}] [@option{-s} @var{symfile}] +-[@option{-e}@w{ }@var{prog}] [@option{-se}@w{ }@var{prog}] +-[@option{-c}@w{ }@var{core}] [@option{-p}@w{ }@var{procID}] +- [@option{-x}@w{ }@var{cmds}] [@option{-d}@w{ }@var{dir}] +-[@var{prog}|@var{prog} @var{procID}|@var{prog} @var{core}] ++gdb [OPTIONS] [@var{prog}|@var{prog} @var{procID}|@var{prog} @var{core}] + @c man end + + @c man begin DESCRIPTION gdb +@@ -47101,8 +47094,8 @@ Here are some of the most frequently needed @value{GDBN} commands: + + @c pod2man highlights the right hand side of the @item lines. + @table @env +-@item break [@var{file}:]@var{function} +-Set a breakpoint at @var{function} (in @var{file}). ++@item break [@var{file}:][@var{function}|@var{line}] ++Set a breakpoint at @var{function} or @var{line} (in @var{file}). + + @item run [@var{arglist}] + Start your program (with @var{arglist}, if specified). +@@ -47150,72 +47143,91 @@ as the @code{gdb} entry in the @code{info} program. + Any arguments other than options specify an executable + file and core file (or process ID); that is, the first argument + encountered with no +-associated option flag is equivalent to a @option{-se} option, and the second, ++associated option flag is equivalent to a @option{--se} option, and the second, + if any, is equivalent to a @option{-c} option if it's the name of a file. + Many options have +-both long and short forms; both are shown here. The long forms are also ++both long and abbreviated forms; both are shown here. The long forms are also + recognized if you truncate them, so long as enough of the option is +-present to be unambiguous. (If you prefer, you can flag option +-arguments with @option{+} rather than @option{-}, though we illustrate the +-more usual convention.) ++present to be unambiguous. ++ ++The abbreviated forms are shown here with @samp{-} and long forms are shown ++with @samp{--} to reflect how they are shown in @option{--help}. However, ++@value{GDBN} recognizes all of the following conventions for most options: ++ ++@table @code ++@item --option=@var{value} ++@item --option @var{value} ++@item -option=@var{value} ++@item -option @var{value} ++@item --o=@var{value} ++@item --o @var{value} ++@item -o=@var{value} ++@item -o @var{value} ++@end table + + All the options and command line arguments you give are processed + in sequential order. The order makes a difference when the @option{-x} + option is used. + + @table @env +-@item -help ++@item --help + @itemx -h + List all options, with brief explanations. + +-@item -symbols=@var{file} ++@item --symbols=@var{file} + @itemx -s @var{file} +-Read symbol table from file @var{file}. ++Read symbol table from @var{file}. + +-@item -write ++@item --write + Enable writing into executable and core files. + +-@item -exec=@var{file} ++@item --exec=@var{file} + @itemx -e @var{file} +-Use file @var{file} as the executable file to execute when ++Use @var{file} as the executable file to execute when + appropriate, and for examining pure data in conjunction with a core + dump. + +-@item -se=@var{file} +-Read symbol table from file @var{file} and use it as the executable ++@item --se=@var{file} ++Read symbol table from @var{file} and use it as the executable + file. + +-@item -core=@var{file} ++@item --core=@var{file} + @itemx -c @var{file} +-Use file @var{file} as a core dump to examine. ++Use @var{file} as a core dump to examine. + +-@item -command=@var{file} ++@item --command=@var{file} + @itemx -x @var{file} +-Execute @value{GDBN} commands from file @var{file}. ++Execute @value{GDBN} commands from @var{file}. + ++@item --eval-command=@var{command} + @item -ex @var{command} + Execute given @value{GDBN} @var{command}. + +-@item -directory=@var{directory} ++@item --init-eval-command=@var{command} ++@item -iex ++Execute @value{GDBN} @var{command} before loading the inferior. ++ ++@item --directory=@var{directory} + @itemx -d @var{directory} + Add @var{directory} to the path to search for source files. + +-@item -nh ++@item --nh + Do not execute commands from @file{~/.config/gdb/gdbinit}, + @file{~/.gdbinit}, @file{~/.config/gdb/gdbearlyinit}, or + @file{~/.gdbearlyinit} + +-@item -nx ++@item --nx + @itemx -n + Do not execute commands from any @file{.gdbinit} or + @file{.gdbearlyinit} initialization files. + +-@item -quiet ++@item --quiet ++@item --silent + @itemx -q + ``Quiet''. Do not print the introductory and copyright messages. These + messages are also suppressed in batch mode. + +-@item -batch ++@item --batch + Run in batch mode. Exit with status @code{0} after processing all the command + files specified with @option{-x} (and @file{.gdbinit}, if not inhibited). + Exit with nonzero status if an error occurs in executing the @value{GDBN} +@@ -47233,11 +47245,71 @@ Program exited normally. + (which is ordinarily issued whenever a program running under @value{GDBN} control + terminates) is not issued when running in batch mode. + +-@item -cd=@var{directory} ++@item --batch-silent ++Run in batch mode, just like @option{--batch}, but totally silent. All @value{GDBN} ++output is supressed (stderr is unaffected). This is much quieter than ++@option{--silent} and would be useless for an interactive session. ++ ++This is particularly useful when using targets that give @samp{Loading section} ++messages, for example. ++ ++Note that targets that give their output via @value{GDBN}, as opposed to writing ++directly to @code{stdout}, will also be made silent. ++ ++@item --args @var{prog} [@var{arglist}] ++Change interpretation of command line so that arguments following this ++option are passed as arguments to the inferior. As an example, take ++the following command: ++ ++@smallexample ++gdb ./a.out -q ++@end smallexample ++ ++@noindent ++It would start @value{GDBN} with @option{-q}, not printing the introductory message. On ++the other hand, using: ++ ++@smallexample ++gdb --args ./a.out -q ++@end smallexample ++ ++@noindent ++starts @value{GDBN} with the introductory message, and passes the option to the inferior. ++ ++@item --pid=@var{pid} ++Attach @value{GDBN} to an already running program, with the PID @var{pid}. ++ ++@item --tui ++Open the terminal user interface. ++ ++@item --readnow ++Read all symbols from the given symfile on the first access. ++ ++@item --readnever ++Do not read symbol files. ++ ++@item --dbx ++Run in DBX compatibility mode. ++ ++@item --return-child-result ++@value{GDBN}'s exit code will be the same as the child's exit code. ++ ++@item --configuration ++Print details about GDB configuration and then exit. ++ ++@item --version ++Print version information and then exit. ++ ++@item --cd=@var{directory} + Run @value{GDBN} using @var{directory} as its working directory, + instead of the current directory. + +-@item -fullname ++@item --data-directory=@var{directory} ++@item -D ++Run @value{GDBN} using @var{directory} as its data directory. The data ++directory is where @value{GDBN} searches for its auxiliary files. ++ ++@item --fullname + @itemx -f + Emacs sets this option when it runs @value{GDBN} as a subprocess. It tells + @value{GDBN} to output the full file name and line number in a standard, +@@ -47248,11 +47320,14 @@ and character position separated by colons, and a newline. The + Emacs-to-@value{GDBN} interface program uses the two @samp{\032} + characters as a signal to display the source code for the frame. + +-@item -b @var{bps} ++@item -b @var{baudrate} + Set the line speed (baud rate or bits per second) of any serial + interface used by @value{GDBN} for remote debugging. + +-@item -tty=@var{device} ++@item -l @var{timeout} ++Set timeout, in seconds, for remote debugging. ++ ++@item --tty=@var{device} + Run using @var{device} for your program's standard input and output. + @end table + @c man end diff --git a/gdb-rhbz2022177-dprintf-1.patch b/gdb-rhbz2022177-dprintf-1.patch new file mode 100644 index 0000000..d912289 --- /dev/null +++ b/gdb-rhbz2022177-dprintf-1.patch @@ -0,0 +1,315 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Kevin Buettner +Date: Wed, 10 Nov 2021 18:52:22 -0700 +Subject: gdb-rhbz2022177-dprintf-1.patch + +;; Backport fix for dprintf bug (RH BZ 2022177). + +Fix PR 28308 - dprintf breakpoints not working when run from script + +This commit fixes Bug 28308, titled "Strange interactions with +dprintf and break/commands": + +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28308 + +Since creating that bug report, I've found a somewhat simpler way of +reproducing the problem. I've encapsulated it into the GDB test case +which I've created along with this bug fix. The name of the new test +is gdb.base/dprintf-execution-x-script.exp, I'll demonstrate the +problem using this test case, though for brevity, I've placed all +relevant files in the same directory and have renamed the files to all +start with 'dp-bug' instead of 'dprintf-execution-x-script'. + +The script file, named dp-bug.gdb, consists of the following commands: + +dprintf increment, "dprintf in increment(), vi=%d\n", vi +break inc_vi +commands + continue +end +run + +Note that the final command in this script is 'run'. When 'run' is +instead issued interactively, the bug does not occur. So, let's look +at the interactive case first in order to see the correct/expected +output: + +$ gdb -q -x dp-bug.gdb dp-bug +... eliding buggy output which I'll discuss later ... +(gdb) run +Starting program: /mesquite2/sourceware-git/f34-master/bld/gdb/tmp/dp-bug +vi=0 +dprintf in increment(), vi=0 + +Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 +26 in dprintf-execution-x-script.c +vi=1 +dprintf in increment(), vi=1 + +Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 +26 in dprintf-execution-x-script.c +vi=2 +dprintf in increment(), vi=2 + +Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 +26 in dprintf-execution-x-script.c +vi=3 +[Inferior 1 (process 1539210) exited normally] + +In this run, in which 'run' was issued from the gdb prompt (instead +of at the end of the script), there are three dprintf messages along +with three 'Breakpoint 2' messages. This is the correct output. + +Now let's look at the output that I snipped above; this is the output +when 'run' is issued from the script loaded via GDB's -x switch: + +$ gdb -q -x dp-bug.gdb dp-bug +Reading symbols from dp-bug... +Dprintf 1 at 0x40116e: file dprintf-execution-x-script.c, line 38. +Breakpoint 2 at 0x40113a: file dprintf-execution-x-script.c, line 26. +vi=0 +dprintf in increment(), vi=0 + +Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 +26 dprintf-execution-x-script.c: No such file or directory. +vi=1 + +Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 +26 in dprintf-execution-x-script.c +vi=2 + +Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 +26 in dprintf-execution-x-script.c +vi=3 +[Inferior 1 (process 1539175) exited normally] + +In the output shown above, only the first dprintf message is printed. +The 2nd and 3rd dprintf messages are missing! However, all three +'Breakpoint 2...' messages are still printed. + +Why does this happen? + +bpstat_do_actions_1() in gdb/breakpoint.c contains the following +comment and code near the start of the function: + + /* Avoid endless recursion if a `source' command is contained + in bs->commands. */ + if (executing_breakpoint_commands) + return 0; + + scoped_restore save_executing + = make_scoped_restore (&executing_breakpoint_commands, 1); + +Also, as described by this comment prior to the 'async' field +in 'struct ui' in top.h, the main UI starts off in sync mode +when processing command line arguments: + + /* True if the UI is in async mode, false if in sync mode. If in + sync mode, a synchronous execution command (e.g, "next") does not + return until the command is finished. If in async mode, then + running a synchronous command returns right after resuming the + target. Waiting for the command's completion is later done on + the top event loop. For the main UI, this starts out disabled, + until all the explicit command line arguments (e.g., `gdb -ex + "start" -ex "next"') are processed. */ + +This combination of things, the state of the static global +'executing_breakpoint_commands' plus the state of the async +field in the main UI causes this behavior. + +This is a backtrace after hitting the dprintf breakpoint for +the second time when doing 'run' from the script file, i.e. +non-interactively: + +Thread 1 "gdb" hit Breakpoint 3, bpstat_do_actions_1 (bsp=0x7fffffffc2b8) + at /ironwood1/sourceware-git/f34-master/bld/../../worktree-master/gdb/breakpoint.c:4431 +4431 if (executing_breakpoint_commands) + + #0 bpstat_do_actions_1 (bsp=0x7fffffffc2b8) + at gdb/breakpoint.c:4431 + #1 0x00000000004d8bc6 in dprintf_after_condition_true (bs=0x1538090) + at gdb/breakpoint.c:13048 + #2 0x00000000004c5caa in bpstat_stop_status (aspace=0x116dbc0, bp_addr=0x40116e, thread=0x137f450, ws=0x7fffffffc718, + stop_chain=0x1538090) at gdb/breakpoint.c:5498 + #3 0x0000000000768d98 in handle_signal_stop (ecs=0x7fffffffc6f0) + at gdb/infrun.c:6172 + #4 0x00000000007678d3 in handle_inferior_event (ecs=0x7fffffffc6f0) + at gdb/infrun.c:5662 + #5 0x0000000000763cd5 in fetch_inferior_event () + at gdb/infrun.c:4060 + #6 0x0000000000746d7d in inferior_event_handler (event_type=INF_REG_EVENT) + at gdb/inf-loop.c:41 + #7 0x00000000007a702f in handle_target_event (error=0, client_data=0x0) + at gdb/linux-nat.c:4207 + #8 0x0000000000b8cd6e in gdb_wait_for_event (block=block@entry=0) + at gdbsupport/event-loop.cc:701 + #9 0x0000000000b8d032 in gdb_wait_for_event (block=0) + at gdbsupport/event-loop.cc:597 + #10 gdb_do_one_event () at gdbsupport/event-loop.cc:212 + #11 0x00000000009d19b6 in wait_sync_command_done () + at gdb/top.c:528 + #12 0x00000000009d1a3f in maybe_wait_sync_command_done (was_sync=0) + at gdb/top.c:545 + #13 0x00000000009d2033 in execute_command (p=0x7fffffffcb18 "", from_tty=0) + at gdb/top.c:676 + #14 0x0000000000560d5b in execute_control_command_1 (cmd=0x13b9bb0, from_tty=0) + at gdb/cli/cli-script.c:547 + #15 0x000000000056134a in execute_control_command (cmd=0x13b9bb0, from_tty=0) + at gdb/cli/cli-script.c:717 + #16 0x00000000004c3bbe in bpstat_do_actions_1 (bsp=0x137f530) + at gdb/breakpoint.c:4469 + #17 0x00000000004c3d40 in bpstat_do_actions () + at gdb/breakpoint.c:4533 + #18 0x00000000006a473a in command_handler (command=0x1399ad0 "run") + at gdb/event-top.c:624 + #19 0x00000000009d182e in read_command_file (stream=0x113e540) + at gdb/top.c:443 + #20 0x0000000000563697 in script_from_file (stream=0x113e540, file=0x13bb0b0 "dp-bug.gdb") + at gdb/cli/cli-script.c:1642 + #21 0x00000000006abd63 in source_gdb_script (extlang=0xc44e80 , stream=0x113e540, + file=0x13bb0b0 "dp-bug.gdb") at gdb/extension.c:188 + #22 0x0000000000544400 in source_script_from_stream (stream=0x113e540, file=0x7fffffffd91a "dp-bug.gdb", + file_to_open=0x13bb0b0 "dp-bug.gdb") + at gdb/cli/cli-cmds.c:692 + #23 0x0000000000544557 in source_script_with_search (file=0x7fffffffd91a "dp-bug.gdb", from_tty=1, search_path=0) + at gdb/cli/cli-cmds.c:750 + #24 0x00000000005445cf in source_script (file=0x7fffffffd91a "dp-bug.gdb", from_tty=1) + at gdb/cli/cli-cmds.c:759 + #25 0x00000000007cf6d9 in catch_command_errors (command=0x5445aa , + arg=0x7fffffffd91a "dp-bug.gdb", from_tty=1, do_bp_actions=false) + at gdb/main.c:523 + #26 0x00000000007cf85d in execute_cmdargs (cmdarg_vec=0x7fffffffd1b0, file_type=CMDARG_FILE, cmd_type=CMDARG_COMMAND, + ret=0x7fffffffd18c) at gdb/main.c:615 + #27 0x00000000007d0c8e in captured_main_1 (context=0x7fffffffd3f0) + at gdb/main.c:1322 + #28 0x00000000007d0eba in captured_main (data=0x7fffffffd3f0) + at gdb/main.c:1343 + #29 0x00000000007d0f25 in gdb_main (args=0x7fffffffd3f0) + at gdb/main.c:1368 + #30 0x00000000004186dd in main (argc=5, argv=0x7fffffffd508) + at gdb/gdb.c:32 + +There are two frames for bpstat_do_actions_1(), one at frame #16 and +the other at frame #0. The one at frame #16 is processing the actions +for Breakpoint 2, which is a 'continue'. The one at frame #0 is attempting +to process the dprintf breakpoint action. However, at this point, +the value of 'executing_breakpoint_commands' is 1, forcing an early +return, i.e. prior to executing the command(s) associated with the dprintf +breakpoint. + +For the sake of comparison, this is what the stack looks like when hitting +the dprintf breakpoint for the second time when issuing the 'run' +command from the GDB prompt. + +Thread 1 "gdb" hit Breakpoint 3, bpstat_do_actions_1 (bsp=0x7fffffffccd8) + at /ironwood1/sourceware-git/f34-master/bld/../../worktree-master/gdb/breakpoint.c:4431 +4431 if (executing_breakpoint_commands) + + #0 bpstat_do_actions_1 (bsp=0x7fffffffccd8) + at gdb/breakpoint.c:4431 + #1 0x00000000004d8bc6 in dprintf_after_condition_true (bs=0x16b0290) + at gdb/breakpoint.c:13048 + #2 0x00000000004c5caa in bpstat_stop_status (aspace=0x116dbc0, bp_addr=0x40116e, thread=0x13f0e60, ws=0x7fffffffd138, + stop_chain=0x16b0290) at gdb/breakpoint.c:5498 + #3 0x0000000000768d98 in handle_signal_stop (ecs=0x7fffffffd110) + at gdb/infrun.c:6172 + #4 0x00000000007678d3 in handle_inferior_event (ecs=0x7fffffffd110) + at gdb/infrun.c:5662 + #5 0x0000000000763cd5 in fetch_inferior_event () + at gdb/infrun.c:4060 + #6 0x0000000000746d7d in inferior_event_handler (event_type=INF_REG_EVENT) + at gdb/inf-loop.c:41 + #7 0x00000000007a702f in handle_target_event (error=0, client_data=0x0) + at gdb/linux-nat.c:4207 + #8 0x0000000000b8cd6e in gdb_wait_for_event (block=block@entry=0) + at gdbsupport/event-loop.cc:701 + #9 0x0000000000b8d032 in gdb_wait_for_event (block=0) + at gdbsupport/event-loop.cc:597 + #10 gdb_do_one_event () at gdbsupport/event-loop.cc:212 + #11 0x00000000007cf512 in start_event_loop () + at gdb/main.c:421 + #12 0x00000000007cf631 in captured_command_loop () + at gdb/main.c:481 + #13 0x00000000007d0ebf in captured_main (data=0x7fffffffd3f0) + at gdb/main.c:1353 + #14 0x00000000007d0f25 in gdb_main (args=0x7fffffffd3f0) + at gdb/main.c:1368 + #15 0x00000000004186dd in main (argc=5, argv=0x7fffffffd508) + at gdb/gdb.c:32 + +This relatively short backtrace is due to the current UI's async field +being set to 1. + +Yet another thing to be aware of regarding this problem is the +difference in the way that commands associated to dprintf breakpoints +versus regular breakpoints are handled. While they both use a command +list associated with the breakpoint, regular breakpoints will place +the commands to be run on the bpstat chain constructed in +bp_stop_status(). These commands are run later on. For dprintf +breakpoints, commands are run via the 'after_condition_true' function +pointer directly from bpstat_stop_status(). (The 'commands' field in +the bpstat is cleared in dprintf_after_condition_true(). This +prevents the dprintf commands from being run again later on when other +commands on the bpstat chain are processed.) + +Another thing that I noticed is that dprintf breakpoints are the only +type of breakpoint which use 'after_condition_true'. This suggests +that one possible way of fixing this problem, that of making dprintf +breakpoints work more like regular breakpoints, probably won't work. +(I must admit, however, that my understanding of this code isn't +complete enough to say why. I'll trust that whoever implemented it +had a good reason for doing it this way.) + +The comment referenced earlier regarding 'executing_breakpoint_commands' +states that the reason for checking this variable is to avoid +potential endless recursion when a 'source' command appears in +bs->commands. We know that a dprintf command is constrained to either +1) execution of a GDB printf command, 2) an inferior function call of +a printf-like function, or 3) execution of an agent-printf command. +Therefore, infinite recursion due to a 'source' command cannot happen +when executing commands upon hitting a dprintf breakpoint. + +I chose to fix this problem by having dprintf_after_condition_true() +directly call execute_control_commands(). This means that it no +longer attempts to go through bpstat_do_actions_1() avoiding the +infinite recursion check for potential 'source' commands on the +command chain. I think it simplifies this code a little bit too, a +definite bonus. + +Summary: + + * breakpoint.c (dprintf_after_condition_true): Don't call + bpstat_do_actions_1(). Call execute_control_commands() + instead. + +diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c +--- a/gdb/breakpoint.c ++++ b/gdb/breakpoint.c +@@ -13043,9 +13043,6 @@ dprintf_print_recreate (struct breakpoint *tp, struct ui_file *fp) + static void + dprintf_after_condition_true (struct bpstats *bs) + { +- struct bpstats tmp_bs; +- struct bpstats *tmp_bs_p = &tmp_bs; +- + /* dprintf's never cause a stop. This wasn't set in the + check_status hook instead because that would make the dprintf's + condition not be evaluated. */ +@@ -13056,14 +13053,9 @@ dprintf_after_condition_true (struct bpstats *bs) + bpstat_do_actions, if a breakpoint that causes a stop happens to + be set at same address as this dprintf, or even if running the + commands here throws. */ +- tmp_bs.commands = bs->commands; +- bs->commands = NULL; +- +- bpstat_do_actions_1 (&tmp_bs_p); +- +- /* 'tmp_bs.commands' will usually be NULL by now, but +- bpstat_do_actions_1 may return early without processing the whole +- list. */ ++ counted_command_line cmds = std::move (bs->commands); ++ gdb_assert (cmds != nullptr); ++ execute_control_commands (cmds.get (), 0); + } + + /* The breakpoint_ops structure to be used on static tracepoints with diff --git a/gdb-rhbz2022177-dprintf-2.patch b/gdb-rhbz2022177-dprintf-2.patch new file mode 100644 index 0000000..44bcd87 --- /dev/null +++ b/gdb-rhbz2022177-dprintf-2.patch @@ -0,0 +1,194 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Kevin Buettner +Date: Wed, 10 Nov 2021 18:55:43 -0700 +Subject: gdb-rhbz2022177-dprintf-2.patch + +;; Backport test case for dprintf bug (RH BZ 2022177). + +Test case for Bug 28308 + +The purpose of this test is described in the comments in +dprintf-execution-x-script.exp. + +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28308 + +The name of this new test was based on that of an existing test, +bp-cmds-execution-x-script.exp. I started off by copying that test, +adding to it, and then rewriting almost all of it. It's different +enough that I decided that listing the copyright year as 2021 +was sufficient. + +diff --git a/gdb/testsuite/gdb.base/dprintf-execution-x-script.c b/gdb/testsuite/gdb.base/dprintf-execution-x-script.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/dprintf-execution-x-script.c +@@ -0,0 +1,53 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2021 Free Software Foundation, Inc. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program 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 General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++#include ++#include ++ ++volatile int vi = 0; ++ ++void ++inc_vi () ++{ ++ vi++; ++} ++ ++void ++print_vi () ++{ ++ printf ("vi=%d\n", vi); ++} ++ ++void ++increment () ++{ ++ inc_vi (); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ print_vi (); ++ increment (); ++ print_vi (); ++ increment (); ++ print_vi (); ++ increment (); ++ print_vi (); ++ ++ exit (0); ++} +diff --git a/gdb/testsuite/gdb.base/dprintf-execution-x-script.exp b/gdb/testsuite/gdb.base/dprintf-execution-x-script.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/dprintf-execution-x-script.exp +@@ -0,0 +1,85 @@ ++# Copyright 2021 Free Software Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program 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 General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . */ ++ ++# Test that commands in a GDB script file run via GDB's -x flag work ++# as expected. Specifically, the script creates a dprintf breakpoint ++# as well as a normal breakpoint that has "continue" in its command ++# list, and then does "run". Correct output from GDB is checked as ++# part of this test. ++ ++# Bail out if the target can't use the 'run' command. ++if ![target_can_use_run_cmd] { ++ return 0 ++} ++ ++standard_testfile ++ ++if {[build_executable "failed to prepare" $testfile $srcfile debug]} { ++ return -1 ++} ++ ++# This is the name of the GDB script to load. ++set x_file ${srcdir}/${subdir}/$testfile.gdb ++ ++# Create context in which the global, GDBFLAGS, will be restored at ++# the end of the block. All commands run within the block are ++# actually run in the outer context. (This is why 'res' is available ++# outside of the save_vars block.) ++save_vars { GDBFLAGS } { ++ # Set flags with which to start GDB. ++ append GDBFLAGS " -ex \"set height unlimited\"" ++ append GDBFLAGS " -x \"$x_file\"" ++ append GDBFLAGS " --args \"$binfile\"" ++ ++ # Start GDB with above flags. ++ set res [gdb_spawn] ++} ++ ++set test "load and run script with -x" ++if { $res != 0} { ++ fail $test ++ return -1 ++} ++ ++# The script loaded via -x contains a run command; while running, GDB ++# is expected to print three messages from dprintf breakpoints along ++# with three interspersed messages from an ordinary breakpoint (which ++# was set up with a continue command). Set up pattern D to match ++# output from hitting the dprintf breakpoint and B for the ordinary ++# breakpoint. Then set PAT to contain the entire pattern of expected ++# output from the interspersed dprintf and ordinary breakpoints along ++# with some (additional) expected output from the dprintf breakpoints, ++# i.e. 0, 1, and 2. ++set d "dprintf in increment.., vi=" ++set b "Breakpoint ., inc_vi" ++set pat "${d}0.*?$b.*?${d}1.*?$b.*?${d}2.*?$b.*?" ++ ++proc do_test {cmd test} { ++ gdb_test $cmd "$::pat$::inferior_exited_re normally.*" $test ++} ++ ++# Check output from running script with -x ++do_test "" $test ++ ++# Restart GDB and 'source' the script; this will (still) run the program ++# due to the 'run' command in the script. ++clean_restart $binfile ++do_test "source $x_file" "load and run script using source command" ++ ++# This should leave us at the gdb prompt; Run program again using ++# already established breakpoints, i.e. those loaded from the ++# script. Prior to fixing PR 28308, this was the only test that ++# would pass. ++do_test "run" "run again" +diff --git a/gdb/testsuite/gdb.base/dprintf-execution-x-script.gdb b/gdb/testsuite/gdb.base/dprintf-execution-x-script.gdb +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/dprintf-execution-x-script.gdb +@@ -0,0 +1,21 @@ ++# Copyright 2021 Free Software Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program 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 General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . */ ++ ++dprintf increment, "dprintf in increment(), vi=%d\n", vi ++break inc_vi ++commands ++ continue ++end ++run diff --git a/gdb-rhbz853071-update-manpages.patch b/gdb-rhbz853071-update-manpages.patch deleted file mode 100644 index 970e6d8..0000000 --- a/gdb-rhbz853071-update-manpages.patch +++ /dev/null @@ -1,258 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Bruno Larsen -Date: Tue, 9 Nov 2021 12:55:34 -0300 -Subject: gdb-rhbz853071-update-manpages.patch - -;; Backport manpage update - -[gdb/doc]: Updated manpages to be consistent with help - -Updated manpages to be consistent with help information provided by the -binary. The main changes are: - -* Making all long-form options have '--', instead of a single '-'; -* added most of the missing options to the manpage; -* removed the information about using '+' instead of '-', since it - doesn't seem to be supported anymore. - -This also fixes 2 upstream bugs: -* https://sourceware.org/bugzilla/show_bug.cgi?id=23965; by adding ---args to the manpage -* https://sourceware.org/bugzilla/show_bug.cgi?id=10619; by adding the -double dashes - -diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo ---- a/gdb/doc/gdb.texinfo -+++ b/gdb/doc/gdb.texinfo -@@ -47030,14 +47030,7 @@ switch (die->tag) - @c man title gdb The GNU Debugger - - @c man begin SYNOPSIS gdb --gdb [@option{-help}] [@option{-nh}] [@option{-nx}] [@option{-q}] --[@option{-batch}] [@option{-cd=}@var{dir}] [@option{-f}] --[@option{-b}@w{ }@var{bps}] -- [@option{-tty=}@var{dev}] [@option{-s} @var{symfile}] --[@option{-e}@w{ }@var{prog}] [@option{-se}@w{ }@var{prog}] --[@option{-c}@w{ }@var{core}] [@option{-p}@w{ }@var{procID}] -- [@option{-x}@w{ }@var{cmds}] [@option{-d}@w{ }@var{dir}] --[@var{prog}|@var{prog} @var{procID}|@var{prog} @var{core}] -+gdb [OPTIONS] [@var{prog}|@var{prog} @var{procID}|@var{prog} @var{core}] - @c man end - - @c man begin DESCRIPTION gdb -@@ -47101,8 +47094,8 @@ Here are some of the most frequently needed @value{GDBN} commands: - - @c pod2man highlights the right hand side of the @item lines. - @table @env --@item break [@var{file}:]@var{function} --Set a breakpoint at @var{function} (in @var{file}). -+@item break [@var{file}:][@var{function}|@var{line}] -+Set a breakpoint at @var{function} or @var{line} (in @var{file}). - - @item run [@var{arglist}] - Start your program (with @var{arglist}, if specified). -@@ -47150,72 +47143,91 @@ as the @code{gdb} entry in the @code{info} program. - Any arguments other than options specify an executable - file and core file (or process ID); that is, the first argument - encountered with no --associated option flag is equivalent to a @option{-se} option, and the second, -+associated option flag is equivalent to a @option{--se} option, and the second, - if any, is equivalent to a @option{-c} option if it's the name of a file. - Many options have --both long and short forms; both are shown here. The long forms are also -+both long and abbreviated forms; both are shown here. The long forms are also - recognized if you truncate them, so long as enough of the option is --present to be unambiguous. (If you prefer, you can flag option --arguments with @option{+} rather than @option{-}, though we illustrate the --more usual convention.) -+present to be unambiguous. -+ -+The abbreviated forms are shown here with @samp{-} and long forms are shown -+with @samp{--} to reflect how they are shown in @option{--help}. However, -+@value{GDBN} recognizes all of the following conventions for most options: -+ -+@table @code -+@item --option=@var{value} -+@item --option @var{value} -+@item -option=@var{value} -+@item -option @var{value} -+@item --o=@var{value} -+@item --o @var{value} -+@item -o=@var{value} -+@item -o @var{value} -+@end table - - All the options and command line arguments you give are processed - in sequential order. The order makes a difference when the @option{-x} - option is used. - - @table @env --@item -help -+@item --help - @itemx -h - List all options, with brief explanations. - --@item -symbols=@var{file} -+@item --symbols=@var{file} - @itemx -s @var{file} --Read symbol table from file @var{file}. -+Read symbol table from @var{file}. - --@item -write -+@item --write - Enable writing into executable and core files. - --@item -exec=@var{file} -+@item --exec=@var{file} - @itemx -e @var{file} --Use file @var{file} as the executable file to execute when -+Use @var{file} as the executable file to execute when - appropriate, and for examining pure data in conjunction with a core - dump. - --@item -se=@var{file} --Read symbol table from file @var{file} and use it as the executable -+@item --se=@var{file} -+Read symbol table from @var{file} and use it as the executable - file. - --@item -core=@var{file} -+@item --core=@var{file} - @itemx -c @var{file} --Use file @var{file} as a core dump to examine. -+Use @var{file} as a core dump to examine. - --@item -command=@var{file} -+@item --command=@var{file} - @itemx -x @var{file} --Execute @value{GDBN} commands from file @var{file}. -+Execute @value{GDBN} commands from @var{file}. - -+@item --eval-command=@var{command} - @item -ex @var{command} - Execute given @value{GDBN} @var{command}. - --@item -directory=@var{directory} -+@item --init-eval-command=@var{command} -+@item -iex -+Execute @value{GDBN} @var{command} before loading the inferior. -+ -+@item --directory=@var{directory} - @itemx -d @var{directory} - Add @var{directory} to the path to search for source files. - --@item -nh -+@item --nh - Do not execute commands from @file{~/.config/gdb/gdbinit}, - @file{~/.gdbinit}, @file{~/.config/gdb/gdbearlyinit}, or - @file{~/.gdbearlyinit} - --@item -nx -+@item --nx - @itemx -n - Do not execute commands from any @file{.gdbinit} or - @file{.gdbearlyinit} initialization files. - --@item -quiet -+@item --quiet -+@item --silent - @itemx -q - ``Quiet''. Do not print the introductory and copyright messages. These - messages are also suppressed in batch mode. - --@item -batch -+@item --batch - Run in batch mode. Exit with status @code{0} after processing all the command - files specified with @option{-x} (and @file{.gdbinit}, if not inhibited). - Exit with nonzero status if an error occurs in executing the @value{GDBN} -@@ -47233,11 +47245,71 @@ Program exited normally. - (which is ordinarily issued whenever a program running under @value{GDBN} control - terminates) is not issued when running in batch mode. - --@item -cd=@var{directory} -+@item --batch-silent -+Run in batch mode, just like @option{--batch}, but totally silent. All @value{GDBN} -+output is supressed (stderr is unaffected). This is much quieter than -+@option{--silent} and would be useless for an interactive session. -+ -+This is particularly useful when using targets that give @samp{Loading section} -+messages, for example. -+ -+Note that targets that give their output via @value{GDBN}, as opposed to writing -+directly to @code{stdout}, will also be made silent. -+ -+@item --args @var{prog} [@var{arglist}] -+Change interpretation of command line so that arguments following this -+option are passed as arguments to the inferior. As an example, take -+the following command: -+ -+@smallexample -+gdb ./a.out -q -+@end smallexample -+ -+@noindent -+It would start @value{GDBN} with @option{-q}, not printing the introductory message. On -+the other hand, using: -+ -+@smallexample -+gdb --args ./a.out -q -+@end smallexample -+ -+@noindent -+starts @value{GDBN} with the introductory message, and passes the option to the inferior. -+ -+@item --pid=@var{pid} -+Attach @value{GDBN} to an already running program, with the PID @var{pid}. -+ -+@item --tui -+Open the terminal user interface. -+ -+@item --readnow -+Read all symbols from the given symfile on the first access. -+ -+@item --readnever -+Do not read symbol files. -+ -+@item --dbx -+Run in DBX compatibility mode. -+ -+@item --return-child-result -+@value{GDBN}'s exit code will be the same as the child's exit code. -+ -+@item --configuration -+Print details about GDB configuration and then exit. -+ -+@item --version -+Print version information and then exit. -+ -+@item --cd=@var{directory} - Run @value{GDBN} using @var{directory} as its working directory, - instead of the current directory. - --@item -fullname -+@item --data-directory=@var{directory} -+@item -D -+Run @value{GDBN} using @var{directory} as its data directory. The data -+directory is where @value{GDBN} searches for its auxiliary files. -+ -+@item --fullname - @itemx -f - Emacs sets this option when it runs @value{GDBN} as a subprocess. It tells - @value{GDBN} to output the full file name and line number in a standard, -@@ -47248,11 +47320,14 @@ and character position separated by colons, and a newline. The - Emacs-to-@value{GDBN} interface program uses the two @samp{\032} - characters as a signal to display the source code for the frame. - --@item -b @var{bps} -+@item -b @var{baudrate} - Set the line speed (baud rate or bits per second) of any serial - interface used by @value{GDBN} for remote debugging. - --@item -tty=@var{device} -+@item -l @var{timeout} -+Set timeout, in seconds, for remote debugging. -+ -+@item --tty=@var{device} - Run using @var{device} for your program's standard input and output. - @end table - @c man end