From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 667 invoked by alias); 29 Mar 2009 04:21:56 -0000 Received: (qmail 658 invoked by uid 22791); 29 Mar 2009 04:21:54 -0000 X-SWARE-Spam-Status: No, hits=-1.3 required=5.0 tests=AWL,BAYES_00,HK_OBFDOM,J_CHICKENPOX_31,SARE_MSGID_LONG40,SPF_PASS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.45.13) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 29 Mar 2009 04:21:46 +0000 Received: from zps77.corp.google.com (zps77.corp.google.com [172.25.146.77]) by smtp-out.google.com with ESMTP id n2T4LiPe022269 for ; Sat, 28 Mar 2009 21:21:44 -0700 Received: from rv-out-0506.google.com (rvbl9.prod.google.com [10.140.88.9]) by zps77.corp.google.com with ESMTP id n2T4Lg0x026838 for ; Sat, 28 Mar 2009 21:21:43 -0700 Received: by rv-out-0506.google.com with SMTP id l9so3127545rvb.31 for ; Sat, 28 Mar 2009 21:21:42 -0700 (PDT) MIME-Version: 1.0 Received: by 10.141.195.5 with SMTP id x5mr2007312rvp.282.1238300502872; Sat, 28 Mar 2009 21:21:42 -0700 (PDT) In-Reply-To: References: <20090302065301.356261C7A1E@localhost> Date: Sun, 29 Mar 2009 04:32:00 -0000 Message-ID: Subject: Re: [RFA]: Handle multi-line versions of multi-breakpoints From: Doug Evans To: gdb-patches@sourceware.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-03/txt/msg00654.txt.bz2 Ping. [This doesn't seem to be a controversial patch, and there is definitely a bug here that needs fixing.] On Fri, Mar 13, 2009 at 9:47 AM, Doug Evans wrote: > Ping. > > On Sun, Mar 1, 2009 at 11:53 PM, Doug Evans wrote: >> Hi. >> >> "multi-breakpoints" (multiple breakpoints for the same source line) >> don't work for constructors and inline functions where the source expres= sion >> spans several lines (at least for the new testcases included in this pat= ch). >> >> This patch fixes it by, if there's no exact match, >> rescanning the symtabs for all matches of the best match. >> Included are updated testcases to exercise the bug. >> The bug isn't exposed by templates, but I updated mb-templates.{cc,exp} >> anyway (if only to confirm things work there too). >> >> Ok to check in? >> >> 2009-03-01 =A0Doug Evans =A0 >> >> =A0 =A0 =A0 =A0* symtab.c (expand_line_sal): If we don't find an exact m= atch, >> =A0 =A0 =A0 =A0rescan all symtabs again to find all copies of the best m= atch. >> >> =A0 =A0 =A0 =A0* gdb.cp/mb-ctor.exp: Add multi-line source statement tes= t. >> =A0 =A0 =A0 =A0* gdb.cp/mb-ctor.cc: Ditto. >> =A0 =A0 =A0 =A0* gdb.cp/mb-inline.exp: Add multi-line source statement t= est. >> =A0 =A0 =A0 =A0* gdb.cp/mb-inline.h (multi_line_foo): New function. >> =A0 =A0 =A0 =A0* gdb.cp/mb-inline1.cc: Call it. >> =A0 =A0 =A0 =A0* gdb.cp/mb-inline2.cc: Ditto. >> =A0 =A0 =A0 =A0* gdb.cp/mb-templates.exp: Add multi-line source statemen= t test. >> =A0 =A0 =A0 =A0* gdb.cp/mb-templates.cc (multi_line_foo): New template. >> >> Index: symtab.c >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> RCS file: /cvs/src/src/gdb/symtab.c,v >> retrieving revision 1.204 >> diff -u -p -r1.204 symtab.c >> --- symtab.c =A0 =A02 Mar 2009 06:33:24 -0000 =A0 =A0 =A0 1.204 >> +++ symtab.c =A0 =A02 Mar 2009 06:39:17 -0000 >> @@ -4481,7 +4481,6 @@ expand_line_sal (struct symtab_and_line >> =A0 else >> =A0 =A0 { >> =A0 =A0 =A0 struct linetable_entry *best_item =3D 0; >> - =A0 =A0 =A0struct symtab *best_symtab =3D 0; >> =A0 =A0 =A0 int exact =3D 0; >> >> =A0 =A0 =A0 lineno =3D sal.line; >> @@ -4533,13 +4532,41 @@ expand_line_sal (struct symtab_and_line >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && (best_item =3D=3D= NULL || item->line < best_item->line)) >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0best_item =3D item; >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 best_symtab =3D symtab; >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} >> =A0 =A0 =A0 =A0 =A0 =A0} >> =A0 =A0 =A0 =A0} >> + >> =A0 =A0 =A0 if (!exact && best_item) >> - =A0 =A0 =A0 append_expanded_sal (&ret, best_symtab, lineno, best_item-= >pc); >> + =A0 =A0 =A0 { >> + =A0 =A0 =A0 =A0 /* We found a "good enough" match. >> + =A0 =A0 =A0 =A0 =A0 =A0Rescan to find all such matches. >> + =A0 =A0 =A0 =A0 =A0 =A0This is to handle constructors, templates, inli= ne-functions >> + =A0 =A0 =A0 =A0 =A0 =A0that have multiple breakpoints for one line num= ber. =A0*/ >> + >> + =A0 =A0 =A0 =A0 ALL_SYMTABS (objfile, symtab) >> + =A0 =A0 =A0 =A0 =A0 { >> + =A0 =A0 =A0 =A0 =A0 =A0 if (strcmp (sal.symtab->filename, >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 symtab->filename) =3D= =3D 0) >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 { >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct linetable *l; >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 int len; >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 l =3D LINETABLE (symtab); >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!l) >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue; >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 len =3D l->nitems; >> + >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 for (j =3D 0; j < len; j++) >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct linetable_entry *item = =3D &(l->item[j]); >> + >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (item->line =3D=3D best_ite= m->line) >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 append_expanded_sal (&ret,= symtab, item->line, >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0item->pc); >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >> + =A0 =A0 =A0 =A0 =A0 } >> + =A0 =A0 =A0 } >> =A0 =A0 } >> >> =A0 /* For optimized code, compiler can scatter one source line accross >> Index: testsuite/gdb.cp/mb-ctor.cc >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/mb-ctor.cc,v >> retrieving revision 1.1 >> diff -u -p -r1.1 mb-ctor.cc >> --- testsuite/gdb.cp/mb-ctor.cc 24 Sep 2007 07:40:32 -0000 =A0 =A0 =A01.1 >> +++ testsuite/gdb.cp/mb-ctor.cc 2 Mar 2009 06:39:17 -0000 >> @@ -28,11 +28,19 @@ public: >> =A0 ~Derived(); >> =A0private: >> =A0 int i; >> + =A0int i2; >> =A0}; >> >> =A0Derived::Derived(int i) : Base(i) >> =A0{ >> =A0 this->i =3D i; >> + =A0/* The next statement is spread over two lines on purpose to exerci= se >> + =A0 =A0 a bug where breakpoints set on all but the last line of a stat= ement >> + =A0 =A0 would not get multiple breakpoints. >> + =A0 =A0 The second line's text for gdb_get_line_number is a subset of = the >> + =A0 =A0 first line so that we don't care which line gdb prints when it= stops. =A0*/ >> + =A0this->i2 =3D // set breakpoint here >> + =A0 =A0i; // breakpoint here >> =A0} >> >> =A0Derived::~Derived() >> Index: testsuite/gdb.cp/mb-ctor.exp >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/mb-ctor.exp,v >> retrieving revision 1.5 >> diff -u -p -r1.5 mb-ctor.exp >> --- testsuite/gdb.cp/mb-ctor.exp =A0 =A0 =A0 =A03 Jan 2009 05:58:04 -000= 0 =A0 =A0 =A0 1.5 >> +++ testsuite/gdb.cp/mb-ctor.exp =A0 =A0 =A0 =A02 Mar 2009 06:39:17 -0000 >> @@ -43,6 +43,11 @@ gdb_start >> =A0gdb_reinitialize_dir $srcdir/$subdir >> =A0gdb_load ${binfile} >> >> +if ![runto_main] then { >> + =A0 =A0perror "couldn't run to breakpoint" >> + =A0 =A0continue >> +} >> + >> =A0# Set a breakpoint with multiple locations >> =A0# and a condition. >> >> @@ -50,34 +55,31 @@ gdb_test "break 'Derived::Derived(int)'" >> =A0 =A0 "Breakpoint.*at.* file .*$srcfile, line.*\\(2 locations\\).*" \ >> =A0 =A0 "set-breakpoint at ctor" >> >> +gdb_breakpoint [gdb_get_line_number "set breakpoint here"] >> + >> =A0gdb_test "break 'Derived::~Derived()'" \ >> =A0 =A0 "Breakpoint.*at.* file .*$srcfile, line.*\\(2 locations\\).*" \ >> =A0 =A0 "set-breakpoint at dtor" >> >> -gdb_run_cmd >> -gdb_expect { >> - =A0 =A0-re "Breakpoint \[0-9\]+,.*Derived.*i=3D7.*$gdb_prompt $" { >> - =A0 =A0 =A0 pass "run to breakpoint" >> - =A0 =A0} >> - =A0 =A0-re "$gdb_prompt $" { >> - =A0 =A0 =A0 fail "run to breakpoint" >> - =A0 =A0} >> - =A0 =A0timeout { >> - =A0 =A0 =A0 fail "run to breakpoint (timeout)" >> - =A0 =A0} >> -} >> +gdb_test "continue" \ >> + =A0 =A0".*Breakpoint.*Derived.*i=3D7.*" \ >> + =A0 =A0"run to breakpoint 1 v1" >> + >> +gdb_continue_to_breakpoint "set breakpoint here" ".* breakpoint here" >> >> =A0gdb_test "continue" \ >> =A0 =A0 ".*Breakpoint.*Derived.*i=3D15.*" \ >> - =A0 =A0"run to breakpoint 2" >> + =A0 =A0"run to breakpoint 1 v2" >> + >> +gdb_continue_to_breakpoint "set breakpoint here" ".* breakpoint here" >> >> =A0gdb_test "continue" \ >> =A0 =A0 ".*Breakpoint.*~Derived.*" \ >> - =A0 =A0"run to breakpoint 3" >> + =A0 =A0"run to breakpoint 3 v1" >> >> =A0gdb_test "continue" \ >> =A0 =A0 ".*Breakpoint.*~Derived.*" \ >> - =A0 =A0"run to breakpoint 4" >> + =A0 =A0"run to breakpoint 3 v2" >> >> =A0gdb_test "continue" \ >> =A0 =A0 ".*exited normally.*" \ >> Index: testsuite/gdb.cp/mb-inline.exp >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/mb-inline.exp,v >> retrieving revision 1.2 >> diff -u -p -r1.2 mb-inline.exp >> --- testsuite/gdb.cp/mb-inline.exp =A0 =A0 =A03 Jan 2009 05:58:04 -0000 = =A0 =A0 =A0 1.2 >> +++ testsuite/gdb.cp/mb-inline.exp =A0 =A0 =A02 Mar 2009 06:39:17 -0000 >> @@ -106,3 +106,25 @@ gdb_expect { >> =A0gdb_test "continue" \ >> =A0 =A0 ".*Program exited normally.*" \ >> =A0 =A0 "continue with disabled breakpoint 1.2" >> + >> +# Make sure we can set a breakpoint on a source statement that spans >> +# multiple lines. >> + >> +delete_breakpoints >> + >> +set bp_location [gdb_get_line_number "set multi-line breakpoint here" $= hdrfile] >> + >> +if { ![runto_main] } { >> + =A0 =A0fail "Can't run to main for multi_line_foo tests." >> + =A0 =A0return 0 >> +} >> + >> +gdb_test "break $hdrfile:$bp_location" \ >> + =A0 =A0"Breakpoint.*at.* file .*$hdrfile, line.*\\(2 locations\\).*" \ >> + =A0 =A0"set multi_line_foo breakpoint" >> +gdb_test "continue" \ >> + =A0 =A0".*Breakpoint.*multi_line_foo \\(i=3D0\\).*" \ >> + =A0 =A0"run to multi_line_foo breakpoint 4 afn" >> +gdb_test "continue" \ >> + =A0 =A0".*Breakpoint.*multi_line_foo \\(i=3D1\\).*" \ >> + =A0 =A0"run to multi_line_foo breakpoint 4 bfn" >> Index: testsuite/gdb.cp/mb-inline.h >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/mb-inline.h,v >> retrieving revision 1.2 >> diff -u -p -r1.2 mb-inline.h >> --- testsuite/gdb.cp/mb-inline.h =A0 =A0 =A0 =A03 Jan 2009 05:58:04 -000= 0 =A0 =A0 =A0 1.2 >> +++ testsuite/gdb.cp/mb-inline.h =A0 =A0 =A0 =A02 Mar 2009 06:39:17 -0000 >> @@ -26,5 +26,12 @@ foo (int i) >> =A0 return i; // set breakpoint here >> =A0} >> >> +static int >> +multi_line_foo (int i) >> +{ >> + =A0return // set multi-line breakpoint here >> + =A0 =A0i; >> +} >> + >> =A0extern int afn (); >> =A0extern int bfn (); >> Index: testsuite/gdb.cp/mb-inline1.cc >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/mb-inline1.cc,v >> retrieving revision 1.2 >> diff -u -p -r1.2 mb-inline1.cc >> --- testsuite/gdb.cp/mb-inline1.cc =A0 =A0 =A03 Jan 2009 05:58:04 -0000 = =A0 =A0 =A0 1.2 >> +++ testsuite/gdb.cp/mb-inline1.cc =A0 =A0 =A02 Mar 2009 06:39:17 -0000 >> @@ -23,7 +23,7 @@ >> =A0int >> =A0afn () >> =A0{ >> - =A0return foo (0); >> + =A0return foo (0) + multi_line_foo (0); >> =A0} >> >> =A0int >> Index: testsuite/gdb.cp/mb-inline2.cc >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/mb-inline2.cc,v >> retrieving revision 1.2 >> diff -u -p -r1.2 mb-inline2.cc >> --- testsuite/gdb.cp/mb-inline2.cc =A0 =A0 =A03 Jan 2009 05:58:04 -0000 = =A0 =A0 =A0 1.2 >> +++ testsuite/gdb.cp/mb-inline2.cc =A0 =A0 =A02 Mar 2009 06:39:17 -0000 >> @@ -21,5 +21,5 @@ >> =A0int >> =A0bfn () >> =A0{ >> - =A0return foo (1); >> + =A0return foo (1) + multi_line_foo (1); >> =A0} >> Index: testsuite/gdb.cp/mb-templates.cc >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/mb-templates.cc,v >> retrieving revision 1.1 >> diff -u -p -r1.1 mb-templates.cc >> --- testsuite/gdb.cp/mb-templates.cc =A0 =A024 Sep 2007 07:40:32 -0000 = =A0 =A0 =A01.1 >> +++ testsuite/gdb.cp/mb-templates.cc =A0 =A02 Mar 2009 06:39:17 -0000 >> @@ -8,6 +8,13 @@ void foo(T i) >> =A0 std::cout << "hi\n"; // set breakpoint here >> =A0} >> >> +template >> +void multi_line_foo(T i) >> +{ >> + =A0std::cout // set multi-line breakpoint here >> + =A0 =A0<< "hi\n"; >> +} >> + >> =A0int main() >> =A0{ >> =A0 =A0 foo(0); >> @@ -16,4 +23,9 @@ int main() >> =A0 =A0 foo(1); >> =A0 =A0 foo(2); >> =A0 =A0 foo(2); >> + >> + =A0 =A0multi_line_foo(0); >> + =A0 =A0multi_line_foo(0); >> + >> + =A0 =A0return 0; >> =A0} >> Index: testsuite/gdb.cp/mb-templates.exp >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/mb-templates.exp,v >> retrieving revision 1.5 >> diff -u -p -r1.5 mb-templates.exp >> --- testsuite/gdb.cp/mb-templates.exp =A0 3 Jan 2009 05:58:04 -0000 =A0 = =A0 =A0 1.5 >> +++ testsuite/gdb.cp/mb-templates.exp =A0 2 Mar 2009 06:39:17 -0000 >> @@ -165,3 +165,25 @@ gdb_test "continue" \ >> =A0 =A0 ".*Breakpoint.*foo \\(i=3D1\\).*" \ >> =A0 =A0 "instantiation: run to breakpoint 2" >> >> + >> +# Make sure we can set a breakpoint on a source statement that spans >> +# multiple lines. >> + >> +delete_breakpoints >> + >> +set bp_location [gdb_get_line_number "set multi-line breakpoint here"] >> + >> +if { ![runto_main] } { >> + =A0 =A0fail "Can't run to main for multi_line_foo tests." >> + =A0 =A0return 0 >> +} >> + >> +gdb_test "break $srcfile:$bp_location" \ >> + =A0 =A0"Breakpoint.*at.* file .*$srcfile, line.*\\(2 locations\\).*" \ >> + =A0 =A0"set multi_line_foo breakpoint" >> +gdb_test "continue" \ >> + =A0 =A0".*Breakpoint.*multi_line_foo \\(i=3D0\\).*" \ >> + =A0 =A0"run to multi_line_foo breakpoint 2 " >> +gdb_test "continue" \ >> + =A0 =A0".*Breakpoint.*multi_line_foo \\(i=3D0\\).*" \ >> + =A0 =A0"run to multi_line_foo breakpoint 2 " >> >