]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/testsuite/gdb.base/catch-syscall.exp
Skip catch-syscall.exp on HP-UX target
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.base / catch-syscall.exp
index ee385adcd31b90ab85b98b9a405985f140c51af4..b8cc1698ef7657194beb3d6c3f3d057ed704994d 100644 (file)
@@ -1,4 +1,4 @@
-#   Copyright 1997, 1999, 2007, 2008, 2010 Free Software Foundation, Inc.
+#   Copyright 1997-2015 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
@@ -23,48 +23,38 @@ if { [is_remote target] || ![isnative] } then {
     continue
 }
 
-set prms_id 0
-set bug_id 0
+# This shall be updated whenever 'catch syscall' is implemented
+# on some architecture.
+if { ![istarget "x86_64-*-linux*"] && ![istarget "i\[34567\]86-*-linux*"]
+     && ![istarget "powerpc-*-linux*"] && ![istarget "powerpc64-*-linux*"]
+     && ![istarget "sparc-*-linux*"] && ![istarget "sparc64-*-linux*"]
+     && ![istarget "mips*-linux*"] && ![istarget "arm*-linux*"]
+     && ![istarget "s390*-linux*"] } {
+     continue
+}
 
-global srcfile
-set testfile "catch-syscall"
-set srcfile ${testfile}.c
-set binfile ${objdir}/${subdir}/${testfile}
+standard_testfile
+
+if  { [prepare_for_testing ${testfile}.exp $testfile ${testfile}.c] } {
+     untested catch-syscall.exp
+     return -1
+}
 
 # All (but the last) syscalls from the example code
 # They are ordered according to the file, so do not change this.
-set all_syscalls { "close" "chroot" }
+set all_syscalls { "close" "chroot" "pipe" "write" "read" }
 set all_syscalls_numbers { }
+
 # The last syscall (exit()) does not return, so
 # we cannot expect the catchpoint to be triggered
 # twice.  It is a special case.
 set last_syscall "exit_group"
-
-if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
-     untested catch-syscall.exp
-     return -1
-}
-
-# Until "catch syscall" is implemented on other targets...
-if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then {
-    continue
-}
-
-# This shall be updated whenever 'catch syscall' is implemented
-# on some architecture.
-#if { ![istarget "i\[34567\]86-*-linux*"]
-if { ![istarget "x86_64-*-linux*"] && ![istarget "i\[34567\]86-*-linux*"]
-     && ![istarget "powerpc-*-linux*"] && ![istarget "powerpc64-*-linux*"]
-     && ![istarget "sparc-*-linux*"] && ![istarget "sparc64-*-linux*"] } {
-     continue
-}
+set last_syscall_number { }
 
 # Internal procedure used to check if, after issuing a 'catch syscall'
 # command (without arguments), the 'info breakpoints' command displays
 # that '"any syscall"' is to be caught.
 proc check_info_bp_any_syscall {} {
-    global gdb_prompt
-
     # Verifying that the catchpoint appears in the 'info breakpoints'
     # command, but with "<any syscall>".
     set thistest "catch syscall appears in 'info breakpoints'"
@@ -75,8 +65,6 @@ proc check_info_bp_any_syscall {} {
 # command (with arguments), the 'info breakpoints' command displays
 # that the syscall 'X' is to be caught.
 proc check_info_bp_specific_syscall { syscall } {
-    global gdb_prompt
-
     set thistest "syscall(s) $syscall appears in 'info breakpoints'"
     gdb_test "info breakpoints" ".*catchpoint.*keep y.*syscall(\[(\]s\[)\])? (.)?${syscall}(.)?.*" $thistest
 }
@@ -85,7 +73,6 @@ proc check_info_bp_specific_syscall { syscall } {
 # command (with many arguments), the 'info breakpoints' command displays
 # that the syscalls 'X' are to be caught.
 proc check_info_bp_many_syscalls { syscalls } {
-    global gdb_prompt
     set filter_str ""
 
     foreach name $syscalls {
@@ -100,25 +87,23 @@ proc check_info_bp_many_syscalls { syscalls } {
 
 # This procedure checks if there was a call to a syscall.
 proc check_call_to_syscall { syscall } {
-    global gdb_prompt
+    global decimal
 
     set thistest "program has called $syscall"
-    gdb_test "continue" "Catchpoint .*(call to syscall .?${syscall}.?).*" $thistest
+    gdb_test "continue" "Catchpoint $decimal \\(call to syscall .?${syscall}.?\\).*" $thistest
 }
 
 # This procedure checks if the syscall returned.
 proc check_return_from_syscall { syscall } {
-    global gdb_prompt
+    global decimal
 
     set thistest "syscall $syscall has returned"
-    gdb_test "continue" "Catchpoint .*(returned from syscall (.)?${syscall}(.)?).*" $thistest
+    gdb_test "continue" "Catchpoint $decimal \\(returned from syscall ${syscall}\\).*" $thistest
 }
 
 # Internal procedure that performs two 'continue' commands and checks if
 # a syscall call AND return occur.
 proc check_continue { syscall } {
-    global gdb_prompt
-
     # Testing if the 'continue' stops at the
     # specified syscall_name.  If it does, then it should
     # first print that the infeior has called the syscall,
@@ -132,163 +117,161 @@ proc check_continue { syscall } {
 
 # Inserts a syscall catchpoint with an argument.
 proc insert_catch_syscall_with_arg { syscall } {
-    global gdb_prompt
+    global decimal
 
     # Trying to set the catchpoint
     set thistest "catch syscall with arguments ($syscall)"
-    gdb_test "catch syscall $syscall" "Catchpoint .*(syscall (.)?${syscall}(.)?( \[\[0-9\]+\])?).*" $thistest
+    gdb_test "catch syscall $syscall" "Catchpoint $decimal \\(syscall \'?${syscall}\'?( \[${decimal}\])?\\)" $thistest
 
     check_info_bp_specific_syscall $syscall
 }
 
 # Inserts a syscall catchpoint with many arguments.
 proc insert_catch_syscall_with_many_args { syscalls numbers } {
-    global gdb_prompt
+    global decimal
+
     set catch [ join $syscalls " " ]
     set filter_str ""
 
     foreach name $syscalls number $numbers {
-      set filter_str "${filter_str}'${name}' \[${number}\] "
+      set filter_str "${filter_str}'${name}' \\\[${number}\\\] "
     }
 
     set filter_str [ string trimright $filter_str " " ]
 
     # Trying to set the catchpoint
     set thistest "catch syscall with arguments ($filter_str)"
-    gdb_test "catch syscall $catch" "Catchpoint .*(syscalls (.)?${filter_str}(.)?).*" $thistest
+    gdb_test "catch syscall $catch" "Catchpoint $decimal \\(syscalls ${filter_str}\\).*" $thistest
 
     check_info_bp_many_syscalls $syscalls
 }
 
 proc check_for_program_end {} {
-    global gdb_prompt
-
     # Deleting the catchpoints
     delete_breakpoints
 
-    set thistest "successful program end"
-    gdb_test "continue" "Program exited normally.*" $thistest
-
+    gdb_continue_to_end
 }
 
 proc test_catch_syscall_without_args {} {
-    global gdb_prompt all_syscalls last_syscall
+    global all_syscalls last_syscall decimal
 
-    # Trying to set the syscall
-    set thistest "setting catch syscall without arguments"
-    gdb_test "catch syscall" "Catchpoint .*(syscall).*" $thistest
+    with_test_prefix "without arguments" {
+       # Trying to set the syscall.
+       gdb_test "catch syscall" "Catchpoint $decimal \\(any syscall\\)"
 
-    check_info_bp_any_syscall
+       check_info_bp_any_syscall
 
-    # We have to check every syscall
-    foreach name $all_syscalls {
-        check_continue $name
-    }
+       # We have to check every syscall.
+       foreach name $all_syscalls {
+           check_continue $name
+       }
 
-    # At last but not least, we check if the inferior
-    # has called the last (exit) syscall.
-    check_call_to_syscall $last_syscall
+       # At last but not least, we check if the inferior has called
+       # the last (exit) syscall.
+       check_call_to_syscall $last_syscall
 
-    # Now let's see if the inferior correctly finishes.
-    check_for_program_end
+       # Now let's see if the inferior correctly finishes.
+       check_for_program_end
+    }
 }
 
 proc test_catch_syscall_with_args {} {
-    global gdb_prompt
-    set syscall_name "close"
+    with_test_prefix "with arguments" {
+       set syscall_name "close"
+       insert_catch_syscall_with_arg $syscall_name
 
-    insert_catch_syscall_with_arg $syscall_name 
+       # Can we continue until we catch the syscall?
+       check_continue $syscall_name
 
-    # Can we continue until we catch the syscall?
-    check_continue $syscall_name
-
-    # Now let's see if the inferior correctly finishes.
-    check_for_program_end
+       # Now let's see if the inferior correctly finishes.
+       check_for_program_end
+    }
 }
 
 proc test_catch_syscall_with_many_args {} {
-    global gdb_prompt all_syscalls all_syscalls_numbers
+    with_test_prefix "with many arguments" {
+       global all_syscalls all_syscalls_numbers
 
-    insert_catch_syscall_with_many_args $all_syscalls $all_syscalls_numbers
+       insert_catch_syscall_with_many_args $all_syscalls $all_syscalls_numbers
 
-    # Can we continue until we catch the syscalls?
-    foreach name $all_syscalls {
-        check_continue $name
-    }
+       # Can we continue until we catch the syscalls?
+       foreach name $all_syscalls {
+           check_continue $name
+       }
 
-    # Now let's see if the inferior correctly finishes.
-    check_for_program_end
+       # Now let's see if the inferior correctly finishes.
+       check_for_program_end
+    }
 }
 
 proc test_catch_syscall_with_wrong_args {} {
-    global gdb_prompt
-    # mlock is not called from the source
-    set syscall_name "mlock"
-
-    insert_catch_syscall_with_arg $syscall_name
-
-    # Now, we must verify if the program stops with a continue.
-    # If it doesn't, everything is right (since we don't have
-    # a syscall named "mlock" in it).  Otherwise, this is a failure.
-    set thistest "catch syscall with unused syscall ($syscall_name)"
-    gdb_test "continue" "Program exited normally.*" $thistest
+    with_test_prefix "wrong args" {
+       # mlock is not called from the source
+       set syscall_name "mlock"
+       insert_catch_syscall_with_arg $syscall_name
+
+       # Now, we must verify if the program stops with a continue.
+       # If it doesn't, everything is right (since we don't have
+       # a syscall named "mlock" in it).  Otherwise, this is a failure.
+       set thistest "catch syscall with unused syscall ($syscall_name)"
+       gdb_continue_to_end $thistest
+    }
 }
 
 proc test_catch_syscall_restarting_inferior {} {
-    global gdb_prompt
-    set syscall_name "chroot"
+    with_test_prefix "restarting inferior" {
+       set syscall_name "chroot"
 
-    insert_catch_syscall_with_arg $syscall_name
+       with_test_prefix "entry" {
+           insert_catch_syscall_with_arg $syscall_name
 
-    # Let's first reach the call of the syscall.
-    check_call_to_syscall $syscall_name
+           # Let's first reach the entry of the syscall.
+           check_call_to_syscall $syscall_name
+       }
 
-    # Now, restart the program
-    rerun_to_main
+       with_test_prefix "entry/return" {
+           # Now, restart the program.
+           rerun_to_main
 
-    # And check for call/return
-    check_continue $syscall_name
+           # And check for entry/return.
+           check_continue $syscall_name
 
-    # Can we finish?
-    check_for_program_end
+           # Can we finish?
+           check_for_program_end
+       }
+    }
 }
 
 proc test_catch_syscall_fail_nodatadir {} {
-    global gdb_prompt
-
-    # Sanitizing.
-    delete_breakpoints
-
-    # Make sure GDB doesn't load the syscalls xml from the system data
-    # directory.
-    gdb_test "set data-directory /the/path/to/nowhere" ""
-
-    # Testing to see if we receive a warning when calling "catch syscall"
-    # without XML support (without datadir).
-    set thistest "Catch syscall displays a warning when there is no XML support (no datadir set)"
-    gdb_test "catch syscall" "warning: Could not load the syscall XML file.*warning: GDB will not be able to display syscall names nor to verify if.*any provided syscall numbers are valid.*Catchpoint .*(syscall).*" $thistest
-
-    # Since the catchpoint was set, we must check if it's present at
-    # "info breakpoints"
-    check_info_bp_any_syscall
-
-    # Sanitizing.
-    delete_breakpoints
+    with_test_prefix "fail no datadir" {
+       # Sanitizing.
+       delete_breakpoints
+
+       # Make sure GDB doesn't load the syscalls xml from the system
+       # data directory.
+       gdb_test "set data-directory /the/path/to/nowhere" \
+           "Warning: /the/path/to/nowhere: .*"
+
+       # Testing to see if we receive a warning when calling "catch
+       # syscall" without XML support (without datadir).
+       set thistest "catch syscall displays a warning when there is no XML support"
+       gdb_test "catch syscall" \
+           "warning: Could not load the syscall XML file.*warning: GDB will not be able to display syscall names nor to verify if.*any provided syscall numbers are valid.*Catchpoint .*(syscall).*" \
+           $thistest
+
+       # Since the catchpoint was set, we must check if it's present
+       # in "info breakpoints" output.
+       check_info_bp_any_syscall
+
+       # Sanitizing.
+       delete_breakpoints
+    }
 }
 
 proc do_syscall_tests {} {
-    global gdb_prompt srcdir
-
-    # First, we need to set GDB datadir.
-    send_gdb "set data-directory $srcdir/..\n"
-    gdb_expect 10 {
-       -re "$gdb_prompt $" {
-           verbose "Setting GDB datadir to $srcdir/..." 2
-       }
-       timeout {
-           error "Couldn't set GDB datadir."
-       }
-    }
+    # NOTE: We don't have to point gdb at the correct data-directory.
+    # For the build tree that is handled by INTERNAL_GDBFLAGS.
 
     # Verify that the 'catch syscall' help is available
     set thistest "help catch syscall"
@@ -298,6 +281,11 @@ proc do_syscall_tests {} {
     set thistest "catch syscall to a nonsense syscall is prohibited"
     gdb_test "catch syscall nonsense_syscall" "Unknown syscall name .*" $thistest
 
+    # Regression test for syscall completer bug.
+    gdb_test "complete catch syscall close chroo" \
+       "catch syscall close chroot" \
+       "complete catch syscall with multiple words"
+
     # Testing the 'catch syscall' command without arguments.
     # This test should catch any syscalls.
     if [runto_main] then { test_catch_syscall_without_args }
@@ -317,79 +305,143 @@ proc do_syscall_tests {} {
     # Testing the 'catch' syscall command during a restart of
     # the inferior.
     if [runto_main] then { test_catch_syscall_restarting_inferior }
+
+    # Testing if the 'catch syscall' command works when switching to
+    # different architectures on-the-fly (PR gdb/10737).
+    if [runto_main] then { test_catch_syscall_multi_arch }
 }
 
 proc test_catch_syscall_without_args_noxml {} {
-    # We will need the syscall names even not using it
-    # because we need to know know many syscalls are in
-    # the example file.
-    global gdb_prompt all_syscalls last_syscall
+    with_test_prefix "without args noxml" {
+       # We will need the syscall names even not using it because we
+       # need to know know many syscalls are in the example file.
+       global all_syscalls last_syscall_number all_syscalls_numbers
 
-    delete_breakpoints
+       delete_breakpoints
 
-    set thistest "Catch syscall without arguments and without XML support"
-    gdb_test "catch syscall" "Catchpoint .*(syscall).*"
-
-    # Now, we should be able to set a catchpoint,
-    # and GDB shall not display the warning anymore.
-    foreach name $all_syscalls {
-        # Unfortunately, we don't know the syscall number
-        # that will be caught because this information is
-        # arch-dependent.  Thus, we try to catch anything
-        # similar to a number.
-        check_continue "\[0-9\]*"
-    }
+       gdb_test "catch syscall" "Catchpoint .*(syscall).*"
 
-    # At last but not least, we check if the inferior
-    # has called the last (exit) syscall.
-    check_call_to_syscall "\[0-9\]*"
+       # Now, we should be able to set a catchpoint, and GDB shall
+       # not display the warning anymore.
+       foreach name $all_syscalls number $all_syscalls_numbers {
+           with_test_prefix "$name" {
+               check_continue $number
+           }
+       }
 
-    delete_breakpoints
+       # At last but not least, we check if the inferior has called
+       # the last (exit) syscall.
+       check_call_to_syscall $last_syscall_number
+
+       delete_breakpoints
+    }
 }
 
 proc test_catch_syscall_with_args_noxml {} {
-    global gdb_prompt
-
-    # The number of the "close" syscall.  This is our
-    # option for a "long-estabilished" syscall in all
-    # Linux architectures, but unfortunately x86_64 and
-    # a few other platforms don't "follow the convention".
-    # Because of this, we need this ugly check :-(.
-    set close_number ""
-    if { [istarget "x86_64-*-linux*"] } {
-        set close_number "3"
-    } else {
-        set close_number "6"
-    }
+    with_test_prefix "with args noxml" {
+       global all_syscalls_numbers
 
-    delete_breakpoints
+       delete_breakpoints
 
-    insert_catch_syscall_with_arg $close_number
+       # Inserting all syscalls numbers to be caught
+       foreach syscall_number $all_syscalls_numbers {
+           insert_catch_syscall_with_arg $syscall_number
+       }
 
-    check_continue $close_number
+       # Checking that all syscalls are caught.
+       foreach syscall_number $all_syscalls_numbers {
+           check_continue $syscall_number
+       }
 
-    delete_breakpoints
+       delete_breakpoints
+    }
 }
 
 proc test_catch_syscall_with_wrong_args_noxml {} {
-    global gdb_prompt
+    with_test_prefix "with wrong args noxml" {
+       delete_breakpoints
 
-    delete_breakpoints
+       # Even without XML support, GDB should not accept unknown
+       # syscall names for the catchpoint.
+       gdb_test "catch syscall nonsense_syscall" \
+           "Unknown syscall name .nonsense_syscall.*"
 
-    # Even without XML support, GDB should not accept unknown
-    # syscall names for the catchpoint.
-    set thistest "Catch a nonsense syscall without XML support"
-    gdb_test "catch syscall nonsense_syscall" "Unknown syscall name .nonsense_syscall.*" $thistest
+       delete_breakpoints
+    }
+}
 
-    delete_breakpoints
+proc test_catch_syscall_multi_arch {} {
+    global decimal binfile
+
+    if { [istarget "i*86-*-*"] || [istarget "x86_64-*-*"] } {
+       set arch1 "i386"
+       set arch2 "i386:x86-64"
+       set syscall1_name "exit"
+       set syscall2_name "write"
+       set syscall_number 1
+    } elseif { [istarget "powerpc-*-linux*"] \
+                  || [istarget "powerpc64-*-linux*"] } {
+       set arch1 "powerpc:common"
+       set arch2 "powerpc:common64"
+       set syscall1_name "openat"
+       set syscall2_name "unlinkat"
+       set syscall_number 286
+    } elseif { [istarget "sparc-*-linux*"] \
+                  || [istarget "sparc64-*-linux*"] } {
+       set arch1 "sparc"
+       set arch2 "sparc:v9"
+       set syscall1_name "setresuid32"
+       set syscall2_name "setresuid"
+       set syscall_number 108
+    } elseif { [istarget "mips*-linux*"] } {
+       # MIPS does not use the same numbers for syscalls on 32 and 64
+       # bits.
+       verbose "Not testing MIPS for multi-arch syscall support"
+       return
+    } elseif { [istarget "arm*-linux*"] } {
+       # catch syscall supports only 32-bit ARM for now.
+       verbose "Not testing ARM for multi-arch syscall support"
+       return
+    } elseif { [istarget "s390*-linux*"] } {
+       set arch1 "s390:31-bit"
+       set arch2 "s390:64-bit"
+       set syscall1_name "_newselect"
+       set syscall2_name "select"
+       set syscall_number 142
+    }
+
+    with_test_prefix "multiple targets" {
+       # We are not interested in loading any binary here, and in
+       # some systems (PowerPC, for example), if we load a binary
+       # there is no way to set other architecture.
+       gdb_exit
+       gdb_start
+
+       gdb_test "set architecture $arch1" \
+           "The target architecture is assumed to be $arch1" \
+           "set arch to $arch1"
+
+       gdb_test "catch syscall $syscall_number" \
+           "Catchpoint $decimal \\(syscall .${syscall1_name}. \\\[${syscall_number}\\\]\\)" \
+           "insert catch syscall on syscall $syscall_number -- $syscall1_name on $arch1"
+
+       gdb_test "set architecture $arch2" \
+           "The target architecture is assumed to be $arch2" \
+           "set arch to $arch2"
+
+       gdb_test "catch syscall $syscall_number" \
+           "Catchpoint $decimal \\(syscall .${syscall2_name}. \\\[${syscall_number}\\\]\\)" \
+           "insert catch syscall on syscall $syscall_number -- $syscall2_name on $arch2"
+
+       clean_restart $binfile
+    }
 }
 
 proc do_syscall_tests_without_xml {} {
-    global gdb_prompt srcdir
-
     # Make sure GDB doesn't load the syscalls xml from the system data
     # directory.
-    gdb_test "set data-directory /the/path/to/nowhere" ""
+    gdb_test "set data-directory /the/path/to/nowhere" \
+       "Warning: /the/path/to/nowhere: .*"
 
     # Let's test if we can catch syscalls without XML support.
     # We should succeed, but GDB is not supposed to print syscall names.
@@ -398,12 +450,6 @@ proc do_syscall_tests_without_xml {} {
     # The only valid argument "catch syscall" should accept is the
     # syscall number, and not the name (since it can't translate a
     # name to a number).
-    #
-    # It's worth mentioning that we only try to catch the syscall
-    # close().  This is because the syscall number is an arch-dependent
-    # information, so we can't assume that we know every syscall number
-    # in this system.  Therefore, we have decided to use a "long-estabilished"
-    # system call, and close() just sounded the right choice :-).
     if [runto_main] then { test_catch_syscall_with_args_noxml }
 
     # Now, we'll try to provide a syscall name (valid or not) to the command,
@@ -414,45 +460,32 @@ proc do_syscall_tests_without_xml {} {
 # This procedure fills the vector "all_syscalls_numbers" with the proper
 # numbers for the used syscalls according to the architecture.
 proc fill_all_syscalls_numbers {} {
-    global all_syscalls_numbers
-
-    # For Linux on x86, PPC, PPC64, SPARC and SPARC64, the numbers for the syscalls
-    # "close" and "chroot" are the same.
-    if { [istarget "i\[34567\]86-*-linux*"]
-         || [istarget "powerpc-*-linux*"] || [istarget "powerpc64-*-linux*"]
-         || [istarget "sparc-*-linux*"] || [istarget "sparc64-*-linux*"] } {
-         set all_syscalls_numbers { "6" "61" }
+    global all_syscalls_numbers last_syscall_number all_syscalls
+
+    foreach syscall $all_syscalls {
+       lappend all_syscalls_numbers [get_integer_valueof "${syscall}_syscall" -1]
     }
-}
 
-# Start with a fresh gdb
+    set last_syscall_number [get_integer_valueof "exit_group_syscall" -1]
+}
 
-gdb_exit
-set do_xml_test ![gdb_skip_xml_test]
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-gdb_load ${binfile}
+# Fill all the syscalls numbers before starting anything.
+fill_all_syscalls_numbers
 
 # Execute the tests, using XML support
-if $do_xml_test {
+if { ![gdb_skip_xml_test] } {
+  clean_restart $binfile
   do_syscall_tests
 
   # Now, we have to see if GDB displays a warning when we
   # don't set the data-directory but try to use catch syscall
   # anyway.  For that, we must restart GDB first.
-  gdb_exit
-  gdb_start
-  gdb_reinitialize_dir $srcdir/$subdir
-  gdb_load ${binfile}
+  clean_restart $binfile
   test_catch_syscall_fail_nodatadir
 }
 
 # Restart gdb
-
-gdb_exit
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-gdb_load ${binfile}
+clean_restart $binfile
 
 # Execute the tests, without XML support.  In this case, GDB will
 # only display syscall numbers, and not syscall names.