aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.python/py-finish-breakpoint.exp
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/gdb.python/py-finish-breakpoint.exp
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/gdb.python/py-finish-breakpoint.exp')
-rw-r--r--gdb/testsuite/gdb.python/py-finish-breakpoint.exp265
1 files changed, 265 insertions, 0 deletions
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