Backported Python frame filters (Phil Muldoon).

- Backported breakpoint conditions crash fix (Sergio Durigan Junior).
This commit is contained in:
Jan Kratochvil 2013-05-21 13:54:33 +02:00
parent 6d620330a4
commit 89fbbfccaf
7 changed files with 5861 additions and 562 deletions

View File

@ -4,11 +4,11 @@
to install and uninstall.
* gstack.sh, gstack.1: New files.
Index: gdb-7.5.91.20130407/gdb/Makefile.in
Index: gdb-7.6/gdb/Makefile.in
===================================================================
--- gdb-7.5.91.20130407.orig/gdb/Makefile.in 2013-04-11 16:50:33.000000000 +0200
+++ gdb-7.5.91.20130407/gdb/Makefile.in 2013-04-11 16:52:51.032280294 +0200
@@ -1027,7 +1027,7 @@ info install-info clean-info dvi pdf ins
--- gdb-7.6.orig/gdb/Makefile.in 2013-05-21 13:26:33.496820763 +0200
+++ gdb-7.6/gdb/Makefile.in 2013-05-21 13:26:33.609819579 +0200
@@ -1029,7 +1029,7 @@ info install-info clean-info dvi pdf ins
install: all
@$(MAKE) $(FLAGS_TO_PASS) install-only
@ -17,7 +17,7 @@ Index: gdb-7.5.91.20130407/gdb/Makefile.in
transformed_name=`t='$(program_transform_name)'; \
echo gdb | sed -e "$$t"` ; \
if test "x$$transformed_name" = x; then \
@@ -1058,7 +1058,25 @@ install-only: $(CONFIG_INSTALL)
@@ -1060,7 +1060,25 @@ install-only: $(CONFIG_INSTALL)
install-python:
$(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_DATADIR)/python/gdb
@ -44,7 +44,7 @@ Index: gdb-7.5.91.20130407/gdb/Makefile.in
transformed_name=`t='$(program_transform_name)'; \
echo gdb | sed -e $$t` ; \
if test "x$$transformed_name" = x; then \
@@ -1081,6 +1099,18 @@ uninstall: force $(CONFIG_UNINSTALL)
@@ -1083,6 +1101,18 @@ uninstall: force $(CONFIG_UNINSTALL)
fi
@$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do
@ -63,10 +63,10 @@ Index: gdb-7.5.91.20130407/gdb/Makefile.in
# The C++ name parser can be built standalone for testing.
test-cp-name-parser.o: cp-name-parser.c
$(COMPILE) -DTEST_CPNAMES cp-name-parser.c
Index: gdb-7.5.91.20130407/gdb/gstack.sh
Index: gdb-7.6/gdb/gstack.sh
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.5.91.20130407/gdb/gstack.sh 2013-04-11 16:52:22.093281616 +0200
+++ gdb-7.6/gdb/gstack.sh 2013-05-21 13:26:55.434625908 +0200
@@ -0,0 +1,43 @@
+#!/bin/sh
+
@ -101,7 +101,7 @@ Index: gdb-7.5.91.20130407/gdb/gstack.sh
+
+# Run GDB, strip out unwanted noise.
+# --readnever is no longer used since .gdb_index is now in use.
+$GDB --quiet -nx /proc/$1/exe $1 <<EOF 2>&1 |
+$GDB --quiet -nx $GDBARGS /proc/$1/exe $1 <<EOF 2>&1 |
+set width 0
+set height 0
+set pagination no
@ -111,10 +111,10 @@ Index: gdb-7.5.91.20130407/gdb/gstack.sh
+ -e 's/^\((gdb) \)*//' \
+ -e '/^#/p' \
+ -e '/^Thread/p'
Index: gdb-7.5.91.20130407/gdb/testsuite/gdb.base/gstack.exp
Index: gdb-7.6/gdb/testsuite/gdb.base/gstack.exp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.5.91.20130407/gdb/testsuite/gdb.base/gstack.exp 2013-04-11 16:52:22.093281616 +0200
+++ gdb-7.6/gdb/testsuite/gdb.base/gstack.exp 2013-05-21 13:26:55.434625908 +0200
@@ -0,0 +1,66 @@
+# Copyright (C) 2012 Free Software Foundation, Inc.
+
@ -167,7 +167,7 @@ Index: gdb-7.5.91.20130407/gdb/testsuite/gdb.base/gstack.exp
+# exiting the function. Still we could retry the gstack command if we fail.
+
+set test "spawn gstack"
+set command "sh -c GDB=$GDB\\ sh\\ ${srcdir}/../gstack.sh\\ $pid\\;echo\\ GSTACK-END"
+set command "sh -c GDB=$GDB\\ GDBARGS=-data-directory\\\\\\ $BUILD_DATA_DIRECTORY\\ sh\\ ${srcdir}/../gstack.sh\\ $pid\\;echo\\ GSTACK-END"
+set res [remote_spawn host $command];
+if { $res < 0 || $res == "" } {
+ perror "Spawning $command failed."
@ -182,10 +182,10 @@ Index: gdb-7.5.91.20130407/gdb/testsuite/gdb.base/gstack.exp
+gdb_exit
+
+remote_exec host "kill -9 $pid"
Index: gdb-7.5.91.20130407/gdb/testsuite/gdb.base/gstack.c
Index: gdb-7.6/gdb/testsuite/gdb.base/gstack.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.5.91.20130407/gdb/testsuite/gdb.base/gstack.c 2013-04-11 16:52:22.093281616 +0200
+++ gdb-7.6/gdb/testsuite/gdb.base/gstack.c 2013-05-21 13:26:33.610819569 +0200
@@ -0,0 +1,43 @@
+/* This testcase is part of GDB, the GNU debugger.
+

View File

@ -1,9 +1,7 @@
Index: ./gdb/testsuite/gdb.threads/threadcrash.c
Index: gdb-7.6/gdb/testsuite/gdb.threads/threadcrash.c
===================================================================
RCS file: gdb/testsuite/gdb.threads/threadcrash.c
diff -N gdb/testsuite/gdb.threads/threadcrash.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.threads/threadcrash.c 31 Oct 2006 17:54:38 -0000
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.6/gdb/testsuite/gdb.threads/threadcrash.c 2013-05-21 13:35:45.592059786 +0200
@@ -0,0 +1,301 @@
+/*
+ * The point of this program is to crash in a multi-threaded app.
@ -306,12 +304,10 @@ diff -N gdb/testsuite/gdb.threads/threadcrash.c
+
+ return 0;
+}
Index: ./gdb/testsuite/gdb.threads/threadcrash.exp
Index: gdb-7.6/gdb/testsuite/gdb.threads/threadcrash.exp
===================================================================
RCS file: gdb/testsuite/gdb.threads/threadcrash.exp
diff -N gdb/testsuite/gdb.threads/threadcrash.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.threads/threadcrash.exp 31 Oct 2006 17:54:38 -0000
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.6/gdb/testsuite/gdb.threads/threadcrash.exp 2013-05-21 13:36:01.451056746 +0200
@@ -0,0 +1,37 @@
+# threadcrash.exp - The point of this program is to crash in a multi-threaded app.
+
@ -337,7 +333,7 @@ diff -N gdb/testsuite/gdb.threads/threadcrash.exp
+}
+
+# ${shellfile} argument must not contain any directories.
+set fd [open "|bash ${shellfile} ${binfile} $GDB -nw $GDBFLAGS" r]
+set fd [open "|bash ${shellfile} ${binfile} $GDB $INTERNAL_GDBFLAGS $GDBFLAGS [host_info gdb_opts]" r]
+while { [gets $fd line] >= 0 } {
+ if [regexp " PASS: (.*)$" $line trash message] {
+ pass $message
@ -350,12 +346,10 @@ diff -N gdb/testsuite/gdb.threads/threadcrash.exp
+}
+
+return 0
Index: ./gdb/testsuite/gdb.threads/threadcrash.sh
Index: gdb-7.6/gdb/testsuite/gdb.threads/threadcrash.sh
===================================================================
RCS file: gdb/testsuite/gdb.threads/threadcrash.sh
diff -N gdb/testsuite/gdb.threads/threadcrash.sh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.threads/threadcrash.sh 31 Oct 2006 17:54:38 -0000
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.6/gdb/testsuite/gdb.threads/threadcrash.sh 2013-05-21 13:35:45.593059786 +0200
@@ -0,0 +1,324 @@
+#! /bin/bash
+
@ -681,12 +675,10 @@ diff -N gdb/testsuite/gdb.threads/threadcrash.sh
+rm -rf $WORKDIR
+
+exit $FAILURES
Index: ./gdb/testsuite/gdb.threads/threadcrash.sh-orig
Index: gdb-7.6/gdb/testsuite/gdb.threads/threadcrash.sh-orig
===================================================================
RCS file: gdb/testsuite/gdb.threads/threadcrash.sh-orig
diff -N gdb/testsuite/gdb.threads/threadcrash.sh-orig
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.threads/threadcrash.sh-orig 31 Oct 2006 17:54:38 -0000
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.6/gdb/testsuite/gdb.threads/threadcrash.sh-orig 2013-05-21 13:35:45.593059786 +0200
@@ -0,0 +1,248 @@
+#! /bin/bash
+

View File

@ -2,7 +2,7 @@ http://sourceware.org/gdb/wiki/ProjectArcher
http://sourceware.org/gdb/wiki/ArcherBranchManagement
GIT snapshot:
commit 92cf2d53a9c69b4fb361de662de9100c6e72caa0
commit b1f8c6821303f6eb087fb7f57405483ac8812227
branch jankratochvil/fedora19 - the merge of branches:
jankratochvil/vla
@ -169,22 +169,17 @@ index ca8d89b..811ad72 100644
plongest (high_bound - low_bound + 1));
fprintf_filtered (stream, (is_vector ? ")))" : "]"));
diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
index d98ac77..e248399 100644
index d98ac77..f6a4b99 100644
--- a/gdb/data-directory/Makefile.in
+++ b/gdb/data-directory/Makefile.in
@@ -52,17 +52,28 @@ SYSCALLS_FILES = \
PYTHON_DIR = python
@@ -53,16 +53,21 @@ PYTHON_DIR = python
PYTHON_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(PYTHON_DIR)
PYTHON_FILES = \
+ gdb/FrameIterator.py \
+ gdb/FrameWrapper.py \
gdb/__init__.py \
- gdb/types.py \
- gdb/printing.py \
- gdb/prompt.py \
+ gdb/backtrace.py \
gdb/command/__init__.py \
+ gdb/command/backtrace.py \
+ gdb/command/ignore_errors.py \
+ gdb/command/pahole.py \
gdb/command/type_printers.py \
@ -194,8 +189,6 @@ index d98ac77..e248399 100644
gdb/function/__init__.py \
- gdb/function/strfns.py
+ gdb/function/strfns.py \
+ gdb/command/require.py \
+ gdb/command/upto.py \
+ gdb/function/__init__.py \
+ gdb/function/caller_is.py \
+ gdb/function/in_scope.py \
@ -3778,323 +3771,6 @@ index 155703d..545a615 100644
+ observer_attach_mark_used (print_types_mark_used);
+#endif
}
diff --git a/gdb/python/lib/gdb/FrameIterator.py b/gdb/python/lib/gdb/FrameIterator.py
new file mode 100644
index 0000000..5654546
--- /dev/null
+++ b/gdb/python/lib/gdb/FrameIterator.py
@@ -0,0 +1,33 @@
+# Iterator over 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/>.
+
+class FrameIterator:
+ """An iterator that iterates over frames."""
+
+ def __init__ (self, frame):
+ "Initialize a FrameIterator. FRAME is the starting frame."
+ self.frame = frame
+
+ def __iter__ (self):
+ return self
+
+ def next (self):
+ result = self.frame
+ if result is None:
+ raise StopIteration
+ self.frame = result.older ()
+ return result
diff --git a/gdb/python/lib/gdb/FrameWrapper.py b/gdb/python/lib/gdb/FrameWrapper.py
new file mode 100644
index 0000000..b790a54
--- /dev/null
+++ b/gdb/python/lib/gdb/FrameWrapper.py
@@ -0,0 +1,112 @@
+# 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):
+ if not func:
+ return
+
+ first = True
+ block = func.value
+
+ 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):
+ if not func:
+ return
+
+ first = True
+ block = func.value
+
+ 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_address (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)
diff --git a/gdb/python/lib/gdb/backtrace.py b/gdb/python/lib/gdb/backtrace.py
new file mode 100644
index 0000000..6bb4fb1
--- /dev/null
+++ b/gdb/python/lib/gdb/backtrace.py
@@ -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']
+
+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 frame_filter
+ if frame_filter == None:
+ frame_filter = constructor
+ else:
+ frame_filter = lambda iterator, filter = frame_filter: constructor (filter (iterator))
+
+def create_frame_filter (iter):
+ global frame_filter
+ if frame_filter is None:
+ return iter
+ return frame_filter (iter)
+
diff --git a/gdb/python/lib/gdb/command/backtrace.py b/gdb/python/lib/gdb/command/backtrace.py
new file mode 100644
index 0000000..eeea909
--- /dev/null
+++ b/gdb/python/lib/gdb/command/backtrace.py
@@ -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()
diff --git a/gdb/python/lib/gdb/command/ignore_errors.py b/gdb/python/lib/gdb/command/ignore_errors.py
new file mode 100644
index 0000000..6fa48ff
@ -4225,204 +3901,6 @@ index 0000000..636f99d
+ self.pahole (type, 0, '')
+
+Pahole()
diff --git a/gdb/python/lib/gdb/command/require.py b/gdb/python/lib/gdb/command/require.py
new file mode 100644
index 0000000..1fbc1e8
--- /dev/null
+++ b/gdb/python/lib/gdb/command/require.py
@@ -0,0 +1,57 @@
+# Demand-loading commands.
+
+# 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
+import os
+
+class RequireCommand (gdb.Command):
+ """Prefix command for requiring features."""
+
+ def __init__ (self):
+ super (RequireCommand, self).__init__ ("require",
+ gdb.COMMAND_SUPPORT,
+ gdb.COMPLETE_NONE,
+ True)
+
+class RequireSubcommand (gdb.Command):
+ """Demand-load a command by name."""
+
+ def __init__ (self, name):
+ self.__doc__ = "Demand-load a %s by name." % name
+ super (RequireSubcommand, self).__init__ ("require %s" % name,
+ gdb.COMMAND_SUPPORT)
+ self.name = name
+
+ def invoke (self, arg, from_tty):
+ for cmd in arg.split():
+ exec ('import gdb.' + self.name + '.' + cmd, globals ())
+
+ def complete (self, text, word):
+ dir = gdb.pythondir + '/gdb/' + self.name
+ result = []
+ for file in os.listdir(dir):
+ if not file.startswith (word) or not file.endswith ('.py'):
+ continue
+ feature = file[0:-3]
+ if feature == 'require' or feature == '__init__':
+ continue
+ result.append (feature)
+ return result
+
+RequireCommand()
+RequireSubcommand("command")
+RequireSubcommand("function")
diff --git a/gdb/python/lib/gdb/command/upto.py b/gdb/python/lib/gdb/command/upto.py
new file mode 100644
index 0000000..faf54ed
--- /dev/null
+++ b/gdb/python/lib/gdb/command/upto.py
@@ -0,0 +1,129 @@
+# upto command.
+
+# Copyright (C) 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
+import re
+from gdb.FrameIterator import FrameIterator
+from gdb.FrameWrapper import FrameWrapper
+
+class UptoPrefix (gdb.Command):
+ def __init__ (self):
+ super (UptoPrefix, self).__init__ ("upto", gdb.COMMAND_STACK,
+ prefix = True)
+
+class UptoImplementation (gdb.Command):
+ def __init__ (self, subcommand):
+ super (UptoImplementation, self).__init__ ("upto " + subcommand,
+ gdb.COMMAND_STACK)
+
+ def search (self):
+ saved = gdb.selected_frame ()
+ iter = FrameIterator (saved)
+ found = False
+ try:
+ for frame in iter:
+ frame.select ()
+ try:
+ if self.filter (frame):
+ wrapper = FrameWrapper (frame)
+ wrapper.describe (sys.stdout, False)
+ return
+ except:
+ pass
+ except:
+ pass
+ saved.select ()
+ raise RuntimeError, 'Could not find a matching frame'
+
+ def invoke (self, arg, from_tty):
+ self.rx = re.compile (arg)
+ self.search ()
+
+class UptoSymbolCommand (UptoImplementation):
+ """Select and print some calling stack frame, based on symbol.
+The argument is a regular expression. This command moves up the
+stack, stopping at the first frame whose symbol matches the regular
+expression."""
+
+ def __init__ (self):
+ super (UptoSymbolCommand, self).__init__ ("symbol")
+
+ def filter (self, frame):
+ name = frame.name ()
+ if name is not None:
+ if self.rx.search (name) is not None:
+ return True
+ return False
+
+class UptoSourceCommand (UptoImplementation):
+ """Select and print some calling stack frame, based on source file.
+The argument is a regular expression. This command moves up the
+stack, stopping at the first frame whose source file name matches the
+regular expression."""
+
+ def __init__ (self):
+ super (UptoSourceCommand, self).__init__ ("source")
+
+ def filter (self, frame):
+ name = frame.find_sal ().symtab.filename
+ if name is not None:
+ if self.rx.search (name) is not None:
+ return True
+ return False
+
+class UptoObjectCommand (UptoImplementation):
+ """Select and print some calling stack frame, based on object file.
+The argument is a regular expression. This command moves up the
+stack, stopping at the first frame whose object file name matches the
+regular expression."""
+
+ def __init__ (self):
+ super (UptoObjectCommand, self).__init__ ("object")
+
+ def filter (self, frame):
+ name = frame.find_sal ().symtab.objfile.filename
+ if name is not None:
+ if self.rx.search (name) is not None:
+ return True
+ return False
+
+class UptoWhereCommand (UptoImplementation):
+ """Select and print some calling stack frame, based on expression.
+The argument is an expression. This command moves up the stack,
+parsing and evaluating the expression in each frame. This stops when
+the expression evaluates to a non-zero (true) value."""
+
+ def __init__ (self):
+ super (UptoWhereCommand, self).__init__ ("where")
+
+ def filter (self, frame):
+ try:
+ if gdb.parse_and_eval (self.expression):
+ return True
+ except:
+ pass
+ return False
+
+ def invoke (self, arg, from_tty):
+ self.expression = arg
+ self.search ()
+
+UptoPrefix ()
+UptoSymbolCommand ()
+UptoSourceCommand ()
+UptoObjectCommand ()
+UptoWhereCommand ()
diff --git a/gdb/python/lib/gdb/function/caller_is.py b/gdb/python/lib/gdb/function/caller_is.py
new file mode 100644
index 0000000..2b9c5c7

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,175 @@
http://sourceware.org/ml/gdb-cvs/2013-05/msg00141.html
### src/gdb/ChangeLog 2013/05/17 06:58:33 1.15565
### src/gdb/ChangeLog 2013/05/17 08:34:18 1.15566
## -1,3 +1,18 @@
+2013-05-17 Phil Muldoon <pmuldoon@redhat.com>
+
+ * frame.c (frame_stash): Convert to htab.
+ (frame_addr_hash): New function.
+ (frame_addr_hash_eq): New function.
+ (frame_stash_create): Convert function to create
+ a hash table.
+ (frame_stash_add): Convert function to add an entry to a hash
+ table.
+ (frame_stash_find): Convert function to search the hash table.
+ (frame_stash_invalidate): Convert function to empty the hash
+ table.
+ (get_frame_id): Only add to stash if a frame_id is created.
+ (_initialize_frame): Call frame_stash_create.
+
2013-05-16 Yue Lu <hacklu.newborn@gmail.com> (tiny change)
* configure.ac: Ensure MIG is available when building for GNU Hurd
--- src/gdb/frame.c 2013/04/10 15:11:11 1.317
+++ src/gdb/frame.c 2013/05/17 08:34:18 1.318
@@ -43,6 +43,7 @@
#include "block.h"
#include "inline-frame.h"
#include "tracepoint.h"
+#include "hashtab.h"
static struct frame_info *get_prev_frame_1 (struct frame_info *this_frame);
static struct frame_info *get_prev_frame_raw (struct frame_info *this_frame);
@@ -128,38 +129,107 @@
enum unwind_stop_reason stop_reason;
};
-/* A frame stash used to speed up frame lookups. */
+/* A frame stash used to speed up frame lookups. Create a hash table
+ to stash frames previously accessed from the frame cache for
+ quicker subsequent retrieval. The hash table is emptied whenever
+ the frame cache is invalidated. */
+
+static htab_t frame_stash;
+
+/* Internal function to calculate a hash from the frame_id addresses,
+ using as many valid addresses as possible. Frames below level 0
+ are not stored in the hash table. */
+
+static hashval_t
+frame_addr_hash (const void *ap)
+{
+ const struct frame_info *frame = ap;
+ const struct frame_id f_id = frame->this_id.value;
+ hashval_t hash = 0;
+
+ gdb_assert (f_id.stack_addr_p || f_id.code_addr_p
+ || f_id.special_addr_p);
+
+ if (f_id.stack_addr_p)
+ hash = iterative_hash (&f_id.stack_addr,
+ sizeof (f_id.stack_addr), hash);
+ if (f_id.code_addr_p)
+ hash = iterative_hash (&f_id.code_addr,
+ sizeof (f_id.code_addr), hash);
+ if (f_id.special_addr_p)
+ hash = iterative_hash (&f_id.special_addr,
+ sizeof (f_id.special_addr), hash);
-/* We currently only stash one frame at a time, as this seems to be
- sufficient for now. */
-static struct frame_info *frame_stash = NULL;
+ return hash;
+}
+
+/* Internal equality function for the hash table. This function
+ defers equality operations to frame_id_eq. */
+
+static int
+frame_addr_hash_eq (const void *a, const void *b)
+{
+ const struct frame_info *f_entry = a;
+ const struct frame_info *f_element = b;
-/* Add the following FRAME to the frame stash. */
+ return frame_id_eq (f_entry->this_id.value,
+ f_element->this_id.value);
+}
+
+/* Internal function to create the frame_stash hash table. 100 seems
+ to be a good compromise to start the hash table at. */
+
+static void
+frame_stash_create (void)
+{
+ frame_stash = htab_create (100,
+ frame_addr_hash,
+ frame_addr_hash_eq,
+ NULL);
+}
+
+/* Internal function to add a frame to the frame_stash hash table. Do
+ not store frames below 0 as they may not have any addresses to
+ calculate a hash. */
static void
frame_stash_add (struct frame_info *frame)
{
- frame_stash = frame;
+ /* Do not stash frames below level 0. */
+ if (frame->level >= 0)
+ {
+ struct frame_info **slot;
+
+ slot = (struct frame_info **) htab_find_slot (frame_stash,
+ frame,
+ INSERT);
+ *slot = frame;
+ }
}
-/* Search the frame stash for an entry with the given frame ID.
- If found, return that frame. Otherwise return NULL. */
+/* Internal function to search the frame stash for an entry with the
+ given frame ID. If found, return that frame. Otherwise return
+ NULL. */
static struct frame_info *
frame_stash_find (struct frame_id id)
{
- if (frame_stash && frame_id_eq (frame_stash->this_id.value, id))
- return frame_stash;
+ struct frame_info dummy;
+ struct frame_info *frame;
- return NULL;
+ dummy.this_id.value = id;
+ frame = htab_find (frame_stash, &dummy);
+ return frame;
}
-/* Invalidate the frame stash by removing all entries in it. */
+/* Internal function to invalidate the frame stash by removing all
+ entries in it. This only occurs when the frame cache is
+ invalidated. */
static void
frame_stash_invalidate (void)
{
- frame_stash = NULL;
+ htab_empty (frame_stash);
}
/* Flag to control debugging. */
@@ -345,10 +415,9 @@
fprint_frame_id (gdb_stdlog, fi->this_id.value);
fprintf_unfiltered (gdb_stdlog, " }\n");
}
+ frame_stash_add (fi);
}
- frame_stash_add (fi);
-
return fi->this_id.value;
}
@@ -2451,6 +2520,8 @@
{
obstack_init (&frame_cache_obstack);
+ frame_stash_create ();
+
observer_attach_target_changed (frame_observer_target_changed);
add_prefix_cmd ("backtrace", class_maintenance, set_backtrace_cmd, _("\

View File

@ -1199,3 +1199,97 @@ http://sourceware.org/ml/gdb-cvs/2013-04/msg00070.html
-($(POD2MAN5) gdbinit.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \
mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1)
rm -f gdbinit.pod
http://sourceware.org/bugzilla/show_bug.cgi?id=15413
http://sourceware.org/ml/gdb-cvs/2013-05/msg00063.html
### src/gdb/ChangeLog 2013/04/26 14:13:13 1.15260.2.50
### src/gdb/ChangeLog 2013/05/07 17:04:56 1.15260.2.51
## -1,3 +1,10 @@
+2013-05-07 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ PR breakpoints/15413:
+ * breakpoint.c (condition_completer): Simplify the code to
+ disconsider multiple locations of breakpoints when completing the
+ "condition" command.
+
2013-04-26 Joel Brobecker <brobecker@adacore.com>
* version.in: Set version to 7.6.0.20130426-cvs.
--- src/gdb/breakpoint.c 2013/04/25 08:15:34 1.745.2.5
+++ src/gdb/breakpoint.c 2013/05/07 17:04:57 1.745.2.6
@@ -1015,27 +1015,14 @@
len = strlen (text);
ALL_BREAKPOINTS (b)
- {
- int single = b->loc->next == NULL;
- struct bp_location *loc;
- int count = 1;
-
- for (loc = b->loc; loc; loc = loc->next)
- {
- char location[50];
-
- if (single)
- xsnprintf (location, sizeof (location), "%d", b->number);
- else
- xsnprintf (location, sizeof (location), "%d.%d", b->number,
- count);
+ {
+ char number[50];
- if (strncmp (location, text, len) == 0)
- VEC_safe_push (char_ptr, result, xstrdup (location));
+ xsnprintf (number, sizeof (number), "%d", b->number);
- ++count;
- }
- }
+ if (strncmp (number, text, len) == 0)
+ VEC_safe_push (char_ptr, result, xstrdup (number));
+ }
return result;
}
### src/gdb/testsuite/ChangeLog 2013/05/03 16:26:32 1.3580.2.20
### src/gdb/testsuite/ChangeLog 2013/05/07 17:04:57 1.3580.2.21
## -1,3 +1,11 @@
+2013-05-07 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ PR breakpoints/15413:
+ * gdb.base/pending.exp: Add test for completion of the "condition"
+ command for pending breakpoints.
+ * gdb.linespec/linespec.ex: Add test for completion of the
+ "condition" command when dealing with multiple locations.
+
2013-05-03 Hafiz Abid Qadeer <abidh@codesourcery.com>
* status-stop.exp (test_tstart_tstart): Check for error
--- src/gdb/testsuite/gdb.base/pending.exp 2013/01/01 06:33:26 1.27
+++ src/gdb/testsuite/gdb.base/pending.exp 2013/05/07 17:04:57 1.27.2.1
@@ -55,6 +55,9 @@
}
}
+# Complete the condition (PR 15413).
+gdb_test "complete condition " "condition 1"
+
gdb_test "info break" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+breakpoint keep y.*PENDING.*pendfunc1.*" \
--- src/gdb/testsuite/gdb.linespec/linespec.exp 2013/01/01 06:41:24 1.6
+++ src/gdb/testsuite/gdb.linespec/linespec.exp 2013/05/07 17:04:57 1.6.2.1
@@ -63,6 +63,10 @@
"Breakpoint $decimal at $hex: dupname:label. \[(\]2 locations\[)\]" \
"multi-location break using duplicate function name and label"
+# Testing if the "condition" command completes only the breakpoints,
+# not the locations.
+gdb_test "complete condition " "condition $decimal\r\ncondition $decimal\r\ncondition $decimal"
+
gdb_test_no_output "set breakpoint pending off" \
"disable pending breakpoints for linespec tests"

View File

@ -36,7 +36,7 @@ Version: 7.6
# 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: 29%{?dist}
Release: 30%{?dist}
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain
Group: Development/Debuggers
@ -266,6 +266,9 @@ Patch231: gdb-6.3-bz202689-exec-from-pthread-test.patch
Patch232: gdb-upstream.patch
Patch828: gdb-upstream-man-gcore-1of2.patch
Patch829: gdb-upstream-man-gcore-2of2.patch
# Backported Python frame filters (Phil Muldoon).
Patch836: gdb-upstream-framefilters-1of2.patch
Patch837: gdb-upstream-framefilters-2of2.patch
# Testcase for PPC Power6/DFP instructions disassembly (BZ 230000).
#=fedoratest+ppc
@ -780,6 +783,8 @@ find -name "*.info*"|xargs rm -f
%patch232 -p1
%patch828 -p1
%patch829 -p1
%patch836 -p1
%patch837 -p1
%patch1 -p1
%patch3 -p1
@ -1397,8 +1402,12 @@ fi
%endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch"
%changelog
* Tue May 21 2013 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.6-30.fc19
- Backported Python frame filters (Phil Muldoon).
- Backported breakpoint conditions crash fix (Sergio Durigan Junior).
* Sun May 19 2013 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.6-29.fc19
- Fix performance regression when inferior opens many libraries (Gary Benson).
- Fix performance regression opening many libraries (Gary Benson, BZ 965106).
* Thu May 9 2013 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.6-28.fc19
- Fix needless expansion of non-gdbindex symtabs (Doug Evans).