aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
diff options
context:
space:
mode:
authorKevin Pouget <kpouget@sourceware.org>2011-12-23 17:06:16 +0000
committerKevin Pouget <kpouget@sourceware.org>2011-12-23 17:06:16 +0000
commitcc72b2a2da6d6372cbdb1d14639a5fce84e1a325 (patch)
tree5fd4fd97f8ba3702213bfc77d8be5d0a68fe86a3 /gdb/testsuite
parent6538471c25155c4230f325e022a091d782a81fad (diff)
downloadgdb-cc72b2a2da6d6372cbdb1d14639a5fce84e1a325.zip
gdb-cc72b2a2da6d6372cbdb1d14639a5fce84e1a325.tar.gz
gdb-cc72b2a2da6d6372cbdb1d14639a5fce84e1a325.tar.bz2
Introduce gdb.FinishBreakpoint in Python
* Makefile.in (SUBDIR_PYTHON_OBS): Add py-finishbreakpoint.o. (SUBDIR_PYTHON_SRCS): Add python/py-finishbreakpoint.c. Add build rule for this file. * infcmd.c (print_return_value): Split to create get_return_value. (get_return_value): New function based on print_return_value. Handle case where stop_registers are not set. * inferior.h (get_return_value): New prototype. * python/py-breakpoint.c (bppy_pending_object): Make non-static. (gdbpy_breakpoint_created): Set is_py_finish_bp is necessary. (struct breakpoint_object): Move to python-internal.h (BPPY_REQUIRE_VALID): Likewise. (BPPY_SET_REQUIRE_VALID): Likewise. (gdbpy_breakpoint_created): Initialize is_finish_bp. (gdbpy_should_stop): Add pre/post hooks before/after calling stop method. * python/python-internal.h (breakpoint_object_type): Add as extern. (bppy_pending_object): Likewise. (typedef struct breakpoint_object) Removed. (struct breakpoint_object): Moved from py-breakpoint.c. Add field is_finish_bp. (BPPY_REQUIRE_VALID): Moved from py-breakpoint.c. (BPPY_SET_REQUIRE_VALID): Likewise. (frame_object_to_frame_info): New prototype. (gdbpy_initialize_finishbreakpoints): New prototype. (bpfinishpy_is_finish_bp): Likewise. (bpfinishpy_pre_stop_hook): Likewise. (bpfinishpy_post_stop_hook): Likewise. * python/py-finishbreakpoint.c: New file. * python/py-frame.c(frame_object_to_frame_info): Make non-static and accept PyObject instead of frame_object. (frapy_is_valid): Don't cast to frame_object. (frapy_name): Likewise. (frapy_type): Likewise. (frapy_unwind_stop_reason): Likewise. (frapy_pc): Likewise. (frapy_block): Likewise. (frapy_function): Likewise. (frapy_older): Likewise. (frapy_newer): Likewise. (frapy_find_sal): Likewise. (frapy_read_var): Likewise. (frapy_select): Likewise. * python/python.c (gdbpy_is_stopped_at_finish_bp): New noop function. (_initialize_python): Add gdbpy_initialize_finishbreakpoints. * python/python.h: Include breakpoint.h (gdbpy_is_stopped_at_finish_bp): New prototype. doc/ * gdb.texinfo (Finish Breakpoints in Python): New subsection. (Python API): Add menu entry for Finish Breakpoints. testsuite/ * Makefile.in (EXECUTABLES): Add py-finish-breakpoint and py-finish-breakpoint2 (MISCALLANEOUS): Add py-events-shlib.so and py-events-shlib-nodebug.so * gdb.python/py-breakpoint.exp (mult_line): Define and use variable instead of line number. * gdb.python/py-finish-breakpoint.c: New file. * gdb.python/py-finish-breakpoint.exp: New file. * gdb.python/py-finish-breakpoint.py: New file. * gdb.python/py-finish-breakpoint2.cc: New file. * gdb.python/py-finish-breakpoint2.exp: New file. * gdb.python/py-finish-breakpoint2.py: New file.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r--gdb/testsuite/ChangeLog15
-rw-r--r--gdb/testsuite/gdb.python/Makefile.in5
-rw-r--r--gdb/testsuite/gdb.python/py-breakpoint.exp7
-rw-r--r--gdb/testsuite/gdb.python/py-finish-breakpoint.c100
-rw-r--r--gdb/testsuite/gdb.python/py-finish-breakpoint.exp265
-rw-r--r--gdb/testsuite/gdb.python/py-finish-breakpoint.py89
-rw-r--r--gdb/testsuite/gdb.python/py-finish-breakpoint2.cc59
-rw-r--r--gdb/testsuite/gdb.python/py-finish-breakpoint2.exp65
-rw-r--r--gdb/testsuite/gdb.python/py-finish-breakpoint2.py33
9 files changed, 634 insertions, 4 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index d00dcb8..4964e4e 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,18 @@
+2011-12-23 Kevin Pouget <kevin.pouget@st.com>
+
+ Introduce gdb.FinishBreakpoint in Python.
+ * Makefile.in (EXECUTABLES): Add py-finish-breakpoint and
+ py-finish-breakpoint2
+ (MISCALLANEOUS): Add py-events-shlib.so and py-events-shlib-nodebug.so
+ * gdb.python/py-breakpoint.exp (mult_line): Define and use variable
+ instead of line number.
+ * gdb.python/py-finish-breakpoint.c: New file.
+ * gdb.python/py-finish-breakpoint.exp: New file.
+ * gdb.python/py-finish-breakpoint.py: New file.
+ * gdb.python/py-finish-breakpoint2.cc: New file.
+ * gdb.python/py-finish-breakpoint2.exp: New file.
+ * gdb.python/py-finish-breakpoint2.py: New file.
+
2011-12-23 Jan Kratochvil <jan.kratochvil@redhat.com>
Partial fix of compatibility with gcc-4.7.
diff --git a/gdb/testsuite/gdb.python/Makefile.in b/gdb/testsuite/gdb.python/Makefile.in
index 9c98db9..5890191 100644
--- a/gdb/testsuite/gdb.python/Makefile.in
+++ b/gdb/testsuite/gdb.python/Makefile.in
@@ -4,9 +4,10 @@ srcdir = @srcdir@
EXECUTABLES = py-type py-value py-prettyprint py-template py-block \
py-symbol py-mi py-breakpoint py-inferior py-infthread \
py-shared python lib-types py-events py-evthreads py-frame \
- py-mi py-pp-maint py-progspace py-section-script py-objfile
+ py-mi py-pp-maint py-progspace py-section-script py-objfile \
+ py-finish-breakpoint py-finish-breakpoint2
-MISCELLANEOUS = py-shared-sl.sl
+MISCELLANEOUS = py-shared-sl.sl py-events-shlib.so py-events-shlib-nodebug.so
all info install-info dvi install uninstall installcheck check:
@echo "Nothing to be done for $@..."
diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp
index e0dd087..0e3adbd 100644
--- a/gdb/testsuite/gdb.python/py-breakpoint.exp
+++ b/gdb/testsuite/gdb.python/py-breakpoint.exp
@@ -44,7 +44,8 @@ gdb_py_test_silent_cmd "python blist = gdb.breakpoints()" "Get Breakpoint List"
gdb_test "python print blist\[0\]" "<gdb.Breakpoint object at $hex>" "Check obj exists"
gdb_test "python print blist\[0\].location" "main." "Check breakpoint location"
-gdb_breakpoint [gdb_get_line_number "Break at multiply."]
+set mult_line [gdb_get_line_number "Break at multiply."]
+gdb_breakpoint ${mult_line}
gdb_continue_to_breakpoint "Break at multiply."
# Check that the Python breakpoint code noted the addition of a
@@ -54,7 +55,9 @@ gdb_test "python print len(blist)" "2" "Check for two breakpoints"
gdb_test "python print blist\[0\]" "<gdb.Breakpoint object at $hex>" "Check obj exists"
gdb_test "python print blist\[0\].location" "main." "Check breakpoint location"
gdb_test "python print blist\[1\]" "<gdb.Breakpoint object at $hex>" "Check obj exists"
-gdb_test "python print blist\[1\].location" "py-breakpoint\.c:41*" "Check breakpoint location"
+
+gdb_test "python print blist\[1\].location" "py-breakpoint\.c:${mult_line}*" \
+ "Check breakpoint location"
# Check hit and ignore counts.
gdb_test "python print blist\[1\].hit_count" "1" "Check breakpoint hit count"
diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint.c b/gdb/testsuite/gdb.python/py-finish-breakpoint.c
new file mode 100644
index 0000000..cf2e06c
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-finish-breakpoint.c
@@ -0,0 +1,100 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 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/>.
+*/
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Defined in py-events-shlib.h. */
+extern void do_nothing (void);
+
+int increase_1 (int *a)
+{
+ *a += 1;
+ return -5;
+}
+
+void increase (int *a)
+{
+ increase_1 (a);
+}
+
+int
+test_1 (int i, int j)
+{
+ return i == j;
+}
+
+int
+test (int i, int j)
+{
+ return test_1 (i, j);
+}
+
+int
+call_longjmp_1 (jmp_buf *buf)
+{
+ longjmp (*buf, 1);
+}
+
+int
+call_longjmp (jmp_buf *buf)
+{
+ call_longjmp_1 (buf);
+}
+
+void
+test_exec_exit (int do_exit)
+{
+ if (do_exit)
+ exit (0);
+ else
+ execl ("/bin/echo", "echo", "-1", (char *)0);
+}
+
+int main (int argc, char *argv[])
+{
+ jmp_buf env;
+ int foo = 5;
+ int bar = 42;
+ int i, j;
+
+ do_nothing ();
+
+ i = 0;
+ /* Break at increase. */
+ increase (&i);
+ increase (&i);
+ increase (&i);
+
+ for (i = 0; i < 10; i++)
+ {
+ j += 1; /* Condition Break. */
+ }
+
+ if (setjmp (env) == 0) /* longjmp caught */
+ {
+ call_longjmp (&env);
+ }
+ else
+ j += 1; /* after longjmp. */
+
+ test_exec_exit (1);
+
+ return j; /* Break at end. */
+}
diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint.exp b/gdb/testsuite/gdb.python/py-finish-breakpoint.exp
new file mode 100644
index 0000000..c7a42a2
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-finish-breakpoint.exp
@@ -0,0 +1,265 @@
+# Copyright (C) 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/>.
+
+# This file is part of the GDB testsuite. It tests the mechanism
+# exposing values to Python.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if {[skip_shlib_tests]} {
+ untested py-finish-breakpoint.exp
+ return 0
+}
+
+load_lib gdb-python.exp
+
+set libfile "py-events-shlib"
+set libsrc $srcdir/$subdir/$libfile.c
+set lib_sl $objdir/$subdir/$libfile-nodebug.so
+set lib_opts ""
+
+set testfile "py-finish-breakpoint"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set exec_opts [list debug shlib=$lib_sl]
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if { [gdb_compile_shlib $libsrc $lib_sl $lib_opts] != ""
+ || [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != ""} {
+ untested "Could not compile either $libsrc or $srcdir/$subdir/$srcfile."
+ return -1
+}
+
+# Start with a fresh gdb.
+clean_restart ${testfile}
+
+set python_file ${srcdir}/${subdir}/${testfile}.py
+
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+#
+# Test FinishBreakpoint in normal conditions
+#
+
+clean_restart ${testfile}
+gdb_load_shlibs ${lib_sl}
+
+if ![runto_main] then {
+ fail "Cannot run to main."
+ return 0
+}
+
+gdb_test_no_output "set confirm off" "disable confirmation"
+gdb_test "source $python_file" "Python script imported.*" \
+ "import python scripts"
+gdb_breakpoint "increase_1"
+gdb_test "continue" "Breakpoint .*at.*" "continue to the function to finish"
+
+# set FinishBreakpoint
+
+gdb_test "python finishbp_default = gdb.FinishBreakpoint ()" \
+ "Temporary breakpoint.*" "set FinishBreakpoint with default frame value"
+gdb_test "python finishbp = MyFinishBreakpoint (gdb.parse_and_eval ('a'), gdb.newest_frame ())" \
+ "Temporary breakpoint.*" "set FinishBreakpoint"
+gdb_test "python print finishbp.return_value" "None.*" \
+ "check return_value at init"
+
+# check normal bp hit
+
+gdb_test "continue" "MyFinishBreakpoint stop with.*return_value is: -5.*#0.*increase.*" \
+ "check MyFinishBreakpoint hit"
+gdb_test "python print finishbp.return_value" "-5.*" "check return_value"
+
+gdb_test "python print finishbp_default.hit_count" "1.*" "check finishBP on default frame has been hit"
+gdb_test "python print finishbp.is_valid()" "False.*"\
+ "ensure that finish bp is invalid afer normal hit"
+
+# check FinishBreakpoint in main no allowed
+
+gdb_test "finish" "main.*" "return to main()"
+gdb_test "python MyFinishBreakpoint (None, gdb.selected_frame ())" \
+ "ValueError: \"FinishBreakpoint\" not meaningful in the outermost frame..*" \
+ "check FinishBP not allowed in main"
+
+#
+# Test FinishBreakpoint with no debug symbol
+#
+
+clean_restart ${testfile}
+gdb_load_shlibs ${lib_sl}
+
+gdb_test "source $python_file" "Python script imported.*" \
+ "import python scripts"
+set cond_line [gdb_get_line_number "Condition Break."]
+
+if ![runto_main] then {
+ fail "Cannot run to main."
+ return 0
+}
+
+gdb_test "print do_nothing" "no debug info.*" "ensure that shared lib has no debug info"
+gdb_breakpoint "do_nothing" {temporary}
+gdb_test "continue" "Temporary breakpoint .*in do_nothing.*" "continue to do_nothing"
+
+gdb_test "python finishBP = SimpleFinishBreakpoint(gdb.newest_frame())" \
+ "SimpleFinishBreakpoint init" \
+ "set finish breakpoint"
+gdb_test "continue" "SimpleFinishBreakpoint stop.*" "check FinishBreakpoint hit"
+gdb_test "python print finishBP.return_value" "None" "check return value without debug symbol"
+
+#
+# Test FinishBreakpoint in function returned by longjmp
+#
+
+clean_restart ${testfile}
+gdb_load_shlibs ${lib_sl}
+
+gdb_test "source $python_file" "Python script imported.*" \
+ "import python scripts"
+
+if ![runto call_longjmp_1] then {
+ perror "couldn't run to breakpoint call_longjmp"
+ continue
+}
+
+gdb_test "python finishbp = SimpleFinishBreakpoint(gdb.newest_frame())" \
+ "SimpleFinishBreakpoint init" \
+ "set finish breakpoint"
+gdb_test "break [gdb_get_line_number "after longjmp."]" "Breakpoint.* at .*" \
+ "set BP after the jump"
+gdb_test "continue" "SimpleFinishBreakpoint out of scope.*" \
+ "check FinishBP out of scope notification"
+gdb_test "python print finishbp.is_valid()" "False.*"\
+ "ensure that finish bp is invalid afer out of scope notification"
+
+#
+# Test FinishBreakpoint in BP condition evaluation
+# (finish in dummy frame)
+#
+
+clean_restart ${testfile}
+gdb_load_shlibs ${lib_sl}
+
+gdb_test "source $python_file" "Python script imported.*" \
+ "import python scripts"
+
+
+if ![runto_main] then {
+ fail "Cannot run to main."
+ return 0
+}
+
+gdb_test "break ${cond_line} if test_1(i,8)" "Breakpoint .* at .*" \
+ "set a conditional BP"
+gdb_test "python TestBreakpoint()" "TestBreakpoint init" \
+ "set FinishBP in a breakpoint condition"
+gdb_test "continue" \
+ "\"FinishBreakpoint\" cannot be set on a dummy frame.*" \
+ "don't allow FinishBreakpoint on dummy frames"
+gdb_test "print i" "8" "check stopped location"
+
+#
+# Test FinishBreakpoint in BP condition evaluation
+# (finish in normal frame)
+#
+
+clean_restart ${testfile}
+gdb_load_shlibs ${lib_sl}
+
+gdb_test "source $python_file" "Python script imported.*" \
+ "import python scripts"
+
+if ![runto_main] then {
+ fail "Cannot run to main."
+ return 0
+}
+
+gdb_test "break ${cond_line} if test(i,8)" \
+ "Breakpoint .* at .*" "set conditional BP"
+gdb_test "python TestBreakpoint()" "TestBreakpoint init" "set BP in condition"
+
+gdb_test "continue" \
+ "test don't stop: 1.*test don't stop: 2.*test stop.*Error in testing breakpoint condition.*The program being debugged stopped while in a function called from GDB.*" \
+ "stop in condition function"
+
+gdb_test "continue" "Continuing.*" "finish condition evaluation"
+gdb_test "continue" "Breakpoint.*" "stop at conditional breakpoint"
+gdb_test "print i" "8" "check stopped location"
+
+#
+# Test FinishBreakpoint in explicit inferior function call
+#
+
+clean_restart ${testfile}
+gdb_load_shlibs ${lib_sl}
+
+gdb_test "source $python_file" "Python script imported.*" \
+ "import python scripts"
+
+if ![runto_main] then {
+ fail "Cannot run to main."
+ return 0
+}
+
+# return address in dummy frame
+
+gdb_test "python TestExplicitBreakpoint('increase_1')" "Breakpoint.*at.*" \
+ "prepare TestExplicitBreakpoint"
+gdb_test "print increase_1(&i)" \
+ "\"FinishBreakpoint\" cannot be set on a dummy frame.*" \
+ "don't allow FinishBreakpoint on dummy frames"
+
+# return address in normal frame
+
+delete_breakpoints
+gdb_test "python TestExplicitBreakpoint(\"increase_1\")" "Breakpoint.*at.*" \
+ "prepare TestExplicitBreakpoint"
+gdb_test "print increase(&i)" \
+ "SimpleFinishBreakpoint init.*SimpleFinishBreakpoint stop.*The program being debugged stopped while in a function called from GDB.*" \
+ "FinishBP stop at during explicit function call"
+
+
+#
+# Test FinishBreakpoint when inferior exits
+#
+
+if ![runto "test_exec_exit"] then {
+ fail "Cannot run to test_exec_exit."
+ return 0
+}
+
+gdb_test "python SimpleFinishBreakpoint(gdb.newest_frame())" "SimpleFinishBreakpoint init" "set FinishBP after the exit()"
+gdb_test "continue" "SimpleFinishBreakpoint out of scope.*" "catch out of scope after exit"
+
+#
+# Test FinishBreakpoint when inferior execs
+#
+
+if ![runto "test_exec_exit"] then {
+ fail "Cannot run to test_exec_exit."
+ return 0
+}
+
+gdb_test_no_output "set var do_exit = 0" "switch to execve() test"
+gdb_test "python SimpleFinishBreakpoint(gdb.newest_frame())" "SimpleFinishBreakpoint init" "set FinishBP after the exec"
+gdb_test "catch exec" "Catchpoint.*\(exec\).*" "catch exec"
+gdb_test "continue" "SimpleFinishBreakpoint out of scope.*" "catch out of scope after exec" \ No newline at end of file
diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint.py b/gdb/testsuite/gdb.python/py-finish-breakpoint.py
new file mode 100644
index 0000000..dea2a73
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-finish-breakpoint.py
@@ -0,0 +1,89 @@
+# Copyright (C) 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/>.
+
+# This file is part of the GDB testsuite. It tests python Finish
+# Breakpoints.
+
+class MyFinishBreakpoint (gdb.FinishBreakpoint):
+ def __init__(self, val, frame):
+ gdb.FinishBreakpoint.__init__ (self, frame)
+ print "MyFinishBreakpoint init"
+ self.val = val
+
+ def stop(self):
+ print "MyFinishBreakpoint stop with %d" % int (self.val.dereference ())
+ print "return_value is: %d" % int (self.return_value)
+ gdb.execute ("where 1")
+ return True
+
+ def out_of_scope(self):
+ print "MyFinishBreakpoint out of scope"
+
+class TestBreakpoint(gdb.Breakpoint):
+ def __init__(self):
+ gdb.Breakpoint.__init__ (self, spec="test_1", internal=1)
+ self.silent = True
+ self.count = 0
+ print "TestBreakpoint init"
+
+ def stop(self):
+ self.count += 1
+ try:
+ TestFinishBreakpoint (gdb.newest_frame (), self.count)
+ except ValueError as e:
+ print e
+ return False
+
+class TestFinishBreakpoint (gdb.FinishBreakpoint):
+ def __init__ (self, frame, count):
+ self.count = count
+ gdb.FinishBreakpoint.__init__ (self, frame, internal=1)
+
+
+ def stop(self):
+ print "-->", self.number
+ if (self.count == 3):
+ print "test stop: %d" % self.count
+ return True
+ else:
+ print "test don't stop: %d" % self.count
+ return False
+
+
+ def out_of_scope(self):
+ print "test didn't finish: %d" % self.count
+
+class TestExplicitBreakpoint(gdb.Breakpoint):
+ def stop(self):
+ try:
+ SimpleFinishBreakpoint (gdb.newest_frame ())
+ except ValueError as e:
+ print e
+ return False
+
+class SimpleFinishBreakpoint(gdb.FinishBreakpoint):
+ def __init__(self, frame):
+ gdb.FinishBreakpoint.__init__ (self, frame)
+
+ print "SimpleFinishBreakpoint init"
+
+ def stop(self):
+ print "SimpleFinishBreakpoint stop"
+ return True
+
+ def out_of_scope(self):
+ print "SimpleFinishBreakpoint out of scope"
+
+print "Python script importedd"
diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint2.cc b/gdb/testsuite/gdb.python/py-finish-breakpoint2.cc
new file mode 100644
index 0000000..a0eea06
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-finish-breakpoint2.cc
@@ -0,0 +1,59 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 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/>.
+*/
+
+
+#include <iostream>
+
+void
+throw_exception_1 (int e)
+{
+ throw new int (e);
+}
+
+void
+throw_exception (int e)
+{
+ throw_exception_1 (e);
+}
+
+int
+main (void)
+{
+ int i;
+ try
+ {
+ throw_exception_1 (10);
+ }
+ catch (const int *e)
+ {
+ std::cerr << "Exception #" << *e << std::endl;
+ }
+ i += 1; /* Break after exception 1. */
+
+ try
+ {
+ throw_exception (10);
+ }
+ catch (const int *e)
+ {
+ std::cerr << "Exception #" << *e << std::endl;
+ }
+ i += 1; /* Break after exception 2. */
+
+ return i;
+}
diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp b/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp
new file mode 100644
index 0000000..433d1e6
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp
@@ -0,0 +1,65 @@
+# Copyright (C) 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/>.
+
+# This file is part of the GDB testsuite. It tests the mechanism
+# exposing values to Python.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+load_lib gdb-python.exp
+
+set testfile "py-finish-breakpoint2"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+set pyfile ${srcdir}/${subdir}/${testfile}.py
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ untested "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ fail "Cannot run to main."
+ return 0
+}
+
+#
+# Check FinishBreakpoints against C++ exceptions
+#
+
+gdb_breakpoint [gdb_get_line_number "Break after exception 2"]
+
+gdb_test "source $pyfile" ".*Python script imported.*" \
+ "import python scripts"
+
+gdb_breakpoint "throw_exception_1"
+gdb_test "continue" "Breakpoint .*throw_exception_1.*" "run to exception 1"
+
+gdb_test "python print len(gdb.breakpoints())" "3" "check BP count"
+gdb_test "python ExceptionFinishBreakpoint(gdb.newest_frame())" "init ExceptionFinishBreakpoint" "set FinishBP after the exception"
+gdb_test "continue" ".*stopped at ExceptionFinishBreakpoint.*" "check FinishBreakpoint in catch()"
+gdb_test "python print len(gdb.breakpoints())" "3" "check finish BP removal"
+
+gdb_test "continue" ".*Breakpoint.* throw_exception_1.*" "continue to second exception"
+gdb_test "python ExceptionFinishBreakpoint(gdb.newest_frame())" "init ExceptionFinishBreakpoint" "set FinishBP after the exception"
+gdb_test "continue" ".*exception did not finish.*" "FinishBreakpoint with exception thrown not caught"
diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint2.py b/gdb/testsuite/gdb.python/py-finish-breakpoint2.py
new file mode 100644
index 0000000..0fb6955
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-finish-breakpoint2.py
@@ -0,0 +1,33 @@
+# Copyright (C) 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/>.
+
+# This file is part of the GDB testsuite. It tests python Finish
+# Breakpoints.
+
+class ExceptionFinishBreakpoint(gdb.FinishBreakpoint):
+ def __init__(self, frame):
+ gdb.FinishBreakpoint.__init__ (self, frame, internal=1)
+ self.silent = True;
+ print "init ExceptionFinishBreakpoint"
+
+ def stop(self):
+ print "stopped at ExceptionFinishBreakpoint"
+ return True
+
+ def out_of_scope(self):
+ print "exception did not finish ..."
+
+
+print "Python script imported"