Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re: [RFA] new test for separate debug info
@ 2004-01-13  5:19 Michael Elizabeth Chastain
  2004-01-13 17:18 ` Elena Zannoni
  0 siblings, 1 reply; 34+ messages in thread
From: Michael Elizabeth Chastain @ 2004-01-13  5:19 UTC (permalink / raw)
  To: ezannoni; +Cc: drow, gdb-patches

Okay, I just ran it on spe191.testdrive.hp.com to see what happens.
What happens is:

  (gdb) info source
  Current source file is /house/chastain/gdb/s1/gdb/testsuite/gdb.base/sepdebug.c
  Located in /house/chastain/gdb/s1/gdb/testsuite/gdb.base/sepdebug.c
  Contains 150 lines.
  Source language is c.
  Compiled with unknown debugging format.
  Does not include preprocessor macro info.
  (gdb) UNSUPPORTED: gdb.base/sepdebug.exp: no separate debug info handling
  testcase /house/chastain/gdb/s1/gdb/testsuite/gdb.base/sepdebug.exp completed in 0 seconds

This is with HP Ansi C B.11.11.28707.GP.

I'm happy with this outcome, although I am not happy that "info source"
prints "compiled with unknown debugging format".  I will investigate and
file a PR.

Also, the message does not happen because of "unknown debugging format".
It happens because I don't have gnu binutils in my $PATH, and the HP-UX
strip barfs on "--strip-debug".

I haven't set up a test bed for gcc + binutils on this platform yet,
just the native tools.  I did try GNU strip from binutils 2.14 on
a hello-world program with "strip --strip-debug hello" and it didn't
complain.

By the way, HP Ansi C and HP C++ have an objdebug switch:

      +objdebug      This option when used with any of the -g options will
                     cause the debug information to be left in the object
                     files instead of being placed in the a.out.  This will
                     bypass the pxdb step and the links will be faster.
                     Available only for wdb(1) or gdb(1).  +noobjdebug is
                     the default at compile time.  +noobjdebug can be used
                     at link time to continue to place the debug info into
                     the a.out, even if some objects were compiled with
                     +objdebug.
                     NOTE: Object files or archive libraries must not be
                     removed if this new method of debugging is used.

Michael C


^ permalink raw reply	[flat|nested] 34+ messages in thread
* Re: [RFA] new test for separate debug info
@ 2004-01-14  2:47 Michael Elizabeth Chastain
  2004-01-14 15:09 ` Elena Zannoni
  0 siblings, 1 reply; 34+ messages in thread
From: Michael Elizabeth Chastain @ 2004-01-14  2:47 UTC (permalink / raw)
  To: ezannoni; +Cc: drow, gdb-patches

> My idea was more to incrementally add broken cases to the skip list as
> we find them.

It's not my favorite, but it's okay with me.

  +} elseif { [test_debug_format "unknown"] } then {
  +    # gdb doesn't know what the debug format is. We are out of luck here.
  +    unsupported "unknown debugging format"
  +    return -1

I tested this.  It works for me:

  ...
  Compiled with unknown debugging format.
  Does not include preprocessor macro info.
  (gdb) UNSUPPORTED: gdb.base/sepdebug.exp: unknown debugging format
  testcase /house/chastain/gdb/s1/gdb/testsuite/gdb.base/sepdebug.exp completed in 1 seconds

   if [gdb_gnu_strip_debug $binfile] {
  -    unsupported "no separate debug info handling"
  +    unsupported "cannot produce separate debug info files (check that you have
  a recent version of strip and objcopy installed)"
       return -1
 }

I would rather that the message be shorter so that it does not blow up
my tables if it appears in a table.  How about:

  if [gdb_gnu_strip_debug $binfile] {
      # check that you have a recent version of strip and objcopy
      unsupported "cannot produce separate debug info files"
  }

Michael C


^ permalink raw reply	[flat|nested] 34+ messages in thread
* Re: [RFA] new test for separate debug info
@ 2004-01-13 22:24 Michael Elizabeth Chastain
  2004-01-13 23:37 ` Elena Zannoni
  0 siblings, 1 reply; 34+ messages in thread
From: Michael Elizabeth Chastain @ 2004-01-13 22:24 UTC (permalink / raw)
  To: ezannoni, mec.gnu; +Cc: drow, gdb-patches

I've seen this "unknown debugging format" before, on dwarf-1.
I really agree with daniel's idea that the test should be
"if format == dwarf-2" rather than "if format != stabs+".

> Maybe the two unsupported messages should differ a bit more from each
> other: "cannot produce separate debug info file" instead?

How about "strip --strip-debug failed", make it really clear.

Michael C


^ permalink raw reply	[flat|nested] 34+ messages in thread
* Re: [RFA] new test for separate debug info
@ 2004-01-13  2:28 Michael Elizabeth Chastain
  2004-01-13  4:49 ` Elena Zannoni
  0 siblings, 1 reply; 34+ messages in thread
From: Michael Elizabeth Chastain @ 2004-01-13  2:28 UTC (permalink / raw)
  To: drow, ezannoni; +Cc: gdb-patches

> Hmm, maybe. That's an easy fix, if needed. Does binutils deal with som?

I don't know.  But I like Daniel's idea; make it "dwarf-2 only".
In the place where you comment that stabs+ does not work, you
can comment that SOM has not even been tried.

Michael C


^ permalink raw reply	[flat|nested] 34+ messages in thread
* Re: [RFA] new test for separate debug info
@ 2003-11-14 19:37 Michael Elizabeth Chastain
  2003-11-14 20:09 ` Elena Zannoni
  0 siblings, 1 reply; 34+ messages in thread
From: Michael Elizabeth Chastain @ 2003-11-14 19:37 UTC (permalink / raw)
  To: ezannoni; +Cc: gdb-patches

Elena Zannoni writes:

    # If we have too many warnings or errors,
    # the output of the test can't be considered correct.
    if { $warning_threshold > 0 && $warncnt >= $warning_threshold
	 || $perror_threshold > 0 && $errcnt >= $perror_threshold } {
        verbose "Error/Warning threshold exceeded: \
                 $errcnt $warncnt (max. $perror_threshold $warning_threshold)"
        set type UNRESOLVED
    }

Ick!

> what to do? Maybe just get rid of the unsupported call, and just get
> out of the test.

Well, "nothing different" is okay.  I'm not worried about the actual
output, as long as we understand why it behaves that way, and stick that
understanding into a comment somewhere.

As Daniel alluded to -- what SHOULD happen when an end user tries
to do this with stabs+?  Should binutils bonk out with a nice error
message?

Michael C


^ permalink raw reply	[flat|nested] 34+ messages in thread
* Re: [RFA] new test for separate debug info
@ 2003-11-14 15:18 Michael Elizabeth Chastain
  2003-11-14 15:52 ` Elena Zannoni
  0 siblings, 1 reply; 34+ messages in thread
From: Michael Elizabeth Chastain @ 2003-11-14 15:18 UTC (permalink / raw)
  To: ezannoni; +Cc: gdb-patches

eza> What happens is that gdb_load errors out and calls perror, then
eza> returns 1.  All I have done is wrap gdb_load in a check for a 1 return
eza> value.

Here's the part that's confusing me.  Your gdb_load wrapper
says "if [gdb_load ...] { unsupported ...}", but your gdb.sum
file says "# of unresolved test cases: 1".  The call to "unsupported"
doesn't fit the result of "unresolved"!

eza> The alternative is to alter the gdb_load (or whatever gets
eza> caled from it) to recognize that error and do something specific, but
eza> I thought that was too ad hoc a behavior for a generic procedure.

Ah, okay.

Michael C


^ permalink raw reply	[flat|nested] 34+ messages in thread
* Re: [RFA] new test for separate debug info
@ 2003-11-14  5:14 Michael Elizabeth Chastain
  2003-11-14 14:30 ` Elena Zannoni
  0 siblings, 1 reply; 34+ messages in thread
From: Michael Elizabeth Chastain @ 2003-11-14  5:14 UTC (permalink / raw)
  To: ezannoni; +Cc: gdb-patches

Woah, I am confused.

Your source code says "unsupported", but your gdb.sum file says
"unresolved", and your gdb.log file says "ERROR".

Is your sandbox a little messed up, or is it me?!

Michael C

===

  ok, How about this behavior?

  Running /to/scratch/ezannoni/pristine/src/gdb/testsuite/gdb.base/sepdebug.exp ...
  ERROR: couldn't load /to/scratch/ezannoni/pristine/tomago/gdb/testsuite/gdb.base/sepdebug.dbglnk into /to/scratch/ezannoni/pristine/tomago/gdb/testsuite/../../gdb/gdb.
   
		  === gdb Summary ===
   
  # of unresolved testcases       1
  /to/scratch/ezannoni/pristine/tomago/gdb/testsuite/../../gdb/gdb version  2003-11-07-cvs -nx
   

  I added a wrapper around the gdb_load call:

  if [gdb_load ${binfile}] {
      unsupported "Gdb cannot process a separate debug info file"
      return -1
  }



^ permalink raw reply	[flat|nested] 34+ messages in thread
* Re: [RFA] new test for separate debug info
@ 2003-11-14  4:57 Michael Elizabeth Chastain
  2003-11-14 14:32 ` Elena Zannoni
  0 siblings, 1 reply; 34+ messages in thread
From: Michael Elizabeth Chastain @ 2003-11-14  4:57 UTC (permalink / raw)
  To: ezannoni; +Cc: gdb-patches

eza> woah. I didn't test this. And I guess nobody did until now.
eza> RH ships only dwarf2 toolchains.

As an aside, my red hat 8.0 gcc supports both dwarf-2 and stabs+,
with dwarf-2 as default.  FSF gcc for i686-pc-linux-gnu has also
been this way since 3.1 or 3.2.

If I recall correctly, FSF gcc for sparc-sun-solaris is still
stabs+ by default, but I wouldn't swear to it.

I'm still waiting for dwarf-1 to die before I take up a
stabs+ death watch!

Michael C


^ permalink raw reply	[flat|nested] 34+ messages in thread
* Re: [RFA] new test for separate debug info
@ 2003-11-13 17:55 Michael Elizabeth Chastain
  2003-11-13 19:23 ` Elena Zannoni
                   ` (2 more replies)
  0 siblings, 3 replies; 34+ messages in thread
From: Michael Elizabeth Chastain @ 2003-11-13 17:55 UTC (permalink / raw)
  To: ezannoni, gdb-patches

My test bed says:

  binutils 2.13.90.0.2-2-rh, dwarf-2
  binutils 2.13.90.0.2-2-rh, stabs+
  binutils 2.14, dwarf-2
  binutils 2.14, stabs+
    1 UNSUPPORTED
    # okay

  binutils HEAD, dwarf-2
    77 PASS
    # okay

  binutils HEAD, stabs+
    3 ERROR, 7 PASS, 44 FAIL, 1 UNRESOLVED
    # not okay

The results are the same for all versions of gcc tested.

Here is an excerpt from gdb.log:
 
  # gdb HEAD, gcc 3.3.2, binutils HEAD, -gstabs+
  (gdb) dir /berman/fsf/_today_/source/gdb/HEAD/src/gdb/testsuite/gdb.base
  Source directories searched: /berman/fsf/_today_/source/gdb/HEAD/src/gdb/testsuite/gdb.base:$cdir:$cwd
  (gdb) file /berman/fsf/_today_/berman/test/gdb.base/sepdebug
  Reading symbols from /berman/fsf/_today_/berman/test/gdb.base/sepdebug...Reading symbols from /berman/fsf/_today_/berman/test/gdb.base/.debug/sepdebug.debug...Can't find any code sections in symbol file
  (gdb) ERROR: couldn't load /berman/fsf/_today_/berman/test/gdb.base/sepdebug into gdb.
  delete breakpoints
  (gdb) UNRESOLVED: gdb.base/sepdebug.exp: Delete all breakpoints when none
  From gdb-patches-return-28583-mec.gnu=mindspring.com@sources.redhat.com  Wed Nov 12 17:26:42 2003

It looks like either binutils or gdb needs some work.

If you could kludge the test to handle "Can't find any code sections
in symbol file" then I would be happy with the test script as a test
script.

I have put up a test result tarball:

  ftp://ftp.shout.net/pub/users/mec/gdb/2003-11-10-sepdebug.tar.gz

The interesting files are:

  native,HEAD,3.3.2,HEAD,stabs+,2/
    gdb.log
    test.tar.gz

I actually run the tests with:

  runtest ...  --target_board unix/gdb:debug_flags=-gdwarf-2\\\\\\ -g2 ...
  runtest ...  --target_board unix/gdb:debug_flags=-gstabs+\\\\\\ -g2 ...

It might be some weird option-processing problem, but I doubt it,
because I run dwarf-2 and stabs+ in the same way.  That is, I don't
just run dwarf-2 by leaving the debug_flags as default.
    
Michael C


^ permalink raw reply	[flat|nested] 34+ messages in thread
* Re: [RFA] new test for separate debug info
@ 2003-11-13 16:49 Michael Elizabeth Chastain
  0 siblings, 0 replies; 34+ messages in thread
From: Michael Elizabeth Chastain @ 2003-11-13 16:49 UTC (permalink / raw)
  To: ac131313, ezannoni; +Cc: gdb-patches

ac> FWIW, I think cloning "break.c" is a good idea.  It avoids the problem 
ac> of someone wanting to change/modify that test being landed with the task 
ac> of changing/modifying N other tests.

Me too.  I agree with Andrew's view.

Michael C


^ permalink raw reply	[flat|nested] 34+ messages in thread
* [RFA] new test for separate debug info
@ 2003-11-12 22:13 Elena Zannoni
  2003-11-12 22:29 ` Daniel Jacobowitz
  0 siblings, 1 reply; 34+ messages in thread
From: Elena Zannoni @ 2003-11-12 22:13 UTC (permalink / raw)
  To: gdb-patches


Ok, I think I addresed all of the comments. Here are the 2 files, in
their entirety. However, since they are clones of break.c and
break.exp, I just added, for your viewing pleasure, a diff between
break.exp and sepdebug.exp.

2003-11-12  Elena Zannoni  <ezannoni@redhat.com>

	* gdb.base/sepdebug.exp: New test for separate debug info files.
	* gdb.base/sepdebug.c: New source file for the above.
	* lib/gdb.exp (separate_debug_filename): New procedure.
	(gdb_gnu_strip_debug): New procedure.

DIffs:

--- break.exp	2003-11-12 10:38:39.000000000 -0500
+++ sepdebug.exp	2003-11-12 15:50:04.000000000 -0500
@@ -19,7 +19,8 @@
 # Please email any bugs, comments, and/or additions to this file to:
 # bug-gdb@prep.ai.mit.edu
 
-# This file was written by Rob Savoye. (rob@cygnus.com)
+# Modified to test gdb's handling of separate debug info files.
+# Based on break.exp, written by Rob Savoye. (rob@cygnus.com)
 
 if $tracelevel then {
     strace $tracelevel
@@ -32,7 +33,7 @@
 set prms_id 0
 set bug_id 0
 
-set testfile "break"
+set testfile "sepdebug"
 set srcfile ${testfile}.c
 set binfile ${objdir}/${subdir}/${testfile}
 
@@ -40,9 +41,18 @@
     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
 }
 
-if [get_compiler_info ${binfile}] {
+# Note: the procedure gdb_gnu_strip_debug will produce an executable called
+# ${binfile}, which is just like the executable ($binfile) but without
+# the debuginfo. Instead $binfile has a .gnudebuglink section which contains
+# the name of a idebuginfo only file. This file will be stored in the
+# gdb.base/.debug subdirectory.
+
+if [gdb_gnu_strip_debug $binfile] {
+    unsupported "no separate debug info handling"
     return -1
 }
 
 gdb_exit
 gdb_start
@@ -159,12 +169,6 @@
     set main_line $bp_location6
 }
 
-if {$hp_aCC_compiler} {
-    set proto "\\(int\\)"
-} else {
-    set proto ""
-}
-
 set bp_location7 [gdb_get_line_number "set breakpoint 7 here"]
 set bp_location8 [gdb_get_line_number "set breakpoint 8 here"]
 set bp_location9 [gdb_get_line_number "set breakpoint 9 here"]
@@ -173,7 +177,7 @@
     "Num Type\[ \]+Disp Enb Address\[ \]+What.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$main_line.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in marker2 at .*$srcfile:($bp_location8|$bp_location9).*
-\[0-9\]+\[\t \]+breakpoint     keep y.* in factorial$proto at .*$srcfile:$bp_location7.*
+\[0-9\]+\[\t \]+breakpoint     keep y.* in factorial at .*$srcfile:$bp_location7.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$bp_location1.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$bp_location1.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$bp_location2.*
@@ -302,7 +306,7 @@
 #
 gdb_test "info break" "Num Type.*Disp Enb Address.*What.*\[\r\n\]
 \[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$main_line.*\[\r\n\]
-\[0-9\]+\[\t \]+breakpoint     del.*y.*in factorial$proto at .*$srcfile:$bp_location7.*\[\r\n\]
+\[0-9\]+\[\t \]+breakpoint     del.*y.*in factorial at .*$srcfile:$bp_location7.*\[\r\n\]
 \[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$bp_location1.*\[\r\n\]
 \[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$bp_location6.*\[\r\n\]
 \[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$bp_location2.*\[\r\n\]
@@ -604,7 +608,7 @@
 }
 send_gdb "print marker2(99)\n"
 gdb_expect {
-  -re "The program being debugged stopped while in a function called from GDB.\r\nWhen the function .marker2$proto. is done executing, GDB will silently\r\nstop .instead of continuing to evaluate the expression containing\r\nthe function call...*$gdb_prompt $"\
+  -re "The program being debugged stopped while in a function called from GDB.\r\nWhen the function .marker2. is done executing, GDB will silently\r\nstop .instead of continuing to evaluate the expression containing\r\nthe function call...*$gdb_prompt $"\
           {pass "hit breakpoint on called function"}
   -re "$gdb_prompt $"\
           {fail "hit breakpoint on called function"}
@@ -845,23 +849,15 @@
 
 #********
 
-# build a new file with optimization enabled so that we can try breakpoints
-# on targets with optimized prologues
-
-set binfileo2 ${objdir}/${subdir}/${testfile}o2
-
-if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfileo2}" executable {debug additional_flags="-O2" }] != "" } {
-    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
-}
-
-if [get_compiler_info ${binfileo2}] {
-    return -1
-}
-
+# now move the .debug file to a different location so that we can test
+# the "set debug-file-directory" command.
+  
+remote_exec build "mv ${objdir}/${subdir}/.debug/${testfile}.debug ${objdir}/${subdir}"
 gdb_exit
 gdb_start
 gdb_reinitialize_dir $srcdir/$subdir
-gdb_load ${binfileo2}
+gdb_test "set debug-file-directory ${objdir}/${subdir}" ".*" "set separate debug location"
+gdb_load ${binfile}
 
 if [target_info exists gdb_stub] {
     gdb_step_for_stub;





Index: gdb.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/gdb.exp,v
retrieving revision 1.37
diff -u -p -r1.37 gdb.exp
--- gdb.exp     1 May 2003 01:09:51 -0000       1.37
+++ gdb.exp     12 Nov 2003 21:12:21 -0000
@@ -1840,3 +1840,84 @@ proc gdb_skip_bogus_test { msg } {
     return 0;
 }
  
+# Note: the procedure gdb_gnu_strip_debug will produce an executable called
+# ${binfile}, which is just like the original executable ($binfile) but without
+# the debuginfo. Instead $binfile has a .gnu_debuglink section which contains
+# the name of a debuginfo only file. This file will be stored in the
+# gdb.base/.debug subdirectory.
+
+# starting with an executable:
+# foo --> original executable
+
+# at the end of the process we have:
+# foo.stripped --> foo w/o debug info
+# .debug/foo.debug --> foo's debug info
+# foo --> like foo, but with a new .gnu_debuglink section pointing to foo.debug
.
+
+# Return the name of the file in which we should stor EXEC's separated
+# debug info. EXEC contains the full path.
+proc separate_debug_filename { exec } {
+
+    # In a .debug subdirectory off the same directory where the testcase
+    # executable is going to be. Something like:
+    # <your-path>/gdb/testsuite/gdb.base/.debug/blah.debug.
+    # This is the default location where gdb expects to findi
+    # the debug info file.
+
+    set exec_dir [file dirname $exec]
+    set exec_file [file tail $exec]
+    set debug_dir [file join $exec_dir ".debug"]
+    set debug_file [file join $debug_dir "${exec_file}.debug"]
+
+    return $debug_file
+}
+
+
+proc gdb_gnu_strip_debug { dest } {
+
+    set debug_file [separate_debug_filename $dest]
+    set strip_to_file_program strip
+    set objcopy_program objcopy
+
+    # Make sure the directory that will hold the separated debug
+    # info actually exists.
+    set debug_dir [file dirname $debug_file]
+    if {! [file isdirectory $debug_dir]} {
+       file mkdir $debug_dir
+    }
+
+    set debug_link [file tail $debug_file]
+    set stripped_file "${dest}.stripped"
+
+    # Get rid of the debug info, and store result in stripped_file
+    # something like gdb/testsuite/gdb.base/blah.stripped.
+    set result [catch "exec $strip_to_file_program --strip-debug ${dest} -o ${s
tripped_file}" output]
+    verbose "result is $result"
+    verbose "output is $output"
+    if {$result == 1} {
+      return 1
+    }
+
+    # Get rid of everything but the debug info, and store result in debug_file
+    # This will be in the .debug subdirectory, see above.
+    set result [catch "exec $strip_to_file_program --only-keep-debug ${dest} -o
 ${debug_file}" output]
+    verbose "result is $result"
+    verbose "output is $output"
+    if {$result == 1} {
+      return 1
+    }
+
+    # Link the two previous output files together, adding the .gnu_debuglink
+    # section to the stripped_file, containing a pointer to the debug_file,
+    # save the new file in dest.
+    # This will be the regular executable filename, in the usual location.
+    set result [catch "exec $objcopy_program --add-gnu-debuglink=${debug_file}
${stripped_file} ${dest}" output]
+    verbose "result is $result"
+    verbose "output is $output"
+    if {$result == 1} {
+      return 1
+    }
+
+   return 0
+}
+

sepdebug.exp
-------------

#   Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999,
#   2000, 2002, 2003
#   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 2 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  

# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu

# Modified to test gdb's handling of separate debug info files.
# Based on break.exp, written by Rob Savoye. (rob@cygnus.com)

if $tracelevel then {
    strace $tracelevel
}


#
# test running programs
#
set prms_id 0
set bug_id 0

set testfile "sepdebug"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}

if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}

# Note: the procedure gdb_gnu_strip_debug will produce an executable called
# ${binfile}, which is just like the executable ($binfile) but without
# the debuginfo. Instead $binfile has a .gnudebuglink section which contains
# the name of a idebuginfo only file. This file will be stored in the
# gdb.base/.debug subdirectory.

if [gdb_gnu_strip_debug $binfile] {
    unsupported "no separate debug info handling"
    return -1
}
  
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}

if [target_info exists gdb_stub] {
    gdb_step_for_stub;
}
#
# test simple breakpoint setting commands
#

# Test deleting all breakpoints when there are none installed,
# GDB should not prompt for confirmation.
# Note that gdb-init.exp provides a "delete_breakpoints" proc
# for general use elsewhere.

send_gdb "delete breakpoints\n"
gdb_expect {
     -re "Delete all breakpoints.*$" {
	    send_gdb "y\n"
	    gdb_expect {
		-re "$gdb_prompt $" {
		    fail "Delete all breakpoints when none (unexpected prompt)"
		}
		timeout	{ fail "Delete all breakpoints when none (timeout after unexpected prompt)" }
	    }
	}
     -re ".*$gdb_prompt $"       { pass "Delete all breakpoints when none" }
    timeout	            { fail "Delete all breakpoints when none (timeout)" }
}

#
# test break at function
#
gdb_test "break main" \
    "Breakpoint.*at.* file .*$srcfile, line.*" \
    "breakpoint function"

#
# test break at quoted function
#
gdb_test "break \"marker2\"" \
    "Breakpoint.*at.* file .*$srcfile, line.*" \
    "breakpoint quoted function"

#
# test break at function in file
#
gdb_test "break $srcfile:factorial" \
    "Breakpoint.*at.* file .*$srcfile, line.*" \
    "breakpoint function in file"

#old line 79
set bp_location1 [gdb_get_line_number "set breakpoint 1 here"]

#
# test break at line number
#
# Note that the default source file is the last one whose source text
# was printed.  For native debugging, before we've executed the
# program, this is the file containing main, but for remote debugging,
# it's wherever the processor was stopped when we connected to the
# board.  So, to be sure, we do a list command.
#
gdb_test "list main" \
    ".*main \\(argc, argv, envp\\).*" \
    "use `list' to establish default source file"
gdb_test "break $bp_location1" \
    "Breakpoint.*at.* file .*$srcfile, line $bp_location1\\." \
    "breakpoint line number"

#
# test duplicate breakpoint
#
gdb_test "break $bp_location1" \
    "Note: breakpoint \[0-9\]+ also set at pc.*Breakpoint \[0-9\]+ at.* file .*$srcfile, line $bp_location1\\." \
    "breakpoint duplicate"

set bp_location2 [gdb_get_line_number "set breakpoint 2 here"]

#
# test break at line number in file
#
gdb_test "break $srcfile:$bp_location2" \
    "Breakpoint.*at.* file .*$srcfile, line $bp_location2\\." \
    "breakpoint line number in file"

set bp_location3 [gdb_get_line_number "set breakpoint 3 here"]
set bp_location4 [gdb_get_line_number "set breakpoint 4 here"]

#
# Test putting a break at the start of a multi-line if conditional.
# Verify the breakpoint was put at the start of the conditional.
#
gdb_test "break multi_line_if_conditional" \
    "Breakpoint.*at.* file .*$srcfile, line $bp_location3\\." \
    "breakpoint at start of multi line if conditional"

gdb_test "break multi_line_while_conditional" \
    "Breakpoint.*at.* file .*$srcfile, line $bp_location4\\." \
    "breakpoint at start of multi line while conditional"

set bp_location5 [gdb_get_line_number "set breakpoint 5 here"]
set bp_location6 [gdb_get_line_number "set breakpoint 6 here"]

#
# check to see what breakpoints are set
#
if [target_info exists gdb_stub] {
    set main_line $bp_location5
} else {
    set main_line $bp_location6
}

set bp_location7 [gdb_get_line_number "set breakpoint 7 here"]
set bp_location8 [gdb_get_line_number "set breakpoint 8 here"]
set bp_location9 [gdb_get_line_number "set breakpoint 9 here"]

gdb_test "info break" \
    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$main_line.*
\[0-9\]+\[\t \]+breakpoint     keep y.* in marker2 at .*$srcfile:($bp_location8|$bp_location9).*
\[0-9\]+\[\t \]+breakpoint     keep y.* in factorial at .*$srcfile:$bp_location7.*
\[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$bp_location1.*
\[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$bp_location1.*
\[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$bp_location2.*
\[0-9\]+\[\t \]+breakpoint     keep y.* in multi_line_if_conditional at .*$srcfile:$bp_location3.*
\[0-9\]+\[\t \]+breakpoint     keep y.* in multi_line_while_conditional at .*$srcfile:$bp_location4" \
    "breakpoint info"

# FIXME: The rest of this test doesn't work with anything that can't
# handle arguments.
# Huh? There doesn't *appear* to be anything that passes arguments
# below.
if [istarget "mips-idt-*"] then {
    return
}

#
# run until the breakpoint at main is hit. For non-stubs-using targets.
#
if ![target_info exists use_gdb_stub] {
  if [istarget "*-*-vxworks*"] then {
    send_gdb "run vxmain \"2\"\n"
    set timeout 120
    verbose "Timeout is now $timeout seconds" 2
  } else {
	send_gdb "run\n"
  }
  gdb_expect {
    -re "The program .* has been started already.*y or n. $" {
	send_gdb "y\n"
	exp_continue
    }
    -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $"\
	                    { pass "run until function breakpoint" }
    -re ".*$gdb_prompt $"       { fail "run until function breakpoint" }
    timeout	            { fail "run until function breakpoint (timeout)" }
  }
} else {
    if ![target_info exists gdb_stub] {
	gdb_test continue ".*Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.*\{.*" "stub continue"
    }
}

#
# run until the breakpoint at a line number
#
gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location1.*$bp_location1\[\t \]+printf.*factorial.*" \
			"run until breakpoint set at a line number"

#
# Run until the breakpoint set in a function in a file
#
for {set i 6} {$i >= 1} {incr i -1} {
	gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, factorial \\(value=$i\\) at .*$srcfile:$bp_location7.*$bp_location7\[\t \]+.*if .value > 1. \{.*" \
			"run until file:function($i) breakpoint"
}

#
# Run until the breakpoint set at a quoted function
#
gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, (0x\[0-9a-f\]+ in )?marker2 \\(a=43\\) at .*$srcfile:($bp_location8|$bp_location9).*" \
		"run until quoted breakpoint"
#
# run until the file:function breakpoint at a line number in a file
#
gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location2.*$bp_location2\[\t \]+argc = \\(argc == 12345\\);.*" \
		"run until file:linenum breakpoint"

# Test break at offset +1
set bp_location10 [gdb_get_line_number "set breakpoint 10 here"]

gdb_test "break +1" \
    "Breakpoint.*at.* file .*$srcfile, line $bp_location10\\." \
    "breakpoint offset +1"

# Check to see if breakpoint is hit when stepped onto

gdb_test "step" \
    ".*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location10.*$bp_location10\[\t \]+return argc;.*breakpoint 10 here.*" \
    "step onto breakpoint"

#
# delete all breakpoints so we can start over, course this can be a test too
#
delete_breakpoints

#
# test temporary breakpoint at function
#

gdb_test "tbreak main" "Breakpoint.*at.* file .*$srcfile, line.*" "Temporary breakpoint function"

#
# test break at function in file
#

gdb_test "tbreak $srcfile:factorial" "Breakpoint.*at.* file .*$srcfile, line.*" \
	"Temporary breakpoint function in file"

#
# test break at line number
#
send_gdb "tbreak $bp_location1\n"
gdb_expect {
    -re "Breakpoint.*at.* file .*$srcfile, line $bp_location1.*$gdb_prompt $" { pass "Temporary breakpoint line number #1" }
	-re ".*$gdb_prompt $"   { pass "Temporary breakpoint line number #1" }
	timeout	    { fail "breakpoint line number #1 (timeout)" }
}

gdb_test "tbreak $bp_location6" "Breakpoint.*at.* file .*$srcfile, line $bp_location6.*" "Temporary breakpoint line number #2"

#
# test break at line number in file
#
send_gdb "tbreak $srcfile:$bp_location2\n"
gdb_expect {
    -re "Breakpoint.*at.* file .*$srcfile, line $bp_location2.*$gdb_prompt $" { pass "Temporary breakpoint line number in file #1" }
	-re ".*$gdb_prompt $"   { pass "Temporary breakpoint line number in file #1" }
	timeout	    { fail "Temporary breakpoint line number in file #1 (timeout)" }
}

set bp_location11 [gdb_get_line_number "set breakpoint 11 here"]
gdb_test  "tbreak $srcfile:$bp_location11" "Breakpoint.*at.* file .*$srcfile, line $bp_location11.*" "Temporary breakpoint line number in file #2"

#
# check to see what breakpoints are set (temporary this time)
#
gdb_test "info break" "Num Type.*Disp Enb Address.*What.*\[\r\n\]
\[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$main_line.*\[\r\n\]
\[0-9\]+\[\t \]+breakpoint     del.*y.*in factorial at .*$srcfile:$bp_location7.*\[\r\n\]
\[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$bp_location1.*\[\r\n\]
\[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$bp_location6.*\[\r\n\]
\[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$bp_location2.*\[\r\n\]
\[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$bp_location11.*" \
    "Temporary breakpoint info"


#***********

# Verify that catchpoints for fork, vfork and exec don't trigger
# inappropriately.  (There are no calls to those system functions
# in this test program.)
#
if ![runto_main] then { fail "break tests suppressed" }

send_gdb "catch\n"
gdb_expect {
  -re "Catch requires an event name.*$gdb_prompt $"\
          {pass "catch requires an event name"}
  -re "$gdb_prompt $"\
          {fail "catch requires an event name"}
  timeout {fail "(timeout) catch requires an event name"}
}


set name "set catch fork, never expected to trigger"
send_gdb "catch fork\n"
gdb_expect {
  -re "Catchpoint \[0-9\]* .fork..*$gdb_prompt $"
          {pass $name}
  -re "Catch of fork not yet implemented.*$gdb_prompt $"
	  {pass $name}
  -re "$gdb_prompt $"
          {fail $name}
  timeout {fail "(timeout) $name"}
}


set name "set catch vfork, never expected to trigger"
send_gdb "catch vfork\n"

# If we are on HP-UX 10.20, we expect an error message to be
# printed if we type "catch vfork" at the gdb gdb_prompt.  This is
# because on HP-UX 10.20, we cannot catch vfork events.

if [istarget "hppa*-hp-hpux10.20"] then {
    gdb_expect {
	-re "Catch of vfork events not supported on HP-UX 10.20..*$gdb_prompt $"
		{pass $name}
	-re "$gdb_prompt $"
		{fail $name}
	timeout {fail "(timeout) $name"}
    }
} else {
    gdb_expect {
	-re "Catchpoint \[0-9\]* .vfork..*$gdb_prompt $"
		{pass $name}
	-re "Catch of vfork not yet implemented.*$gdb_prompt $"
		{pass $name}
	-re "$gdb_prompt $"
		{fail $name}
	timeout {fail "(timeout) $name"}
    }
}

set name "set catch exec, never expected to trigger"
send_gdb "catch exec\n"
gdb_expect {
  -re "Catchpoint \[0-9\]* .exec..*$gdb_prompt $"
          {pass $name}
  -re "Catch of exec not yet implemented.*$gdb_prompt $"
	  {pass $name}
  -re "$gdb_prompt $" {fail $name}
  timeout {fail "(timeout) $name"}
}

# Verify that GDB responds gracefully when asked to set a breakpoint
# on a nonexistent source line.
#
send_gdb "break 999\n"
gdb_expect {
  -re "No line 999 in file .*$gdb_prompt $"\
          {pass "break on non-existent source line"}
  -re "$gdb_prompt $"\
          {fail "break on non-existent source line"}
  timeout {fail "(timeout) break on non-existent source line"}
}

# Run to the desired default location. If not positioned here, the
# tests below don't work.
#
gdb_test "until $bp_location1" "main .* at .*:$bp_location1.*" "until $bp_location1"


# Verify that GDB allows one to just say "break", which is treated
# as the "default" breakpoint.  Note that GDB gets cute when printing
# the informational message about other breakpoints at the same
# location.  We'll hit that bird with this stone too.
#
send_gdb "break\n"
gdb_expect {
  -re "Breakpoint \[0-9\]*.*$gdb_prompt $"\
          {pass "break on default location, 1st time"}
  -re "$gdb_prompt $"\
          {fail "break on default location, 1st time"}
  timeout {fail "(timeout) break on default location, 1st time"}
}

send_gdb "break\n"
gdb_expect {
  -re "Note: breakpoint \[0-9\]* also set at .*Breakpoint \[0-9\]*.*$gdb_prompt $"\
          {pass "break on default location, 2nd time"}
  -re "$gdb_prompt $"\
          {fail "break on default location, 2nd time"}
  timeout {fail "(timeout) break on default location, 2nd time"}
}

send_gdb "break\n"
gdb_expect {
  -re "Note: breakpoints \[0-9\]* and \[0-9\]* also set at .*Breakpoint \[0-9\]*.*$gdb_prompt $"\
          {pass "break on default location, 3rd time"}
  -re "$gdb_prompt $"\
          {fail "break on default location, 3rd time"}
  timeout {fail "(timeout) break on default location, 3rd time"}
}

send_gdb "break\n"
gdb_expect {
  -re "Note: breakpoints \[0-9\]*, \[0-9\]* and \[0-9\]* also set at .*Breakpoint \[0-9\]*.*$gdb_prompt $"\
          {pass "break on default location, 4th time"}
  -re "$gdb_prompt $"\
          {fail "break on default location, 4th time"}
  timeout {fail "(timeout) break on default location, 4th time"}
}

# Verify that a "silent" breakpoint can be set, and that GDB is indeed
# "silent" about its triggering.
#
if ![runto_main] then { fail "break tests suppressed" }

send_gdb "break $bp_location1\n"
gdb_expect {
  -re "Breakpoint (\[0-9\]*) at .*, line $bp_location1.*$gdb_prompt $"\
          {pass "set to-be-silent break $bp_location1"}
  -re "$gdb_prompt $"\
          {fail "set to-be-silent break $bp_location1"}
  timeout {fail "(timeout) set to-be-silent break $bp_location1"}
}

send_gdb "commands $expect_out(1,string)\n"
send_gdb "silent\n"
send_gdb "end\n"
gdb_expect {
  -re ".*$gdb_prompt $"\
          {pass "set silent break $bp_location1"}
  timeout {fail "(timeout) set silent break $bp_location1"}
}

send_gdb "info break $expect_out(1,string)\n"
gdb_expect {
  -re "\[0-9\]*\[ \t\]*breakpoint.*:$bp_location1\r\n\[ \t\]*silent.*$gdb_prompt $"\
          {pass "info silent break $bp_location1"}
  -re "$gdb_prompt $"\
          {fail "info silent break $bp_location1"}
  timeout {fail "(timeout) info silent break $bp_location1"}
}
send_gdb "continue\n"
gdb_expect {
  -re "Continuing.\r\n$gdb_prompt $"\
          {pass "hit silent break $bp_location1"}
  -re "$gdb_prompt $"\
          {fail "hit silent break $bp_location1"}
  timeout {fail "(timeout) hit silent break $bp_location1"}
}
send_gdb "bt\n"
gdb_expect {
  -re "#0  main .* at .*:$bp_location1.*$gdb_prompt $"\
          {pass "stopped for silent break $bp_location1"}
  -re "$gdb_prompt $"\
          {fail "stopped for silent break $bp_location1"}
  timeout {fail "(timeout) stopped for silent break $bp_location1"}
}

# Verify that GDB can at least parse a breakpoint with the
# "thread" keyword.  (We won't attempt to test here that a
# thread-specific breakpoint really triggers appropriately.
# The gdb.threads subdirectory contains tests for that.)
#
set bp_location12 [gdb_get_line_number "set breakpoint 12 here"]
send_gdb "break $bp_location12 thread 999\n"
gdb_expect {
  -re "Unknown thread 999.*$gdb_prompt $"\
          {pass "thread-specific breakpoint on non-existent thread disallowed"}
  -re "$gdb_prompt $"\
          {fail "thread-specific breakpoint on non-existent thread disallowed"}
  timeout {fail "(timeout) thread-specific breakpoint on non-existent thread disallowed"}
}
send_gdb "break $bp_location12 thread foo\n"
gdb_expect {
  -re "Junk after thread keyword..*$gdb_prompt $"\
          {pass "thread-specific breakpoint on bogus thread ID disallowed"}
  -re "$gdb_prompt $"\
          {fail "thread-specific breakpoint on bogus thread ID disallowed"}
  timeout {fail "(timeout) thread-specific breakpoint on bogus thread ID disallowed"}
}

# Verify that GDB responds gracefully to a breakpoint command with
# trailing garbage.
#
send_gdb "break $bp_location12 foo\n"
gdb_expect {
  -re "Junk at end of arguments..*$gdb_prompt $"\
          {pass "breakpoint with trailing garbage disallowed"}
  -re "$gdb_prompt $"\
          {fail "breakpoint with trailing garbage disallowed"}
  timeout {fail "(timeout) breakpoint with trailing garbage disallowed"}
}

# Verify that GDB responds gracefully to a "clear" command that has
# no matching breakpoint.  (First, get us off the current source line,
# which we know has a breakpoint.)
#
send_gdb "next\n"
gdb_expect {
  -re ".*$gdb_prompt $"\
          {pass "step over breakpoint"}
  timeout {fail "(timeout) step over breakpoint"}
}
send_gdb "clear 81\n"
gdb_expect {
  -re "No breakpoint at 81..*$gdb_prompt $"\
          {pass "clear line has no breakpoint disallowed"}
  -re "$gdb_prompt $"\
          {fail "clear line has no breakpoint disallowed"}
  timeout {fail "(timeout) clear line has no breakpoint disallowed"}
}
send_gdb "clear\n"
gdb_expect {
  -re "No breakpoint at this line..*$gdb_prompt $"\
          {pass "clear current line has no breakpoint disallowed"}
  -re "$gdb_prompt $"\
          {fail "clear current line has no breakpoint disallowed"}
  timeout {fail "(timeout) clear current line has no breakpoint disallowed"}
}

# Verify that we can set and clear multiple breakpoints.
#
# We don't test that it deletes the correct breakpoints.  We do at
# least test that it deletes more than one breakpoint.
#
gdb_test "break marker3" "Breakpoint.*at.*" "break marker3 #1"
gdb_test "break marker3" "Breakpoint.*at.*" "break marker3 #2"
gdb_test "clear marker3" {Deleted breakpoints [0-9]+ [0-9]+.*}

# Verify that a breakpoint can be set via a convenience variable.
#
send_gdb "set \$foo=$bp_location11\n"
gdb_expect {
  -re "$gdb_prompt $"\
          {pass "set convenience variable \$foo to $bp_location11"}
  timeout {fail "(timeout) set convenience variable \$foo to $bp_location11"}
}
send_gdb "break \$foo\n"
gdb_expect {
  -re "Breakpoint (\[0-9\]*) at .*, line $bp_location11.*$gdb_prompt $"\
          {pass "set breakpoint via convenience variable"}
  -re "$gdb_prompt $"\
          {fail "set breakpoint via convenience variable"}
  timeout {fail "(timeout) set breakpoint via convenience variable"}
}

# Verify that GDB responds gracefully to an attempt to set a
# breakpoint via a convenience variable whose type is not integer.
#
send_gdb "set \$foo=81.5\n"
gdb_expect {
  -re "$gdb_prompt $"\
          {pass "set convenience variable \$foo to 81.5"}
  timeout {fail "(timeout) set convenience variable \$foo to 81.5"}
}
send_gdb "break \$foo\n"
gdb_expect {
  -re "Convenience variables used in line specs must have integer values..*$gdb_prompt $"\
          {pass "set breakpoint via non-integer convenience variable disallowed"}
  -re "$gdb_prompt $"\
          {fail "set breakpoint via non-integer convenience variable disallowed"}
  timeout {fail "(timeout) set breakpoint via non-integer convenience variable disallowed"}
}

# Verify that we can set and trigger a breakpoint in a user-called function.
#
send_gdb "break marker2\n"
gdb_expect {
    -re "Breakpoint (\[0-9\]*) at .*, line ($bp_location8|$bp_location9).*$gdb_prompt $"\
          {pass "set breakpoint on to-be-called function"}
  -re "$gdb_prompt $"\
          {fail "set breakpoint on to-be-called function"}
  timeout {fail "(timeout) set breakpoint on to-be-called function"}
}
send_gdb "print marker2(99)\n"
gdb_expect {
  -re "The program being debugged stopped while in a function called from GDB.\r\nWhen the function .marker2. is done executing, GDB will silently\r\nstop .instead of continuing to evaluate the expression containing\r\nthe function call...*$gdb_prompt $"\
          {pass "hit breakpoint on called function"}
  -re "$gdb_prompt $"\
          {fail "hit breakpoint on called function"}
  timeout {fail "(timeout) hit breakpoint on called function"}
}

# As long as we're stopped (breakpointed) in a called function,
# verify that we can successfully backtrace & such from here.
#
# In this and the following test, the _sr4export check apparently is needed
# for hppa*-*-hpux.
#
send_gdb "bt\n"
gdb_expect {
    -re "#0\[ \t\]*($hex in )?marker2.*:($bp_location8|$bp_location9)\r\n#1.*_sr4export.*$gdb_prompt $"\
            {pass "backtrace while in called function"}
    -re "#0\[ \t\]*($hex in )?marker2.*:($bp_location8|$bp_location9)\r\n#1.*function called from gdb.*$gdb_prompt $"\
	    {pass "backtrace while in called function"}
    -re "$gdb_prompt $"\
            {fail "backtrace while in called function"}
    timeout {fail "(timeout) backtrace while in called function"}
}

# Return from the called function.  For remote targets, it's important to do
# this before runto_main, which otherwise may silently stop on the dummy
# breakpoint inserted by GDB at the program's entry point.
#
send_gdb "finish\n"
gdb_expect {
    -re "Run till exit from .*marker2.* at .*($bp_location8|$bp_location9)\r\n.* in _sr4export.*$gdb_prompt $"\
            {pass "finish from called function"}
    -re "Run till exit from .*marker2.* at .*($bp_location8|$bp_location9)\r\n.*function called from gdb.*$gdb_prompt $"\
            {pass "finish from called function"}
    -re "Run till exit from .*marker2.* at .*($bp_location8|$bp_location9)\r\n.*Value returned.*$gdb_prompt $"\
            {pass "finish from called function"}
    -re "$gdb_prompt $"\
            {fail "finish from called function"}
    timeout {fail "(timeout) finish from called function"}
}

# Verify that GDB responds gracefully to a "finish" command with
# arguments.
#
if ![runto_main] then { fail "break tests suppressed" }

send_gdb "finish 123\n"
gdb_expect {
  -re "The \"finish\" command does not take any arguments.\r\n$gdb_prompt $"\
          {pass "finish with arguments disallowed"}
  -re "$gdb_prompt $"\
          {fail "finish with arguments disallowed"}
  timeout {fail "(timeout) finish with arguments disallowed"}
}

# Verify that GDB responds gracefully to a request to "finish" from
# the outermost frame.  On a stub that never exits, this will just
# run to the stubs routine, so we don't get this error...  Thus the 
# second condition.
#

send_gdb "finish\n"
gdb_expect {
  -re "\"finish\" not meaningful in the outermost frame.\r\n$gdb_prompt $"\
          {pass "finish from outermost frame disallowed"}
  -re "Run till exit from.*\r\n$gdb_prompt $" {
     pass "finish from outermost frame disallowed"
  }
  -re "$gdb_prompt $"\
          {fail "finish from outermost frame disallowed"}
  timeout {fail "(timeout) finish from outermost frame disallowed"}
}

# Verify that we can explicitly ask GDB to stop on all shared library
# events, and that it does so.
#
if [istarget "hppa*-*-hpux*"] then {
  if ![runto_main] then { fail "break tests suppressed" }

  send_gdb "set stop-on-solib-events 1\n"
  gdb_expect {
    -re "$gdb_prompt $"\
            {pass "set stop-on-solib-events"}
    timeout {fail "(timeout) set stop-on-solib-events"}
  }

  send_gdb "run\n"
  gdb_expect {
    -re ".*Start it from the beginning.*y or n. $"\
            {send_gdb "y\n"
             gdb_expect {
               -re ".*Stopped due to shared library event.*$gdb_prompt $"\
                       {pass "triggered stop-on-solib-events"}
               -re "$gdb_prompt $"\
                       {fail "triggered stop-on-solib-events"}
               timeout {fail "(timeout) triggered stop-on-solib-events"}
             }
            }
    -re "$gdb_prompt $"\
            {fail "rerun for stop-on-solib-events"}
    timeout {fail "(timeout) rerun for stop-on-solib-events"}
  }

  send_gdb "set stop-on-solib-events 0\n"
  gdb_expect {
    -re "$gdb_prompt $"\
            {pass "reset stop-on-solib-events"}
    timeout {fail "(timeout) reset stop-on-solib-events"}
  }
}

# Hardware breakpoints are unsupported on HP-UX.  Verify that GDB
# gracefully responds to requests to create them.
#
if [istarget "hppa*-*-hpux*"] then {
  if ![runto_main] then { fail "break tests suppressed" }

  send_gdb "hbreak\n"
  gdb_expect {
    -re "No hardware breakpoint support in the target.*$gdb_prompt $"\
            {pass "hw breaks disallowed"}
    -re "$gdb_prompt $"\
            {fail "hw breaks disallowed"}
    timeout {fail "(timeout) hw breaks disallowed"}
  }

  send_gdb "thbreak\n"
  gdb_expect {
    -re "No hardware breakpoint support in the target.*$gdb_prompt $"\
            {pass "temporary hw breaks disallowed"}
    -re "$gdb_prompt $"\
            {fail "temporary hw breaks disallowed"}
    timeout {fail "(timeout) temporary hw breaks disallowed"}
  }
}

#********


#
# Test "next" over recursive function call.
#

proc test_next_with_recursion {} { 
    global gdb_prompt
    global decimal
    global binfile

    if [target_info exists use_gdb_stub] {
	# Reload the program.
	delete_breakpoints
	gdb_load ${binfile};
    } else {
	# FIXME: should be using runto
	gdb_test "kill" "" "kill program" "Kill the program being debugged.*y or n. $" "y"

	delete_breakpoints
    }

    gdb_test "break factorial" "Breakpoint $decimal at .*" "break at factorial"

    # Run until we call factorial with 6

    if [istarget "*-*-vxworks*"] then {
	send_gdb "run vxmain \"6\"\n"
    } else {
	gdb_run_cmd
    }
    gdb_expect {
	-re "Break.* factorial .value=6. .*$gdb_prompt $" {}
	-re ".*$gdb_prompt $" {
	    fail "run to factorial(6)";
	    gdb_suppress_tests;
	}
	timeout { fail "run to factorial(6) (timeout)" ; gdb_suppress_tests }
    }

    # Continue until we call factorial recursively with 5.

    if [gdb_test "continue" \
	"Continuing.*Break.* factorial .value=5. .*" \
	"continue to factorial(5)"] then { gdb_suppress_tests }

    # Do a backtrace just to confirm how many levels deep we are.

    if [gdb_test "backtrace" \
	"#0\[ \t\]+ factorial .value=5..*" \
	"backtrace from factorial(5)"] then { gdb_suppress_tests }

    # Now a "next" should position us at the recursive call, which
    # we will be performing with 4.

    if [gdb_test "next" \
	".* factorial .value - 1.;.*" \
	"next to recursive call"] then { gdb_suppress_tests }

    # Disable the breakpoint at the entry to factorial by deleting them all.
    # The "next" should run until we return to the next line from this
    # recursive call to factorial with 4.
    # Buggy versions of gdb will stop instead at the innermost frame on
    # the line where we are trying to "next" to.

    delete_breakpoints

    if [istarget "mips*tx39-*"] {
	set timeout 60
    }
    # We used to set timeout here for all other targets as well.  This
    # is almost certainly wrong.  The proper timeout depends on the
    # target system in use, and how we communicate with it, so there
    # is no single value appropriate for all targets.  The timeout
    # should be established by the Dejagnu config file(s) for the
    # board, and respected by the test suite.
    #
    # For example, if I'm running GDB over an SSH tunnel talking to a
    # portmaster in California talking to an ancient 68k board running
    # a crummy ROM monitor (a situation I can only wish were
    # hypothetical), then I need a large timeout.  But that's not the
    # kind of knowledge that belongs in this file.

    gdb_test next "\[0-9\]*\[\t \]+return \\(value\\);.*" \
	    "next over recursive call"

    # OK, we should be back in the same stack frame we started from.
    # Do a backtrace just to confirm.

    set result [gdb_test "backtrace" \
	    "#0\[ \t\]+ factorial .value=120.*\r\n#1\[ \t\]+ \[0-9a-fx\]+ in factorial .value=6..*" \
	    "backtrace from factorial(5.1)"]
    if { $result != 0 } { gdb_suppress_tests }

    if [target_info exists gdb,noresults] { gdb_suppress_tests }
  gdb_continue_to_end "recursive next test"
   gdb_stop_suppressing_tests;
}

test_next_with_recursion


#********

# now move the .debug file to a different location so that we can test
# the "set debug-file-directory" command.
  
remote_exec build "mv ${objdir}/${subdir}/.debug/${testfile}.debug ${objdir}/${subdir}"
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_test "set debug-file-directory ${objdir}/${subdir}" ".*" "set separate debug location"
gdb_load ${binfile}

if [target_info exists gdb_stub] {
    gdb_step_for_stub;
}

#
# test break at function
#
gdb_test "break main" \
    "Breakpoint.*at.* file .*$srcfile, line.*" \
    "breakpoint function, optimized file"

#
# test break at function
#
gdb_test "break marker4" \
    "Breakpoint.*at.* file .*$srcfile, line.*" \
    "breakpoint small function, optimized file"

#
# run until the breakpoint at main is hit. For non-stubs-using targets.
#
if ![target_info exists use_gdb_stub] {
  if [istarget "*-*-vxworks*"] then {
    send_gdb "run vxmain \"2\"\n"
    set timeout 120
    verbose "Timeout is now $timeout seconds" 2
  } else {
	send_gdb "run\n"
  }
  gdb_expect {
    -re "The program .* has been started already.*y or n. $" {
	send_gdb "y\n"
	exp_continue
    }
    -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $"\
	                    { pass "run until function breakpoint, optimized file" }
    -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $"\
	                    { pass "run until function breakpoint, optimized file (code motion)" }
    -re ".*$gdb_prompt $"       { fail "run until function breakpoint, optimized file" }
    timeout	            { fail "run until function breakpoint, optimized file (timeout)" }
  }
} else {
    if ![target_info exists gdb_stub] {
	gdb_test continue ".*Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.*\{.*" "stub continue, optimized file"
    }
}

#
# run until the breakpoint at a small function
#

#
# Add a second pass pattern.  The behavior differs here between stabs
# and dwarf for one-line functions.  Stabs preserves two line symbols
# (one before the prologue and one after) with the same line number, 
# but dwarf regards these as duplicates and discards one of them.
# Therefore the address after the prologue (where the breakpoint is)
# has no exactly matching line symbol, and GDB reports the breakpoint
# as if it were in the middle of a line rather than at the beginning.

set bp_location13 [gdb_get_line_number "set breakpoint 13 here"]
set bp_location14 [gdb_get_line_number "set breakpoint 14 here"]
send_gdb "continue\n"
gdb_expect {
    -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
	pass "run until breakpoint set at small function, optimized file"
    }
    -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
	pass "run until breakpoint set at small function, optimized file"
    }
    -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" {
        # marker4() is defined at line 46 when compiled with -DPROTOTYPES
	pass "run until breakpoint set at small function, optimized file (line $bp_location14)"
    }
    -re ".*$gdb_prompt " {
	fail "run until breakpoint set at small function, optimized file"
    }
    timeout {
	fail "run until breakpoint set at small function, optimized file (timeout)"
    }
}


# Reset the default arguments for VxWorks
if [istarget "*-*-vxworks*"] {
    set timeout 10
    verbose "Timeout is now $timeout seconds" 2
    send_gdb "set args main\n"
    gdb_expect -re ".*$gdb_prompt $" {}
}


sepdebug.c
-----------------------
/* Copyright 1994, 1995, 1999, 2002, 2003  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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  

   Please email any bugs, comments, and/or additions to this file to:
   bug-gdb@prep.ai.mit.edu  */

#ifdef vxworks

#  include <stdio.h>

/* VxWorks does not supply atoi.  */
static int
atoi (z)
     char *z;
{
  int i = 0;

  while (*z >= '0' && *z <= '9')
    i = i * 10 + (*z++ - '0');
  return i;
}

/* I don't know of any way to pass an array to VxWorks.  This function
   can be called directly from gdb.  */

vxmain (arg)
char *arg;
{
  char *argv[2];

  argv[0] = "";
  argv[1] = arg;
  main (2, argv, (char **) 0);
}

#else /* ! vxworks */
#  include <stdio.h>
#  include <stdlib.h>
#endif /* ! vxworks */

/*
 * The following functions do nothing useful.  They are included simply
 * as places to try setting breakpoints at.  They are explicitly
 * "one-line functions" to verify that this case works (some versions
 * of gcc have or have had problems with this).
 */

#ifdef PROTOTYPES
int marker1 (void) { return (0); }
int marker2 (int a) { return (1); } /* set breakpoint 8 here */
void marker3 (char *a, char *b) {}
void marker4 (long d) {} /* set breakpoint 14 here */
#else
int marker1 () { return (0); }
int marker2 (a) int a; { return (1); } /* set breakpoint 9 here */
void marker3 (a, b) char *a, *b; {}
void marker4 (d) long d; {}  /* set breakpoint 13 here */
#endif

/*
 *	This simple classical example of recursion is useful for
 *	testing stack backtraces and such.
 */

#ifdef PROTOTYPES
int factorial(int);

int
main (int argc, char **argv, char **envp)
#else
int
main (argc, argv, envp)
int argc;
char *argv[], **envp;
#endif
{
#ifdef usestubs
    set_debug_traps();  /* set breakpoint 5 here */
    breakpoint();
#endif
    if (argc == 12345) {  /* an unlikely value < 2^16, in case uninited */ /* set breakpoint 6 here */
	fprintf (stderr, "usage:  factorial <number>\n");
	return 1;
    }
    printf ("%d\n", factorial (atoi ("6")));  /* set breakpoint 1 here */
    /* set breakpoint 12 here */
    marker1 ();  /* set breakpoint 11 here */
    marker2 (43);
    marker3 ("stack", "trace");
    marker4 (177601976L);
    argc = (argc == 12345); /* This is silly, but we can step off of it */ /* set breakpoint 2 here */
    return argc;  /* set breakpoint 10 here */
}

#ifdef PROTOTYPES
int factorial (int value)
#else
int factorial (value)
int value;
#endif
{
  if (value > 1) {  /* set breakpoint 7 here */
	value *= factorial (value - 1);
    }
    return (value);
}

#ifdef PROTOTYPES
int multi_line_if_conditional (int a, int b, int c)
#else
int multi_line_if_conditional (a, b, c)
  int a, b, c;
#endif
{
  if (a    /* set breakpoint 3 here */
      && b
      && c)
    return 0;
  else
    return 1;
}

#ifdef PROTOTYPES
int multi_line_while_conditional (int a, int b, int c)
#else
int multi_line_while_conditional (a, b, c)
  int a, b, c;
#endif
{
  while (a /* set breakpoint 4 here */
      && b
      && c)
    {
      a--, b--, c--;
    }
  return 0;
}


^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2004-01-16 22:41 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-01-13  5:19 [RFA] new test for separate debug info Michael Elizabeth Chastain
2004-01-13 17:18 ` Elena Zannoni
  -- strict thread matches above, loose matches on Subject: below --
2004-01-14  2:47 Michael Elizabeth Chastain
2004-01-14 15:09 ` Elena Zannoni
2004-01-13 22:24 Michael Elizabeth Chastain
2004-01-13 23:37 ` Elena Zannoni
2004-01-13  2:28 Michael Elizabeth Chastain
2004-01-13  4:49 ` Elena Zannoni
2003-11-14 19:37 Michael Elizabeth Chastain
2003-11-14 20:09 ` Elena Zannoni
2004-01-12 17:20   ` Elena Zannoni
2004-01-12 22:01     ` Andrew Cagney
2004-01-12 22:28       ` Daniel Jacobowitz
2004-01-12 23:11         ` Elena Zannoni
2004-01-12 23:20           ` Daniel Jacobowitz
2004-01-13  3:12           ` Ian Lance Taylor
2004-01-16 19:55         ` Andrew Cagney
2004-01-16 22:41           ` Daniel Jacobowitz
2003-11-14 15:18 Michael Elizabeth Chastain
2003-11-14 15:52 ` Elena Zannoni
2003-11-14  5:14 Michael Elizabeth Chastain
2003-11-14 14:30 ` Elena Zannoni
2003-11-14  4:57 Michael Elizabeth Chastain
2003-11-14 14:32 ` Elena Zannoni
2003-11-13 17:55 Michael Elizabeth Chastain
2003-11-13 19:23 ` Elena Zannoni
2003-11-13 20:08 ` Elena Zannoni
2003-11-13 23:15 ` Elena Zannoni
2003-11-14  4:22   ` Daniel Jacobowitz
2003-11-14 14:34     ` Elena Zannoni
2003-11-13 16:49 Michael Elizabeth Chastain
2003-11-12 22:13 Elena Zannoni
2003-11-12 22:29 ` Daniel Jacobowitz
2003-11-13 16:18   ` Andrew Cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox