- Update to fedora rawhide @ 0481d32. Maintenance script import-fedora.sh: * Skip gdb-fix-bg-execution-repeat.patch. - Add MIT in License tag due to gdbsupport/unordered_dense.h. - Update to fedora rawhide @ 89e3933. Maintenance script import-fedora.sh: * Drop gdb-6.8-bz466901-backtrace-full-prelinked.patch from skip_patches. - Update to fedora rawhide @ 660c52f. Drop patches: * gdb-rhbz1149205-catch-syscall-after-fork-test.patch - Update to fedora rawhide @ 885cdf8. Update patches: * gdb-add-rpm-suggestion-script.patch Drop patches: * fixup-gdb-add-rpm-suggestion-script.patch - Update to fedora rawhide @ 9c718a5. Drop patches: * gdb-6.3-mapping-zero-inode-test.patch - Update to fedora rawhide @ 15778f3. Drop patches: * gdb-archer-next-over-throw-cxx-exec.patch - Update to fedora rawhide @ 152468c. Maintenance script import-fedora.sh: * Rename gdb-6.3-rh-testversion-20041202.patch to gdb-test-show-version.patch in skip_patches. Patches dropped (Renamed to ...): * gdb-add-rpm-suggestion-script.patch Patches added (... this): * gdb-rpm-suggestion-script.patch - Move some patches from "Backport from gdb-patches" to "Backports from master, available in GDB 17". - Add patches (swo#33000): * gdb-tdep-fix-gdb.ada-finish-var-size.exp-on-ppc64le-.patch - Add patches (swo#32409): * gdb-ada-fix-gdb.ada-overloads.exp-on-s390x.patch - Add patches: * gdb-testsuite-make-gdb.reverse-time-reverse.exp-more.patch * gdb-testsuite-fix-gdb.reverse-time-reverse.exp-timeo.patch * gdb-testsuite-handle-asm-frame-in-gdb.python-py-miss.patch * gdb-testsuite-fix-gdb.base-ptype.exp-with-gcc-15.patch * gdb-testsuite-fix-gdb.python-py-objfile.exp-with-gcc.patch * gdb-testsuite-fix-gdb.ada-scalar_storage.exp-on-s390.patch * gdb-testsuite-fix-gdb.base-bp-permanent.exp-with-gcc.patch * gdb-testsuite-don-t-run-to-main-in-gdb.cp-cplusfuncs.patch OBS-URL: https://build.opensuse.org/package/show/devel:gcc/gdb?expand=0&rev=465
1012 lines
39 KiB
Diff
1012 lines
39 KiB
Diff
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
|
From: Andrew Burgess <aburgess@redhat.com>
|
|
Date: Thu, 7 Mar 2024 15:14:23 +0000
|
|
Subject: gdb-rpm-suggestion-script.patch
|
|
|
|
;; Not a backport. Add a new script which hooks into GDB and suggests
|
|
;; RPMs to install when GDB finds an objfile with no debug info.
|
|
|
|
gdb: add script which will suggest debuginfo RPMs to install
|
|
|
|
This script hooks into GDB's missing debug info Python API and
|
|
suggests debuginfo RPMs to install.
|
|
|
|
diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
|
|
--- a/gdb/data-directory/Makefile.in
|
|
+++ b/gdb/data-directory/Makefile.in
|
|
@@ -92,6 +92,7 @@ PYTHON_FILE_LIST = \
|
|
gdb/command/missing_files.py \
|
|
gdb/command/pretty_printers.py \
|
|
gdb/command/prompt.py \
|
|
+ gdb/command/rpm-suggestions.py \
|
|
gdb/command/type_printers.py \
|
|
gdb/command/unwinders.py \
|
|
gdb/command/xmethods.py \
|
|
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
|
|
--- a/gdb/doc/gdb.texinfo
|
|
+++ b/gdb/doc/gdb.texinfo
|
|
@@ -186,6 +186,7 @@ software in general. We will miss him.
|
|
* Trace File Format:: @value{GDBN} trace file format
|
|
* Index Section Format:: .gdb_index section format
|
|
* Debuginfod:: Download debugging resources with @code{debuginfod}
|
|
+* RPM Suggestions:: RPM Suggestions from GDB
|
|
* Man Pages:: Manual pages
|
|
* Copying:: GNU General Public License says
|
|
how you can copy and share @value{GDBN}
|
|
@@ -50588,6 +50589,111 @@ Show the current verbosity setting.
|
|
|
|
@end table
|
|
|
|
+@node RPM Suggestions
|
|
+@appendix Receiving RPM installation suggestions
|
|
+@cindex rpm suggestions
|
|
+
|
|
+When @value{GDBN} loads an executable, or shared library, and cannot
|
|
+find the corresponding debug information, @value{GDBN} will check to
|
|
+see if an RPM is available which could provide the missing debug
|
|
+information. If a suitable RPM is found then @value{GDBN} will print
|
|
+a hint before the next prompt is displayed:
|
|
+
|
|
+@smallexample
|
|
+(@value{GDBP}) file /bin/ls
|
|
+Reading symbols from /bin/ls...
|
|
+Reading symbols from .gnu_debugdata for /usr/bin/ls...
|
|
+(No debugging symbols found in .gnu_debugdata for /usr/bin/ls)
|
|
+Missing rpms, try: dnf --enablerepo='*debug*' install coreutils-debuginfo-9.3-7.fc39.x86_64
|
|
+(@value{GDBP})
|
|
+@end smallexample
|
|
+
|
|
+In this case, installing @file{coreutils-debuginfo-9.3-7.fc39.x86_64}
|
|
+will provide the missing debug information for @file{/bin/ls}. It is
|
|
+up to you to install the suggested package, if possible, and after
|
|
+that reload the executable in @value{GDBN} so that the newly installed
|
|
+debug information can be found.
|
|
+
|
|
+The RPM suggestion feature can be disabled:
|
|
+
|
|
+@table @code
|
|
+@kindex set rpm-suggestion enabled
|
|
+@kindex show rpm-suggestion enabled
|
|
+@cindex rpm suggestions, disabling
|
|
+@item set rpm-suggestion enabled @r{[}on@r{|}off@r{]}
|
|
+@itemx show rpm-suggestion enabled
|
|
+When @samp{on} @value{GDBN} will make RPM suggestions where possible.
|
|
+When @samp{off} all RPM suggestion will be disabled.
|
|
+@end table
|
|
+
|
|
+When opening a core file (@pxref{core-file command}), it may be the
|
|
+case that not only is the debug information missing, but the
|
|
+corresponding executable itself is missing. For example, if a core
|
|
+file is copied from one machine to another in order to debug.
|
|
+
|
|
+In this case @value{GDBN} is able to suggest a command which will
|
|
+install the missing executable based on the build-id of the
|
|
+executable. For example:
|
|
+
|
|
+@smallexample
|
|
+(@value{GDBP}) core-file /tmp/core.5489
|
|
+warning: Can't open file /usr/bin/sl during file-backed mapping note processing
|
|
+[New LWP 5489]
|
|
+Core was generated by `sl'.
|
|
+Program terminated with signal SIGQUIT, Quit.
|
|
+#0 0x00007f1b41ced1a7 in ?? ()
|
|
+Missing file(s), try: dnf --enablerepo='*debug*' install /usr/lib/.build-id/33/2f1a8e56693960e3beb2d70cd79ddfec451cc3 /usr/lib/debug/.build-id/33/2f1a8e56693960e3beb2d70cd79ddfec451cc3.debug
|
|
+(@value{GDBP})
|
|
+@end smallexample
|
|
+
|
|
+The core file was generated from the @file{/usr/bin/sl} binary, which
|
|
+is not present on the machine opening the core file. @value{GDBN} has
|
|
+suggested a command, based on the build-id of the binary, which was
|
|
+extracted from the core file, that would install both the missing
|
|
+binary, and the corresponding debug information.
|
|
+
|
|
+Unfortunately, @value{GDBN} doesn't know if the suggested command will
|
|
+actually find a matching RPM or not. Querying the RPM database to see
|
|
+which packages, if any, will provide a file with the given build-id,
|
|
+is rather slow. As @file{/usr/bin/sl} is available in an RPM, then
|
|
+the above command will succeed.
|
|
+
|
|
+It is possible to have @value{GDBN} check to see if there is a package
|
|
+available before making the suggestion, but this is significantly
|
|
+slower. To enable this mode use the following command:
|
|
+
|
|
+@table @code
|
|
+@kindex set rpm-suggestion build-id-mode
|
|
+@kindex show rpm-suggestion build-id-mode
|
|
+@cindex rpm suggestions, build-id-mode
|
|
+@item set rpm-suggestion build-id-mode @r{[}fast@r{|}slow@r{]}
|
|
+@itemx show rpm-suggestion build-id-mode
|
|
+When set to @samp{fast}, which is the default, @value{GDBN} will offer
|
|
+suggestions based on the build-id of any missing executables or shared
|
|
+libraries while opening a core file. This is fast, but @value{GDBN}
|
|
+has not checked if there is a package available that can supply the
|
|
+required file, so running the suggested command might not install any
|
|
+packages.
|
|
+
|
|
+When set to @samp{slow}, each time @value{GDBN} encounters an
|
|
+executable, or shared library, that is missing, @value{GDBN} will
|
|
+check to see if there is an RPM available that will supply the missing
|
|
+binary. If a suitable RPM is found then @value{GDBN} will offer a
|
|
+command which will install the missing RPM. If no suitable RPM is
|
|
+found then @value{GDBN} will make no suggestions.
|
|
+@end table
|
|
+
|
|
+It is possible to review all of the previous RPM suggestions that
|
|
+@value{GDBN} has made using the following command:
|
|
+
|
|
+@table @code
|
|
+@kindex info rpm-suggestions
|
|
+@cindex rpm suggestions, listing
|
|
+@item info rpm-suggestions
|
|
+List all of the RPM suggestions @value{GDBN} has made since the
|
|
+executable was last changed.
|
|
+@end table
|
|
+
|
|
@node Man Pages
|
|
@appendix Manual pages
|
|
@cindex Man pages
|
|
diff --git a/gdb/python/lib/gdb/command/rpm-suggestions.py b/gdb/python/lib/gdb/command/rpm-suggestions.py
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/gdb/python/lib/gdb/command/rpm-suggestions.py
|
|
@@ -0,0 +1,527 @@
|
|
+# Copyright 2023 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 <http://www.gnu.org/licenses/>.
|
|
+
|
|
+import gdb
|
|
+import gdb.missing_debug
|
|
+import gdb.missing_objfile
|
|
+
|
|
+# These modules are all system modules, and should be available on any
|
|
+# correctly setup Python install.
|
|
+import sys
|
|
+import os
|
|
+import subprocess
|
|
+import re
|
|
+from threading import Thread
|
|
+import time
|
|
+
|
|
+try:
|
|
+ import rpm
|
|
+except ModuleNotFoundError:
|
|
+ # The "RPM suggestions" mechanism will not work without the (python)
|
|
+ # rpm module. Inform the user of this, but wait to do so until
|
|
+ # just prior to printing the GDB prompt. If we do it right away,
|
|
+ # the message typically appears before the version and copyright
|
|
+ # info, which is easily missed by many users. Additionally, it
|
|
+ # seems that several other packages which parse GDB version info
|
|
+ # are confused by an early error message regarding a missing
|
|
+ # python3-rpm package, so waiting to print the error allows those
|
|
+ # applications to work as they used to.
|
|
+ def before_prompt():
|
|
+ print(
|
|
+ ("\nUnable to load the Python 'rpm' module. Lack of this module disables\n"
|
|
+ "the RPM suggestions mechanism which recommends shell commands for\n"
|
|
+ "installing missing debuginfo packages. To enable this functionality,\n"
|
|
+ "please install the python3-rpm package."),
|
|
+ file=sys.stderr
|
|
+ )
|
|
+ gdb.events.before_prompt.disconnect(before_prompt)
|
|
+
|
|
+ gdb.events.before_prompt.connect(before_prompt)
|
|
+
|
|
+ # Implement 'info rpm-suggestions' when the 'rpm' module is not
|
|
+ # available. Just throws an error.
|
|
+ def info_rpm_suggestions():
|
|
+ raise gdb.GdbError("rpm-suggestions are disabled as the Python 'rpm' module is not installed")
|
|
+else:
|
|
+ # Track all the RPMs suggested during a single debug session so we
|
|
+ # don't suggest the same RPM twice. This is only cleared when the
|
|
+ # main executable is changed.
|
|
+ __missing_rpms = {}
|
|
+
|
|
+ # Track any missing RPMs that have been discovered since the last time
|
|
+ # the prompt was displayed. RPMs in here are also present in the
|
|
+ # __MISSING_RPMS dictionary, but this dictionary is cleared each time
|
|
+ # the prompt is shown.
|
|
+ __suggest_rpms = {}
|
|
+
|
|
+ # Track all the build-ids suggested during a single debug session so we
|
|
+ # don't suggest installing using the same build-id twice. This is only
|
|
+ # cleared when the main executable is changed.
|
|
+ __missing_build_ids = {}
|
|
+
|
|
+ # Track any build-ids that have been discovered missing since the last
|
|
+ # time the prompt was displayed. Build-ids in here are also present in
|
|
+ # the __MISSING_BUILD_IDS dictionary, but this dictionary is cleared
|
|
+ # each time the prompt is shown.
|
|
+ __suggest_build_ids = {}
|
|
+
|
|
+ # The build-id to RPM lookup is very slow. This cache maps
|
|
+ # build-ids to the set of RPM we can suggest installing. The key
|
|
+ # is the build-id string, and the value is a list of RPM names, or
|
|
+ # None if there was an error with the build-id to RPM lookup.
|
|
+ #
|
|
+ # This cache is never cleared, even when the executable is
|
|
+ # changed. The build-ids should be unique, so a build-id lookup
|
|
+ # should be good for the lifetime of the session.
|
|
+ __build_id_lookup_cache = {}
|
|
+
|
|
+ # When searching for an RPM given a build-id, if the search takes
|
|
+ # too long, then a message is printed to the user. We only print
|
|
+ # the message once between each GDB prompt. This flag is set True
|
|
+ # when the message is printed, and reset to False when a prompt is
|
|
+ # displayed.
|
|
+ __searching_message_printed = False
|
|
+
|
|
+ # Add a suggestion to install RPM_NAME (the full name of an RPM)
|
|
+ # to the list of suggestions to make the next time a prompt is
|
|
+ # displayed.
|
|
+ def add_rpm_suggestion(rpm_name):
|
|
+ global __missing_rpms
|
|
+ global __suggest_rpms
|
|
+
|
|
+ if not rpm_name in __missing_rpms:
|
|
+ __suggest_rpms[rpm_name] = True
|
|
+ __missing_rpms[rpm_name] = True
|
|
+
|
|
+ # Return True if RPM_NAME is installed, where RPM_NAME is the full
|
|
+ # name of an RPM.
|
|
+ def is_rpm_installed(ts, rpm_name):
|
|
+ res = ts.dbMatch(rpm.RPMDBI_LABEL, rpm_name)
|
|
+ return len(res) > 0
|
|
+
|
|
+ # Add a suggestion to install RPMs based on BUILD_ID, a string
|
|
+ # containing a build-id, to the list of suggestions to make the next
|
|
+ # time a prompt is displayed.
|
|
+ def add_build_id_suggestion(build_id):
|
|
+ global __missing_build_ids
|
|
+ global __suggest_build_ids
|
|
+
|
|
+ if not build_id in __missing_build_ids:
|
|
+ __suggest_build_ids[build_id] = True
|
|
+ __missing_build_ids[build_id] = True
|
|
+
|
|
+ # Return true if '/usr/lib' is in the debug-file-directory list.
|
|
+ # System packages install their debug information into /usr/lib,
|
|
+ # so if GDB isn't looking in that directory, then there's no
|
|
+ # reason to try and figure out a suitable RPM to install.
|
|
+ def using_suitable_debug_file_directory():
|
|
+ debug_file_directories = gdb.parameter("debug-file-directory")
|
|
+ for d in debug_file_directories.split(os.pathsep):
|
|
+ if d[:8] == "/usr/lib":
|
|
+ return True
|
|
+ return False
|
|
+
|
|
+ # Return True if rpm-suggestion is disabled for any reason.
|
|
+ def rpm_suggestion_is_disabled():
|
|
+ # If /usr/lib/ is not being used to find debug information
|
|
+ # then there's no point offering any RPMs as GDB would not
|
|
+ # find the newly installed content.
|
|
+ if not using_suitable_debug_file_directory():
|
|
+ return True
|
|
+
|
|
+ # Is 'rpm-suggestion enabled' set to 'off'?
|
|
+ if not param_rpm_suggestion_enabled.value:
|
|
+ return True
|
|
+
|
|
+ return False
|
|
+
|
|
+
|
|
+ # Lookup RPMs that might provide the debug information for FILENAME,
|
|
+ # which is a string containing the path to an object file GDB could
|
|
+ # not find any debug information for.
|
|
+ #
|
|
+ # If a possible RPM is found then this is added to the globals
|
|
+ # __MISSING_RPMS and __SUGGEST_RPMS, which are used elsewhere in this
|
|
+ # script.
|
|
+ def find_debug_suggestions(filename):
|
|
+ if rpm_suggestion_is_disabled():
|
|
+ return
|
|
+
|
|
+ ts = rpm.TransactionSet()
|
|
+ mi = ts.dbMatch(rpm.RPMDBI_BASENAMES, filename)
|
|
+ for h in mi:
|
|
+ # Build the debuginfo package name.
|
|
+ obj = h.format("%{name}-debuginfo-%{version}-%{release}.%{arch}")
|
|
+ rpm_name = str(obj)
|
|
+
|
|
+ # Check to see if the package is installed.
|
|
+ if is_rpm_installed(ts, rpm_name):
|
|
+ continue
|
|
+
|
|
+ add_rpm_suggestion(rpm_name)
|
|
+
|
|
+
|
|
+ # Return a string which is the filename of the filename
|
|
+ # corresponding to BUILD_ID in one of the two locations under
|
|
+ # /usr/lib.
|
|
+ #
|
|
+ # When DEBUG_P is True, return a filename within:
|
|
+ # /usr/lib/debug/.build-id/ and when DEBUG_P is False, return a
|
|
+ # filename within: /usr/lib/.build-id/.
|
|
+ #
|
|
+ # The SUFFIX string is appended to the generated filename.
|
|
+ def build_id_to_usr_lib_filename(build_id, debug_p, suffix = ""):
|
|
+ key = build_id[:2]
|
|
+ rst = build_id[2:]
|
|
+
|
|
+ filename = '/usr/lib'
|
|
+ if debug_p:
|
|
+ filename += '/debug'
|
|
+ filename += '/.build-id/' + key + '/' + rst + suffix
|
|
+
|
|
+ return filename
|
|
+
|
|
+ # A regexp object used to match against the output of `dnf`. This
|
|
+ # is initialised the first time it is needed.
|
|
+ find_objfile_suggestions_re = None
|
|
+
|
|
+ # Given BUILD_ID, a string containing a build-id, run a `dnf`
|
|
+ # command to figure out if any RPMs can provide a file with that
|
|
+ # build-id.
|
|
+ #
|
|
+ # If any suitable RPMs are found then `add_rpm_suggestion` is called
|
|
+ # to register the suggestion.
|
|
+ #
|
|
+ # This function is pretty slow, which is a shame, as the results
|
|
+ # returned are much nicer than just telling the user to try the
|
|
+ # lookup command for themselves.
|
|
+ def find_objfile_suggestions_in_thread(build_id):
|
|
+ global find_objfile_suggestions_re
|
|
+
|
|
+ if find_objfile_suggestions_re is None:
|
|
+ find_objfile_suggestions_re = re.compile("^(.*)-debuginfo-(.*) : Debug information for package (.*)$")
|
|
+
|
|
+ result = subprocess.run(['dnf', "--enablerepo=*debug*", '--nogpgcheck', '-C', 'provides',
|
|
+ build_id_to_usr_lib_filename(build_id, True)],
|
|
+ capture_output=True, timeout=30)
|
|
+
|
|
+ lines = result.stdout.decode('utf-8').splitlines()
|
|
+ ts = rpm.TransactionSet()
|
|
+
|
|
+ for l in lines:
|
|
+ m = find_objfile_suggestions_re.match(l)
|
|
+ if not m:
|
|
+ continue
|
|
+ if m.group(1) != m.group(3):
|
|
+ return
|
|
+
|
|
+ main_rpm = m.group(1) + '-' + m.group(2)
|
|
+ dbg_rpm = m.group(1) + '-debuginfo-' + m.group(2)
|
|
+
|
|
+ if not is_rpm_installed(ts, main_rpm):
|
|
+ add_rpm_suggestion(main_rpm)
|
|
+
|
|
+ if not is_rpm_installed(ts, dbg_rpm):
|
|
+ add_rpm_suggestion(dbg_rpm)
|
|
+
|
|
+ return
|
|
+
|
|
+ # Call `find_objfile_suggestions_in_thread` is a separate thread,
|
|
+ # then wait for the thread to complete. Don't touch any shared
|
|
+ # state while waiting for the thread to complete. There's no
|
|
+ # locking on any of our caches, and the worker thread will add RPM
|
|
+ # suggestions as it wants.
|
|
+ #
|
|
+ # If thre thread takes too long to complete then print a message
|
|
+ # to the user telling them what's going on.
|
|
+ def find_objfile_suggestions_slow_core(build_id):
|
|
+ global __searching_message_printed
|
|
+
|
|
+ thread = Thread(target = find_objfile_suggestions_in_thread, args = (build_id, ))
|
|
+ thread.start()
|
|
+ start = time.time_ns()
|
|
+
|
|
+ while thread.is_alive ():
|
|
+ time.sleep(0.05)
|
|
+ now = time.time_ns ()
|
|
+ if not __searching_message_printed and (now - start > 1000000000):
|
|
+ print("Searching for packages to install that could improve debugging...")
|
|
+ __searching_message_printed = True
|
|
+
|
|
+ thread.join()
|
|
+
|
|
+
|
|
+ # Given BUILD_ID, a string containing a build-id, lookup suitable
|
|
+ # RPMs that could be installed to provide a file with the required
|
|
+ # build-id.
|
|
+ #
|
|
+ # Any suitable RPMs are recorded by calling `add_rpm_suggestion`, and
|
|
+ # will be printed before the next prompt.
|
|
+ def find_objfile_suggestions_slow(build_id):
|
|
+ global __build_id_lookup_cache
|
|
+ global __suggest_rpms
|
|
+
|
|
+ # The code to lookup an RPM given only a build-id is pretty
|
|
+ # slow. Cache the results to try and reduce the UI delays.
|
|
+ if build_id in __build_id_lookup_cache:
|
|
+ rpms = __build_id_lookup_cache[build_id]
|
|
+ if rpms is not None:
|
|
+ for r in rpms:
|
|
+ add_rpm_suggestion(r)
|
|
+ return
|
|
+
|
|
+ # Make sure the cache entry exists before we do the lookup.
|
|
+ # If, for any reason, the lookup raises an exception, then
|
|
+ # having a cache entry will prevent us retrying this lookup in
|
|
+ # the future.
|
|
+ __build_id_lookup_cache[build_id] = None
|
|
+
|
|
+ # Now do the lookup. This is the slow part.
|
|
+ find_objfile_suggestions_slow_core(build_id)
|
|
+
|
|
+ # Fill in the cache, for a given build-id which RPMs were
|
|
+ # suggested.
|
|
+ rpms = []
|
|
+ for r in __suggest_rpms:
|
|
+ rpms.append(r)
|
|
+ __build_id_lookup_cache[build_id] = rpms
|
|
+
|
|
+
|
|
+ # Given BUILD_ID, a string containing a build-id, just record that we
|
|
+ # should advise the user to try installing RPMs based on this build-id.
|
|
+ def find_objfile_suggestions_fast(build_id):
|
|
+ add_build_id_suggestion(build_id)
|
|
+
|
|
+ # Given BUILD_ID, a string containing a build-id, which GDB has failed
|
|
+ # to find, possibly record some information so that we can, at the next
|
|
+ # prompt, give some RPM installation advice to the user.
|
|
+ #
|
|
+ # We have two different strategies for RPM lookup based on a build-id,
|
|
+ # one approach is that we actually lookup the RPMs and only suggest
|
|
+ # something if there is a suitable RPM. However, this is pretty slow,
|
|
+ # and users will probably find this annoying.
|
|
+ #
|
|
+ # So we also have a fast way. With this approach we just record the
|
|
+ # build-id that was missing and tell the user to try installing based on
|
|
+ # the build-id. The downside with this is that if there is no RPM for
|
|
+ # that build-id, then the user will try the command, but nothing will
|
|
+ # install.
|
|
+ def find_objfile_suggestions(build_id):
|
|
+ if rpm_suggestion_is_disabled():
|
|
+ return
|
|
+
|
|
+ if param_rpm_suggestion_build_id_mode.fast_mode():
|
|
+ find_objfile_suggestions_fast(build_id)
|
|
+ else:
|
|
+ find_objfile_suggestions_slow(build_id)
|
|
+
|
|
+ # A missing debug handler class. Just forwards the name of the
|
|
+ # objfile for which we are missing debug information to
|
|
+ # find_debug_suggestions.
|
|
+ class RPM_MissingDebugHandler(gdb.missing_debug.MissingDebugHandler):
|
|
+ def __init__(self):
|
|
+ super().__init__("rpm-suggestions")
|
|
+
|
|
+ def __call__(self, objfile):
|
|
+ find_debug_suggestions(objfile.filename)
|
|
+ return False
|
|
+
|
|
+ # A missing objfile handler class. Just forwards the build-id of
|
|
+ # the objfile that is missing to find_objfile_suggestions.
|
|
+ class RPM_MissingObjfileHandler(gdb.missing_objfile.MissingObjfileHandler):
|
|
+ def __init__(self):
|
|
+ super().__init__("rpm-suggestions")
|
|
+
|
|
+ def __call__(self, pspace, build_id, filename):
|
|
+ find_objfile_suggestions(build_id)
|
|
+ return False
|
|
+
|
|
+ # Take a non-empty list of RPM names and print a command line a
|
|
+ # user could run to install these RPMs.
|
|
+ def print_rpm_suggestions(rpm_name_list):
|
|
+ print("Missing rpms, try: dnf --enablerepo='*debug*' install " + ' '.join(rpm_name_list))
|
|
+
|
|
+ # Take a non-empty list of build-id strings and print a series of
|
|
+ # lines that a user could run to instll the RPMs that provide
|
|
+ # files with this build-id.
|
|
+ #
|
|
+ # The printed commands will also install the corresponding debug
|
|
+ # packages for the executable with the given build-id.
|
|
+ def print_build_id_suggestions(build_id_list):
|
|
+ for build_id in build_id_list:
|
|
+ print("Missing file(s), try: dnf --enablerepo='*debug*' install "
|
|
+ + build_id_to_usr_lib_filename(build_id, False)
|
|
+ + ' '
|
|
+ + build_id_to_usr_lib_filename(build_id, True, ".debug"))
|
|
+
|
|
+ # Called before GDB displays its prompt. If the global __SUGGEST_RPMS
|
|
+ # dictionary is not empty, then this hook prints the keys of this
|
|
+ # dictionary as strings which are the names of RPMs. This hook formats
|
|
+ # each RPM name into a suggested 'dnf install' command and suggests this
|
|
+ # to the user.
|
|
+ #
|
|
+ # Additionally, if the global __SUGGEST_BUILD_IDS dictionary is not
|
|
+ # empty, then this hook uses the keys of this dictionary as build-ids
|
|
+ # that were found to be missing, and formats these into some file based
|
|
+ # 'dnf install' suggestions to the user.
|
|
+ def before_prompt():
|
|
+ global __suggest_rpms
|
|
+ global __suggest_build_ids
|
|
+ global __searching_message_printed
|
|
+
|
|
+ # We allow the searching message to be printed just once
|
|
+ # between prompts.
|
|
+ __searching_message_printed = False
|
|
+
|
|
+ if len(__suggest_rpms) > 0:
|
|
+ print_rpm_suggestions(__suggest_rpms.keys())
|
|
+ __suggest_rpms = {}
|
|
+
|
|
+ if len(__suggest_build_ids) > 0:
|
|
+ print_build_id_suggestions(__suggest_build_ids.keys())
|
|
+ __suggest_build_ids = {}
|
|
+
|
|
+ # Called when the executable within a progrm space is changed. Clear
|
|
+ # the lists of RPM suggestions. We only clear the previous suggestion
|
|
+ # list when the executable really changes. If the user simply
|
|
+ # recompiles the executable, then we don't both clearing this list.
|
|
+ def executable_changed_handler(event):
|
|
+ global __missing_rpms
|
|
+ global __suggest_rpms
|
|
+ global __suggest_build_ids
|
|
+ global __missing_build_ids
|
|
+
|
|
+ if not event.reload:
|
|
+ __missing_rpms = {}
|
|
+ __suggest_rpms = {}
|
|
+ __missing_build_ids = {}
|
|
+ __suggest_build_ids = {}
|
|
+
|
|
+
|
|
+ # Attach to the required GDB events.
|
|
+ gdb.events.executable_changed.connect(executable_changed_handler)
|
|
+ gdb.events.before_prompt.connect(before_prompt)
|
|
+
|
|
+ # Register the missing debug and missing objfile handlers with GDB.
|
|
+ gdb.missing_debug.register_handler(None, RPM_MissingDebugHandler())
|
|
+ gdb.missing_objfile.register_handler(None, RPM_MissingObjfileHandler())
|
|
+
|
|
+ # Implement the core of 'info rpm-suggestions'. Reprint all rpm
|
|
+ # suggestions.
|
|
+ def info_rpm_suggestions():
|
|
+ global __missing_rpms
|
|
+ global __missing_build_ids
|
|
+
|
|
+ if len(__missing_rpms) == 0 and len(__missing_build_ids) == 0:
|
|
+ print("No RPM suggestions have been made so far.")
|
|
+ return
|
|
+
|
|
+ if len(__missing_rpms) > 0:
|
|
+ print_rpm_suggestions(__missing_rpms.keys())
|
|
+ if len(__missing_build_ids) > 0:
|
|
+ print_build_id_suggestions(__missing_build_ids.keys())
|
|
+
|
|
+####################################################################
|
|
+# The following code is outside the 'else' block of the attempt to #
|
|
+# load the 'rpm' module. Nothing after this point depends on the #
|
|
+# 'rpm' module. #
|
|
+####################################################################
|
|
+
|
|
+# The 'set rpm-suggestion' prefix command.
|
|
+class rpm_suggestion_set_prefix(gdb.Command):
|
|
+ """Prefix command for 'set' rpm-suggestion related commands."""
|
|
+
|
|
+ def __init__(self):
|
|
+ super().__init__("set rpm-suggestion", gdb.COMMAND_NONE,
|
|
+ gdb.COMPLETE_NONE, True)
|
|
+
|
|
+# The 'show rpm-suggestion' prefix command.
|
|
+class rpm_suggestion_show_prefix(gdb.Command):
|
|
+ """Prefix command for 'show' rpm-suggestion related commands."""
|
|
+
|
|
+ def __init__(self):
|
|
+ super().__init__("show rpm-suggestion", gdb.COMMAND_NONE,
|
|
+ gdb.COMPLETE_NONE, True)
|
|
+
|
|
+# The 'set/show rpm-suggestion enabled' command.
|
|
+class rpm_suggestion_enabled(gdb.Parameter):
|
|
+ """
|
|
+ When 'on' GDB will search for RPMS that might provide additional
|
|
+ debug information, or provide missing executables or shared
|
|
+ libraries (when opening a core file), and will make suggestions
|
|
+ about what should be installed.
|
|
+
|
|
+ When 'off' GDB will not make these suggestions.
|
|
+ """
|
|
+
|
|
+ set_doc = "Set whether to perform rpm-suggestion."
|
|
+ show_doc = "Show whether rpm-suggestion is enabled."
|
|
+
|
|
+ def __init__(self):
|
|
+ super().__init__("rpm-suggestion enabled", gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)
|
|
+ self.value = True
|
|
+
|
|
+# The 'set/show rpm-suggestion enabled' command.
|
|
+class rpm_suggestion_build_id_mode(gdb.Parameter):
|
|
+ """
|
|
+ When set to 'fast' (the default), GDB doesn't try to map a build-id to
|
|
+ an actual RPM, instead, GDB just suggests a command based on the
|
|
+ build-id which might install some RPMs, if there are any RPMs that
|
|
+ supply that build-id. However, it is equally possible that there are no
|
|
+ suitable RPMs, and nothing will install. This approach has almost zero
|
|
+ overhead.
|
|
+
|
|
+ When set to 'slow', GDB first does the build-id to RPM check itself, and
|
|
+ only if something is found are RPMs installation commands suggested.
|
|
+ The suggested command will include the name of the RPM to install. This
|
|
+ approach is considerably slower as querying the RPM database for the RPM
|
|
+ that supplies a specific file is slow.
|
|
+ """
|
|
+
|
|
+ set_doc = "Set how build-id based rpm suggestions should be performed."
|
|
+ show_doc = "Show how build-id based rpm suggestions shoud be performed."
|
|
+
|
|
+ def __init__(self):
|
|
+ super().__init__("rpm-suggestion build-id-mode",
|
|
+ gdb.COMMAND_NONE, gdb.PARAM_ENUM, ["fast", "slow"])
|
|
+ self.value = "fast"
|
|
+
|
|
+ def fast_mode(self):
|
|
+ return self.value == "fast"
|
|
+
|
|
+# The 'info rpm-suggestions' command.
|
|
+class rpm_suggestion_info(gdb.Command):
|
|
+ """Relist RPM suggestions.
|
|
+
|
|
+ Relist any RPM installation suggestions that have been made
|
|
+ since the executable was last changed."""
|
|
+ def __init__(self):
|
|
+ super().__init__("info rpm-suggestions", gdb.COMMAND_NONE, gdb.COMPLETE_NONE)
|
|
+
|
|
+ def invoke(self, args, from_tty):
|
|
+ if args != "":
|
|
+ raise gdb.GdbError("unexpected arguments: %s" % args)
|
|
+
|
|
+ info_rpm_suggestions ()
|
|
+
|
|
+
|
|
+# Create the 'set/show rpm-suggestion' commands.
|
|
+rpm_suggestion_set_prefix()
|
|
+rpm_suggestion_show_prefix()
|
|
+param_rpm_suggestion_enabled = rpm_suggestion_enabled()
|
|
+param_rpm_suggestion_build_id_mode = rpm_suggestion_build_id_mode()
|
|
+
|
|
+# Create the 'info rpm-suggestions' commands.
|
|
+rpm_suggestion_info()
|
|
diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c
|
|
@@ -0,0 +1,21 @@
|
|
+/* Copyright 2010 Free Software Foundation, Inc.
|
|
+
|
|
+ This file is part of GDB.
|
|
+
|
|
+ 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 <http://www.gnu.org/licenses/>. */
|
|
+
|
|
+void
|
|
+lib (void)
|
|
+{
|
|
+}
|
|
diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c
|
|
@@ -0,0 +1,25 @@
|
|
+/* Copyright 2010 Free Software Foundation, Inc.
|
|
+
|
|
+ This file is part of GDB.
|
|
+
|
|
+ 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 <http://www.gnu.org/licenses/>. */
|
|
+
|
|
+extern void lib (void);
|
|
+
|
|
+int
|
|
+main (void)
|
|
+{
|
|
+ lib ();
|
|
+ return 0;
|
|
+}
|
|
diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp
|
|
@@ -0,0 +1,104 @@
|
|
+# Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
|
+
|
|
+require allow_shlib_tests
|
|
+
|
|
+set testfile "gcore-buildid-exec-but-not-solib"
|
|
+set srcmainfile ${testfile}-main.c
|
|
+set srclibfile ${testfile}-lib.c
|
|
+set libfile [standard_output_file ${testfile}-lib.so]
|
|
+set objfile [standard_output_file ${testfile}-main.o]
|
|
+set executable ${testfile}-main
|
|
+set binfile [standard_output_file ${executable}]
|
|
+set gcorefile [standard_output_file ${executable}.gcore]
|
|
+set outdir [file dirname $binfile]
|
|
+
|
|
+if { [gdb_compile_shlib ${srcdir}/${subdir}/${srclibfile} ${libfile} "debug additional_flags=-Wl,--build-id"] != ""
|
|
+ || [gdb_compile ${srcdir}/${subdir}/${srcmainfile} ${objfile} object {debug}] != "" } {
|
|
+ unsupported "-Wl,--build-id compilation failed"
|
|
+ return -1
|
|
+}
|
|
+set opts [list debug shlib=${libfile} "additional_flags=-Wl,--build-id"]
|
|
+if { [gdb_compile ${objfile} ${binfile} executable $opts] != "" } {
|
|
+ unsupported "-Wl,--build-id compilation failed"
|
|
+ return -1
|
|
+}
|
|
+
|
|
+clean_restart $executable
|
|
+gdb_load_shlib $libfile
|
|
+
|
|
+# Does this gdb support gcore?
|
|
+set test "help gcore"
|
|
+gdb_test_multiple $test $test {
|
|
+ -re "Undefined command: .gcore.*\r\n$gdb_prompt $" {
|
|
+ # gcore command not supported -- nothing to test here.
|
|
+ unsupported "gdb does not support gcore on this target"
|
|
+ return -1;
|
|
+ }
|
|
+ -re "Save a core file .*\r\n$gdb_prompt $" {
|
|
+ pass $test
|
|
+ }
|
|
+}
|
|
+
|
|
+if { ![runto lib] } then {
|
|
+ return -1
|
|
+}
|
|
+
|
|
+set escapedfilename [string_to_regexp ${gcorefile}]
|
|
+
|
|
+set test "save a corefile"
|
|
+gdb_test_multiple "gcore ${gcorefile}" $test {
|
|
+ -re "Saved corefile ${escapedfilename}\r\n$gdb_prompt $" {
|
|
+ pass $test
|
|
+ }
|
|
+ -re "Can't create a corefile\r\n$gdb_prompt $" {
|
|
+ unsupported $test
|
|
+ return -1
|
|
+ }
|
|
+}
|
|
+
|
|
+# Now restart gdb and load the corefile.
|
|
+
|
|
+clean_restart $executable
|
|
+gdb_load_shlib $libfile
|
|
+
|
|
+set buildid [build_id_debug_filename_get $libfile]
|
|
+
|
|
+regsub {\.debug$} $buildid {} buildid
|
|
+
|
|
+set debugdir [standard_output_file ${testfile}-debugdir]
|
|
+file delete -force -- $debugdir
|
|
+
|
|
+file mkdir $debugdir/[file dirname $libfile]
|
|
+file copy $libfile $debugdir/${libfile}
|
|
+
|
|
+file mkdir $debugdir/[file dirname $buildid]
|
|
+file copy $libfile $debugdir/${buildid}
|
|
+
|
|
+remote_exec build "ln -s /lib ${debugdir}/"
|
|
+remote_exec build "ln -s /lib64 ${debugdir}/"
|
|
+# /usr is not needed, all the libs are in /lib64: libm.so.6 libc.so.6 ld-linux-x86-64.so.2
|
|
+
|
|
+gdb_test_no_output "set solib-absolute-prefix $debugdir" \
|
|
+ "set solib-absolute-prefix"
|
|
+
|
|
+gdb_test_no_output "set debug-file-directory $debugdir" "set debug-file-directory"
|
|
+
|
|
+gdb_test "core ${gcorefile}" "Core was generated by .*" "re-load generated corefile"
|
|
+
|
|
+gdb_test "frame" "#0 \[^\r\n\]* lib .*" "library got loaded"
|
|
+
|
|
+gdb_test "bt"
|
|
+gdb_test "info shared"
|
|
diff --git a/gdb/testsuite/gdb.base/gdbinit-history.exp b/gdb/testsuite/gdb.base/gdbinit-history.exp
|
|
--- a/gdb/testsuite/gdb.base/gdbinit-history.exp
|
|
+++ b/gdb/testsuite/gdb.base/gdbinit-history.exp
|
|
@@ -179,7 +179,8 @@ proc test_empty_history_filename { } {
|
|
global env
|
|
global gdb_prompt
|
|
|
|
- set common_history [list "set height 0" "set width 0"]
|
|
+ set common_history [list "set height 0" "set width 0" \
|
|
+ "set rpm-suggestion enabled off"]
|
|
|
|
set test_dir [standard_output_file history_test]
|
|
remote_exec host "mkdir -p $test_dir"
|
|
diff --git a/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp
|
|
@@ -0,0 +1,60 @@
|
|
+# Copyright (C) 2014 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 <http://www.gnu.org/licenses/>.
|
|
+
|
|
+# Create a core file, then hide the executable. Restart GDB and load
|
|
+# the core file. Check GDB gives a message suggesting a 'dnf' command
|
|
+# to try and install the executable based on its build-id.
|
|
+
|
|
+standard_testfile "normal.c"
|
|
+
|
|
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
|
|
+ return -1
|
|
+}
|
|
+
|
|
+# Get the build-id of the file.
|
|
+set build_id_debug_file [build_id_debug_filename_get $binfile]
|
|
+regsub -all ".debug$" $build_id_debug_file "" build_id_without_debug
|
|
+
|
|
+# Run to main.
|
|
+if { ![runto_main] } {
|
|
+ return -1
|
|
+}
|
|
+
|
|
+# We first need to generate a corefile.
|
|
+set corefilename "[standard_output_file gcore.test]"
|
|
+if { ![gdb_gcore_cmd "$corefilename" "save corefile"] } {
|
|
+ untested "could not generate a corefile"
|
|
+ return -1
|
|
+}
|
|
+
|
|
+# Move the binfile to a temporary name.
|
|
+remote_exec build "mv $binfile ${binfile}.old"
|
|
+
|
|
+# Reinitialize GDB and see if we get a dnf suggestion.
|
|
+clean_restart
|
|
+
|
|
+gdb_test "set rpm-suggestion enabled on" "" \
|
|
+ "turn on rpm-suggestion feature"
|
|
+
|
|
+# GDB only makes build-id based RPM suggestions if /usr/lib is in
|
|
+# the debug-file-directory list, the reason being that system RPMs
|
|
+# will always install under this location. If GDB is not looking
|
|
+# here then there's no point making suggestions.
|
|
+gdb_test "set debug-file-directory /usr/lib/" "" \
|
|
+ "set debug-file-directory"
|
|
+
|
|
+gdb_test "core-file [standard_output_file gcore.test]" \
|
|
+ "Missing file\\(s\\), try: dnf --enablerepo='\\*debug\\*' install [string_to_regexp /usr/lib/$build_id_without_debug] [string_to_regexp /usr/lib/debug/$build_id_debug_file]" \
|
|
+ "test first yum/dnf warning"
|
|
diff --git a/gdb/testsuite/gdb.python/py-missing-debug.py b/gdb/testsuite/gdb.python/py-missing-debug.py
|
|
--- a/gdb/testsuite/gdb.python/py-missing-debug.py
|
|
+++ b/gdb/testsuite/gdb.python/py-missing-debug.py
|
|
@@ -19,6 +19,13 @@ from enum import Enum
|
|
import gdb
|
|
from gdb.missing_debug import MissingDebugHandler
|
|
|
|
+# This is a RHEL/Fedora work around: There's already a
|
|
+# missing-debug-info handler registered for these versions of GDB.
|
|
+# Discard the handler now so that the tests will pass (the tests
|
|
+# assume no handler is currently registered).
|
|
+gdb.missing_debug_handlers = []
|
|
+
|
|
+
|
|
# A global log that is filled in by instances of the LOG_HANDLER class
|
|
# when they are called.
|
|
handler_call_log = []
|
|
@@ -118,4 +125,7 @@ def register(name, locus=None):
|
|
rhandler = exception_handler()
|
|
handler_obj = handler()
|
|
|
|
+# Discard the rpm-suggestion handler.
|
|
+gdb.missing_file_handlers = []
|
|
+
|
|
print("Success")
|
|
diff --git a/gdb/testsuite/gdb.python/py-missing-objfile.py b/gdb/testsuite/gdb.python/py-missing-objfile.py
|
|
--- a/gdb/testsuite/gdb.python/py-missing-objfile.py
|
|
+++ b/gdb/testsuite/gdb.python/py-missing-objfile.py
|
|
@@ -164,4 +164,7 @@ def register(name, locus=None):
|
|
rhandler = exception_handler()
|
|
handler_obj = handler()
|
|
|
|
+# Discard the rpm-suggestion handler.
|
|
+gdb.missing_file_handlers = []
|
|
+
|
|
print("Success")
|
|
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
|
|
--- a/gdb/testsuite/lib/gdb.exp
|
|
+++ b/gdb/testsuite/lib/gdb.exp
|
|
@@ -255,7 +255,8 @@ if ![info exists INTERNAL_GDBFLAGS] {
|
|
"-nx" \
|
|
"-q" \
|
|
{-iex "set height 0"} \
|
|
- {-iex "set width 0"}]]
|
|
+ {-iex "set width 0"} \
|
|
+ {-iex "set rpm-suggestion enabled off"}]]
|
|
|
|
# If DEBUGINFOD_URLS is set, gdb will try to download sources and
|
|
# debug info for f.i. system libraries. Prevent this.
|
|
@@ -2610,6 +2611,18 @@ proc default_gdb_start { } {
|
|
}
|
|
}
|
|
|
|
+ # Turn off the missing debug info messages as the testsuite does
|
|
+ # not expect them.
|
|
+ send_gdb "set rpm-suggestion enabled off\n"
|
|
+ gdb_expect 10 {
|
|
+ -re "$gdb_prompt $" {
|
|
+ verbose "Disabled the missing debug info messages." 2
|
|
+ }
|
|
+ timeout {
|
|
+ warning "Could not disable the missing debug info messages."
|
|
+ }
|
|
+ }
|
|
+
|
|
gdb_debug_init
|
|
return 0
|
|
}
|
|
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
|
|
--- a/gdb/testsuite/lib/mi-support.exp
|
|
+++ b/gdb/testsuite/lib/mi-support.exp
|
|
@@ -321,6 +321,17 @@ proc default_mi_gdb_start { { flags {} } } {
|
|
warning "Couldn't set the width to 0."
|
|
}
|
|
}
|
|
+ # Turn off the missing debug info messages as the testsuite does
|
|
+ # not expect them.
|
|
+ send_gdb "190-gdb-set rpm-suggestion enabled off\n"
|
|
+ gdb_expect 10 {
|
|
+ -re ".*190-gdb-set rpm-suggestion enabled off\r\n190\\\^done\r\n$mi_gdb_prompt$" {
|
|
+ verbose "Disabled the missing debug info messages." 2
|
|
+ }
|
|
+ timeout {
|
|
+ warning "Could not disable the missing debug info messages."
|
|
+ }
|
|
+ }
|
|
|
|
if { $separate_inferior_pty } {
|
|
mi_create_inferior_pty
|