The GDB 7.8 features are: * Python Scripting - You can now access frame registers from Python scripts. - New attribute 'producer' for gdb.Symtab objects. * New Python-based convenience functions: - $_caller_is(name [, number_of_frames]) - $_caller_matches(regexp [, number_of_frames]) - $_any_caller_is(name [, number_of_frames]) - $_any_caller_matches(regexp [, number_of_frames]) * New commands - queue-signal signal-name-or-number Queue a signal to be delivered to the thread when it is resumed. * On resume, GDB now always passes the signal the program had stopped for to the thread the signal was sent to, even if the user changed threads before resuming. Previously GDB would often (but not always) deliver the signal to the thread that happens to be current at resume time. * Conversely, the "signal" command now consistently delivers the requested signal to the current thread. GDB now asks for confirmation if the program had stopped for a signal and the user switched threads meanwhile. * "breakpoint always-inserted" modes "off" and "auto" merged. Now, when 'breakpoint always-inserted mode' is set to "off", GDB won't remove breakpoints from the target until all threads stop, even in non-stop mode. The "auto" mode has been removed, and "off" is now the default mode. * MI changes - The -list-thread-groups command outputs an exit-code field for inferiors that have exited. OBS-URL: https://build.opensuse.org/package/show/devel:gcc/gdb?expand=0&rev=115
309 lines
11 KiB
Diff
309 lines
11 KiB
Diff
https://bugzilla.redhat.com/show_bug.cgi?id=1020004
|
|
|
|
Index: gdb-7.8.50.20141228/gdb/data-directory/Makefile.in
|
|
===================================================================
|
|
--- gdb-7.8.50.20141228.orig/gdb/data-directory/Makefile.in 2015-01-05 22:51:10.707756810 +0100
|
|
+++ gdb-7.8.50.20141228/gdb/data-directory/Makefile.in 2015-01-05 22:51:48.608923139 +0100
|
|
@@ -60,6 +60,8 @@ PYTHON_FILE_LIST = \
|
|
gdb/frames.py \
|
|
gdb/FrameIterator.py \
|
|
gdb/FrameDecorator.py \
|
|
+ gdb/FrameWrapper.py \
|
|
+ gdb/backtrace.py \
|
|
gdb/types.py \
|
|
gdb/printing.py \
|
|
gdb/prompt.py \
|
|
@@ -74,6 +76,7 @@ PYTHON_FILE_LIST = \
|
|
gdb/command/pretty_printers.py \
|
|
gdb/command/prompt.py \
|
|
gdb/command/explore.py \
|
|
+ gdb/command/backtrace.py \
|
|
gdb/function/__init__.py \
|
|
gdb/function/caller_is.py \
|
|
gdb/function/strfns.py \
|
|
Index: gdb-7.8.50.20141228/gdb/python/lib/gdb/FrameWrapper.py
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ gdb-7.8.50.20141228/gdb/python/lib/gdb/FrameWrapper.py 2015-01-05 22:51:24.706818245 +0100
|
|
@@ -0,0 +1,122 @@
|
|
+# Wrapper API for frames.
|
|
+
|
|
+# Copyright (C) 2008, 2009 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
|
|
+
|
|
+# FIXME: arguably all this should be on Frame somehow.
|
|
+class FrameWrapper:
|
|
+ def __init__ (self, frame):
|
|
+ self.frame = frame;
|
|
+
|
|
+ def write_symbol (self, stream, sym, block):
|
|
+ if len (sym.linkage_name):
|
|
+ nsym, is_field_of_this = gdb.lookup_symbol (sym.linkage_name, block)
|
|
+ if nsym.addr_class != gdb.SYMBOL_LOC_REGISTER:
|
|
+ sym = nsym
|
|
+
|
|
+ stream.write (sym.print_name + "=")
|
|
+ try:
|
|
+ val = self.read_var (sym)
|
|
+ if val != None:
|
|
+ val = str (val)
|
|
+ # FIXME: would be nice to have a more precise exception here.
|
|
+ except RuntimeError, text:
|
|
+ val = text
|
|
+ if val == None:
|
|
+ stream.write ("???")
|
|
+ else:
|
|
+ stream.write (str (val))
|
|
+
|
|
+ def print_frame_locals (self, stream, func):
|
|
+
|
|
+ try:
|
|
+ block = self.frame.block()
|
|
+ except RuntimeError:
|
|
+ block = None
|
|
+
|
|
+ while block != None:
|
|
+ if block.is_global or block.is_static:
|
|
+ break
|
|
+
|
|
+ for sym in block:
|
|
+ if sym.is_argument:
|
|
+ continue;
|
|
+
|
|
+ self.write_symbol (stream, sym, block)
|
|
+ stream.write ('\n')
|
|
+
|
|
+ def print_frame_args (self, stream, func):
|
|
+
|
|
+ try:
|
|
+ block = self.frame.block()
|
|
+ except RuntimeError:
|
|
+ block = None
|
|
+
|
|
+ while block != None:
|
|
+ if block.function != None:
|
|
+ break
|
|
+ block = block.superblock
|
|
+
|
|
+ first = True
|
|
+ for sym in block:
|
|
+ if not sym.is_argument:
|
|
+ continue;
|
|
+
|
|
+ if not first:
|
|
+ stream.write (", ")
|
|
+
|
|
+ self.write_symbol (stream, sym, block)
|
|
+ first = False
|
|
+
|
|
+ # FIXME: this should probably just be a method on gdb.Frame.
|
|
+ # But then we need stream wrappers.
|
|
+ def describe (self, stream, full):
|
|
+ if self.type () == gdb.DUMMY_FRAME:
|
|
+ stream.write (" <function called from gdb>\n")
|
|
+ elif self.type () == gdb.SIGTRAMP_FRAME:
|
|
+ stream.write (" <signal handler called>\n")
|
|
+ else:
|
|
+ sal = self.find_sal ()
|
|
+ pc = self.pc ()
|
|
+ name = self.name ()
|
|
+ if not name:
|
|
+ name = "??"
|
|
+ if pc != sal.pc or not sal.symtab:
|
|
+ stream.write (" 0x%08x in" % pc)
|
|
+ stream.write (" " + name + " (")
|
|
+
|
|
+ func = self.function ()
|
|
+ self.print_frame_args (stream, func)
|
|
+
|
|
+ stream.write (")")
|
|
+
|
|
+ if sal.symtab and sal.symtab.filename:
|
|
+ stream.write (" at " + sal.symtab.filename)
|
|
+ stream.write (":" + str (sal.line))
|
|
+
|
|
+ if not self.name () or (not sal.symtab or not sal.symtab.filename):
|
|
+ lib = gdb.solib_name (pc)
|
|
+ if lib:
|
|
+ stream.write (" from " + lib)
|
|
+
|
|
+ stream.write ("\n")
|
|
+
|
|
+ if full:
|
|
+ self.print_frame_locals (stream, func)
|
|
+
|
|
+ def __getattr__ (self, name):
|
|
+ return getattr (self.frame, name)
|
|
Index: gdb-7.8.50.20141228/gdb/python/lib/gdb/backtrace.py
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ gdb-7.8.50.20141228/gdb/python/lib/gdb/backtrace.py 2015-01-05 22:51:24.706818245 +0100
|
|
@@ -0,0 +1,42 @@
|
|
+# Filtering backtrace.
|
|
+
|
|
+# Copyright (C) 2008, 2011 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 itertools
|
|
+
|
|
+# Our only exports.
|
|
+__all__ = ['push_frame_filter', 'create_frame_filter']
|
|
+
|
|
+old_frame_filter = None
|
|
+
|
|
+def push_frame_filter (constructor):
|
|
+ """Register a new backtrace filter class with the 'backtrace' command.
|
|
+The filter will be passed an iterator as an argument. The iterator
|
|
+will return gdb.Frame-like objects. The filter should in turn act as
|
|
+an iterator returning such objects."""
|
|
+ global old_frame_filter
|
|
+ if old_frame_filter == None:
|
|
+ old_frame_filter = constructor
|
|
+ else:
|
|
+ old_frame_filter = lambda iterator, filter = frame_filter: constructor (filter(iterator))
|
|
+
|
|
+def create_frame_filter (iter):
|
|
+ global old_frame_filter
|
|
+ if old_frame_filter is None:
|
|
+ return iter
|
|
+ return old_frame_filter (iter)
|
|
+
|
|
Index: gdb-7.8.50.20141228/gdb/python/lib/gdb/command/backtrace.py
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ gdb-7.8.50.20141228/gdb/python/lib/gdb/command/backtrace.py 2015-01-05 22:51:24.707818249 +0100
|
|
@@ -0,0 +1,106 @@
|
|
+# New backtrace command.
|
|
+
|
|
+# Copyright (C) 2008, 2009, 2011 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.backtrace
|
|
+import itertools
|
|
+from gdb.FrameIterator import FrameIterator
|
|
+from gdb.FrameWrapper import FrameWrapper
|
|
+import sys
|
|
+
|
|
+class ReverseBacktraceParameter (gdb.Parameter):
|
|
+ """The new-backtrace command can show backtraces in 'reverse' order.
|
|
+This means that the innermost frame will be printed last.
|
|
+Note that reverse backtraces are more expensive to compute."""
|
|
+
|
|
+ set_doc = "Enable or disable reverse backtraces."
|
|
+ show_doc = "Show whether backtraces will be printed in reverse order."
|
|
+
|
|
+ def __init__(self):
|
|
+ gdb.Parameter.__init__ (self, "reverse-backtrace",
|
|
+ gdb.COMMAND_STACK, gdb.PARAM_BOOLEAN)
|
|
+ # Default to compatibility with gdb.
|
|
+ self.value = False
|
|
+
|
|
+class FilteringBacktrace (gdb.Command):
|
|
+ """Print backtrace of all stack frames, or innermost COUNT frames.
|
|
+With a negative argument, print outermost -COUNT frames.
|
|
+Use of the 'full' qualifier also prints the values of the local variables.
|
|
+Use of the 'raw' qualifier avoids any filtering by loadable modules.
|
|
+"""
|
|
+
|
|
+ def __init__ (self):
|
|
+ # FIXME: this is not working quite well enough to replace
|
|
+ # "backtrace" yet.
|
|
+ gdb.Command.__init__ (self, "new-backtrace", gdb.COMMAND_STACK)
|
|
+ self.reverse = ReverseBacktraceParameter()
|
|
+
|
|
+ def reverse_iter (self, iter):
|
|
+ result = []
|
|
+ for item in iter:
|
|
+ result.append (item)
|
|
+ result.reverse()
|
|
+ return result
|
|
+
|
|
+ def final_n (self, iter, x):
|
|
+ result = []
|
|
+ for item in iter:
|
|
+ result.append (item)
|
|
+ return result[x:]
|
|
+
|
|
+ def invoke (self, arg, from_tty):
|
|
+ i = 0
|
|
+ count = 0
|
|
+ filter = True
|
|
+ full = False
|
|
+
|
|
+ for word in arg.split (" "):
|
|
+ if word == '':
|
|
+ continue
|
|
+ elif word == 'raw':
|
|
+ filter = False
|
|
+ elif word == 'full':
|
|
+ full = True
|
|
+ else:
|
|
+ count = int (word)
|
|
+
|
|
+ # FIXME: provide option to start at selected frame
|
|
+ # However, should still number as if starting from newest
|
|
+ newest_frame = gdb.newest_frame()
|
|
+ iter = itertools.imap (FrameWrapper,
|
|
+ FrameIterator (newest_frame))
|
|
+ if filter:
|
|
+ iter = gdb.backtrace.create_frame_filter (iter)
|
|
+
|
|
+ # Now wrap in an iterator that numbers the frames.
|
|
+ iter = itertools.izip (itertools.count (0), iter)
|
|
+
|
|
+ # Reverse if the user wanted that.
|
|
+ if self.reverse.value:
|
|
+ iter = self.reverse_iter (iter)
|
|
+
|
|
+ # Extract sub-range user wants.
|
|
+ if count < 0:
|
|
+ iter = self.final_n (iter, count)
|
|
+ elif count > 0:
|
|
+ iter = itertools.islice (iter, 0, count)
|
|
+
|
|
+ for pair in iter:
|
|
+ sys.stdout.write ("#%-2d" % pair[0])
|
|
+ pair[1].describe (sys.stdout, full)
|
|
+
|
|
+FilteringBacktrace()
|