This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hello, I've included with this mail a complete patch build agains the current HEAD, and checked that there was no regression in the testsuite Kevin On Mon, May 16, 2011 at 7:23 AM, Kevin Pouget <kevin.pouget@gmail.com> wrote: > Hello, > > I prepared some tests which show the behavior of this new Breakpoint > type in various environment: > - normal termination, forced termination (gdb return) > - longjmp > - c++ exception > - breakpoint condition > > there is two bits which differs from what I expected, in the > breakpoint conditions > > * setting a BP in a DUMMY_FRAME: the `stop' function will be triggerd, > but it's return value (stop or continue/booleans) won't be taken into > account. I'm not sure whether the kind of FinishBreakpoint should be > forbidden or not, because I may want to track ALL the calls to that > function, including GDB inferior calls > > * the "normal_stop" notification if not triggered during condition > evaluation, so the `out_of_scope_notif' flag is not turn off (more > generally, the notification should be disabled when the breakpoint is > hit, and not when GDB stops) > > > otherwise, for c++ exception, the return PC of a frame surrounded by a > try/catch is at the end of the catch, so with > try { fct_1() } catch { ... }, a FinishBreakpoint in fct_1 will be > correcty catch, but it won't work for function nested within fct_1. > > > > Does this testsuite match your expectations, or would you like it to > be more advanced? (I'll need more hints in this case) > > > cordially, > > Kevin > > > diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint-cc.cc > b/gdb/testsuite/gdb.python/py-finish-breakpoint-cc.cc > new file mode 100644 > index 0000000..a0eea06 > --- /dev/null > +++ b/gdb/testsuite/gdb.python/py-finish-breakpoint-cc.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-breakpoint-cc.exp > b/gdb/testsuite/gdb.python/py-finish-breakpoint-cc.exp > new file mode 100644 > index 0000000..e74023d > --- /dev/null > +++ b/gdb/testsuite/gdb.python/py-finish-breakpoint-cc.exp > @@ -0,0 +1,59 @@ > +# 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-breakpoint-cc" > +set srcfile ${testfile}.cc > +set binfile ${objdir}/${subdir}/${testfile} > +set pyfile ?${srcdir}/${subdir}/${testfile}.py > + > +# Start with a fresh gdb. > +gdb_exit > +gdb_start > +gdb_reinitialize_dir $srcdir/$subdir > +gdb_load ${binfile} > + > +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" > executable {debug c++}] != "" } { > + ? ?untested "Couldn't compile ${srcfile}" > + ? ?return -1 > +} > + > +if ![runto_main] then { > + ? ?fail "Cannot run to main." > + ? ?return 0 > +} > + > +gdb_test "source $pyfile" ".*Python script imported.*" \ > + ? ? ? ? "import python scripts" > + > +gdb_test "break [gdb_get_line_number "Break after exception 1."]" > "Breakpoint.* at .*" \ > + ? ? ? ? "set watchdog after the exception 1" > +gdb_test "break [gdb_get_line_number "Break after exception 2."]" > "Breakpoint.* at .*" \ > + ? ? ? ? "set watchdog after the exception 2" > + > +gdb_test "python ExceptionBreakpoint()" "ExceptionBreakpoint init" > "set BP before throwing the exception" > +gdb_test "python print len(gdb.breakpoints())" "4" "check number of BPs" > +gdb_test "continue" ".*stopped at ExceptionFinishBreakpoint.*" "check > FinishBreakpoint in catch()" > +gdb_test "python print len(gdb.breakpoints())" "4" "check finish BP removal" > + > +gdb_test "continue" ".*exception did not finish.*" "FinishBreakpoint > with exception thrown not caught" > diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint-cc.py > b/gdb/testsuite/gdb.python/py-finish-breakpoint-cc.py > new file mode 100644 > index 0000000..d0dfe2f > --- /dev/null > +++ b/gdb/testsuite/gdb.python/py-finish-breakpoint-cc.py > @@ -0,0 +1,43 @@ > +# 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 ExceptionBreakpoint(gdb.Breakpoint): > + ? ?def __init__(self): > + ? ? ? ?gdb.Breakpoint.__init__(self, spec="throw_exception_1", internal=1) > + ? ? ? ?self.silent = True > + ? ? ? ?print "ExceptionBreakpoint init" > + > + ? ?def stop(self): > + ? ? ? ?ExceptionFinishBreakpoint(gdb.newest_frame()) > + ? ? ? ?return False > + > +class ExceptionFinishBreakpoint(gdb.FinishBreakpoint): > + ? ?def __init__(self, frame): > + ? ? ? ?gdb.FinishBreakpoint.__init__(self, frame, internal=1) > + ? ? ? ?self.silent = True; > + > + ? ?def stop(self): > + ? ? ? print "stopped at ExceptionFinishBreakpoint" > + ? ? ? gdb.post_event(self.delete) > + ? ? ? ?return True > + > + ? ?def out_of_scope(self): > + ? ? ? ?print "exception did not finish ..." > + > + > +print "Python script imported" > 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..32b8b38 > --- /dev/null > +++ b/gdb/testsuite/gdb.python/py-finish-breakpoint.c > @@ -0,0 +1,82 @@ > +/* 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> > + > +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); > +} > + > + > +int main (int argc, char *argv[]) > +{ > + ?jmp_buf env; > + ?int foo = 5; > + ?int bar = 42; > + ?int i, j; > + > + ?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. */ > + > + ?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..65eebc9 > --- /dev/null > +++ b/gdb/testsuite/gdb.python/py-finish-breakpoint.exp > @@ -0,0 +1,183 @@ > +# 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-breakpoint" > +set srcfile ${testfile}.c > + > +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { > + ? ?return -1 > +} > + > +set remote_python_file [remote_download host > ${srcdir}/${subdir}/${testfile}.py] > + > + > +# Skip all tests if Python scripting is not enabled. > +if { [skip_python_tests] } { continue } > + > +# > +# Test FinishBreakpoint in function returned by longjmp > +# > + > +clean_restart ${testfile} > + > +if ![runto call_longjmp_1] then { > + ? ?perror "couldn't run to breakpoint call_longjmp" > + ? ?continue > +} > + > +gdb_test "source $remote_python_file" ".*Python script imported.*" \ > + ? ? ? ? "import python scripts" > + > +gdb_test "python ljmpBP = LongjmpFinishBreakpoint(gdb.newest_frame())" \ > + ? ? ? ? "LongjmpFinishBreakpoint init" \ > + ? ? ? ? "set finish breakpoint" > +gdb_test "break [gdb_get_line_number "after longjmp."]" "Breakpoint.* at .*" \ > + ? ? ? ? "set BP after the jump" > +gdb_test "continue" ".*Longjmp didn't finish.*" "check FinishBP out > of scope notification" > + > +# > +# Test FinishBreakpoint in BP condition evaluation > +# (finish in dummy frame) > +# > + > +clean_restart ${testfile} > + > +set cond_line [gdb_get_line_number "Condition Break."] > +if ![runto_main] then { > + ? ?fail "Cannot run to main." > + ? ?return 0 > +} > + > +gdb_test "source $remote_python_file" ".*Python script imported.*" \ > + ? ? ? ? "import python scripts" > + > +gdb_test "break ${cond_line} if test_1(i,8)" ".*Breakpoint .* at .*" > "set conditional BP" > +gdb_test "python TestBreakpoint()" "TestBreakpoint init" "set BP in condition" > + > + > +set msg "check FinishBreakpoint don't stop in GDB Dummy Frame" > +gdb_test_multiple "continue" $msg { > + ? ? ? -re ".*test don't stop 2.*test stop.*test don't stop 4.*" { > + ? ? ? ? ? ? ? pass $msg > + ? ? ? } > + ? ? ? -re ".*test don't stop 2.*test stop.*$gdb_prompt" { > + ? ? ? ? ? ? ? fail $msg > + ? ? ? } > +} > + > +gdb_test "print i" "8" "check stopped location" > + > +# > +# Test FinishBreakpoint in BP condition evaluation > +# (finish in normal frame) > +# > + > +clean_restart ${testfile} > + > +gdb_test "source $remote_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" > + > +setup_kfail "normal_stop_notification not triggered during condition > evaluation" *-*-* > +gdb_test "python print gdb.breakpoints()\[2\].out_of_scope_notif" > ".*False.*" "check out_of_scope notification disabled" > +gdb_test_no_output "python gdb.breakpoints()\[2\].out_of_scope_notif > = False" "reestablish correct value" > + > +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 normal conditions > +# > + > +clean_restart ${testfile} > + > +if ![runto_main] then { > + ? ?fail "Cannot run to main." > + ? ?return 0 > +} > +gdb_test_no_output "set confirm off" "disable confirmation" > +gdb_test "source $remote_python_file" ".*Python script imported.*" \ > + ? ? ? ? "import python scripts" > +gdb_test "python MyBreakpoint(\"increase_1\")" ".*Breakpoint 2.*" \ > + ? ? ? ? "create Python function breakpoint" > +gdb_test "continue" ".*Arrived at MyBreakpoint with 0.*" "check > MyBreakpoint hit" > + > +# set FinishBreakpoint > + > +gdb_test "python finishbp = MyFinishBreakpoint (gdb.parse_and_eval > (\"a\"), gdb.selected_frame ())" \ > + ? ? ? ? ".*Breakpoint 3.*" "set FinishBreakpoint" > +gdb_test "python print finishbp.out_of_scope_notif" ".*True.*" \ > + ? ? ? ? "check out_of_scope_notif at init" > +gdb_test "python print finishbp.return_value" ".*None.*" \ > + ? ? ? ? "check return_value at init" > + > +# check normal bp hit > + > +gdb_test "continue" ".*MyFinishBreakpoint stop with.*#0.*increase.*" \ > + ? ? ? ? "check MyFinishBreakpoint hit" > +gdb_test "python print finishbp.return_value" ".*-5.*" "check return_value" > +gdb_test "python print finishbp.out_of_scope_notif" ".*False.*" \ > + ? ? ? ? "check out_of_scope_notif disabled after hit" > +gdb_test "finish" ".*main.*" "return to main()" > +gdb_test "python print finishbp.return_value" ".*None.*" "check return_value" > + > +# check forced return / check out of scpop > +gdb_test_no_output "python finishbp.out_of_scope_notif = True" \ > + ? ? ? ? "re-enable out_of_scope_notif" > + > +gdb_test "continue" ".*Arrived at MyBreakpoint with.*" "check > MyBreakpoint second hit" > +gdb_test "up" ".*increase_1.*" "go one frame up" > +gdb_test_no_output "return" "return from the frame" > +gdb_test "python print finishbp.check_scope()" ".*MyFinishBreakpoint > out of scope.*True.*" \ > + ? ? ? ? "go one frame up" > + > +# check forced return / automatic notification > + > +gdb_test_no_output "python finishbp.out_of_scope_notif = True" \ > + ? ? ? ? "re-enable out_of_scope_notif" > + > +gdb_test "continue" ".*Arrived at MyBreakpoint with.*" "check > MyBreakpoint third hit" > +gdb_test "up" ".*increase_1.*" "go one frame up" > +gdb_test_no_output "return" "return from the frame" > +gdb_test "next" ".*MyFinishBreakpoint out of scope.*" "check Finish > breakpoint discard" > +gdb_test "python print finishbp.out_of_scope_notif" ".*False.*" > "check out_of_scope_notif" > + > +# check FinishBreakpoint in main > + > +gdb_test "python MyFinishBreakpoint (None, gdb.selected_frame ())" \ > + ? ? ? ? ".*ValueError: \"FinishBreakpoint\" not meaningful in the > outermost frame..*" \ > + ? ? ? ? "check FinishBP not allowed in main" > + > + > 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..f014cc6 > --- /dev/null > +++ b/gdb/testsuite/gdb.python/py-finish-breakpoint.py > @@ -0,0 +1,85 @@ > +# 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 MyBreakpoint(gdb.Breakpoint): > + ? ? ? def stop(self): > + ? ? ? ? ? ? ? val = gdb.parse_and_eval ("a") > + ? ? ? ? ? ? ? print "Arrived at MyBreakpoint with %d" % int(val.dereference()) > + ? ? ? ? ? ? ? return True > + > +class MyFinishBreakpoint(gdb.FinishBreakpoint): > + ? ? ? def __init__(self, val, frame): > + ? ? ? ? ? ? ? super (MyFinishBreakpoint, self).__init__ (frame) > + ? ? ? ? ? ? ? print "MyFinishBreakpoint init" > + ? ? ? ? ? ? ? self.val = val > + > + ? ? ? def stop(self): > + ? ? ? ? ? ? ? print "MyFinishBreakpoint stop with %d" % int(self.val.dereference()) > + ? ? ? ? ? ? ? gdb.execute("where 1") > + ? ? ? ? ? ? ? return True > + > + ? ? ? def out_of_scope(self): > + ? ? ? ? ? ? ? print "MyFinishBreakpoint out of scope..." > + > +test_finish_bp = None > +class TestBreakpoint(gdb.Breakpoint): > + ? ?def __init__(self): > + ? ? ? ?gdb.Breakpoint.__init__(self, spec="test_1", internal=1) > + ? ? ? ?self.silent = True > + ? ? ? ?self.finish = None > + ? ? ? ?print "TestBreakpoint init" > + > + ? ?def stop(self): > + ? ? ? global test_finish_bp > + ? ? ? ?if (self.finish == None): > + ? ? ? ? ? ?self.finish = TestFinishBreakpoint(gdb.newest_frame()) > + ? ? ? ? ? ?test_finish_bp = self.finish > + ? ? ? ?return False > + > + > +class TestFinishBreakpoint(gdb.FinishBreakpoint): > + ? ?def __init__(self, frame): > + ? ? ? ?gdb.FinishBreakpoint.__init__(self, frame, internal=1) > + ? ? ? ?self.count = 0 > + > + ? ?def stop(self): > + ? ? ? ?self.count += 1 > + ? ? ? ?if (self.count == 3): > + ? ? ? ? ? ?print "test stop ..." > + ? ? ? ? ? ?return True > + ? ? ? ?else: > + ? ? ? ? ? ?print "test don't stop %d" % self.count > + ? ? ? ? ? ?return False > + > + > + ? ?def out_of_scope(self): > + ? ? ? ?print "test didn't finish ..." > + > +class LongjmpFinishBreakpoint(gdb.FinishBreakpoint): > + ? ? ? def __init__(self, frame): > + ? ? ? ? ? ? ? gdb.FinishBreakpoint.__init__(self, frame, internal=1) > + ? ? ? ? ? ? ? print "LongjmpFinishBreakpoint init" > + > + ? ? ? def stop(self): > + ? ? ? ? ? ? ? print "Stopped at LongjmpFinishBreakpoint" > + > + > + ? ? ? def out_of_scope(self): > + ? ? ? ? ? ? ? print "Longjmp didn't finish ..." > + > +print "Python script imported" > -- > 1.7.4.4 >
Attachment:
0001-Python-Finish-Breakpoints.txt
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |