diff --git a/_gdb.spec.Patch.include b/_gdb.spec.Patch.include index 25594b2..4884f06 100644 --- a/_gdb.spec.Patch.include +++ b/_gdb.spec.Patch.include @@ -328,3 +328,9 @@ Patch078: gdb-rhbz2012976-paper-over-fortran-lex-problems.patch # Backport manpage update 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 6a7f166..863ee71 100644 --- a/_patch_order +++ b/_patch_order @@ -77,3 +77,5 @@ gdb-rhbz1976887-field-location-kind.patch gdb-test-for-rhbz1976887.patch gdb-rhbz2012976-paper-over-fortran-lex-problems.patch gdb-rhbz-853071-update-manpages.patch +gdb-rhbz2022177-dprintf-1.patch +gdb-rhbz2022177-dprintf-2.patch 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.spec b/gdb.spec index 1c4da64..616f1d9 100644 --- a/gdb.spec +++ b/gdb.spec @@ -37,7 +37,7 @@ Version: 11.1 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL # Do not provide URL for snapshots as the file lasts there only for 2 days. @@ -1143,6 +1143,10 @@ fi %endif %changelog +* Wed Nov 10 2021 Kevin Buettner - 11.1-5 +- Backport upstream fix and test case for a dprintf bug (RHBZ 2022177, Kevin + Buettner). + * Tue Nov 9 2021 Bruno Larsen - 11.1-4 - Backport manpage update to be closer to -help (RHBZ 853071)