From: Sergio Durigan Junior Date: Wed, 18 Dec 2013 22:19:01 +0000 (-0200) Subject: Improve and fix catch-syscall.exp X-Git-Tag: gdb-7.7-release~171 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2e0d821f2db9d3ffe06c3532993584d484b04699;p=external%2Fbinutils.git Improve and fix catch-syscall.exp While fixing another bug, I found that the current gdb.base/catch-syscall.exp is kind of messy, could use some improvements, and is not correctly testing some things. I've made the following patch to address all the issues I found. On the organization side, it does a cleanup and removes unecessary imports of gdb_prompt, uses prepare_for_testing and clean_restart where needed, and fixes some comments. The testcase was also not correctly testing catching syscalls using only numbers, or catching many syscalls at once. I fixed that. The patch also uses a new method for obtaining the syscalls numbers: it relies on the C source file to get them, via and SYS_* macros. This makes the .exp file simpler because there is no need to include target conditionals there. I tested this on x86_64 Fedora 18. gdb/testsuite/ChangeLog: 2013-12-18 Sergio Durigan Junior * gdb.base/catch-syscall.c: Include . (close_syscall, chroot_syscall, exit_group_syscall): New variables. * gdb.base/catch-syscall.exp: Replace gdb_compile by prepare_for_testing. Call fill_all_syscalls_numbers before starting. Replace gdb_exit, gdb_start, gdb_reinitialize_dir and gdb_load by clean_restart. (check_info_bp_any_syscall, check_info_bp_specific_syscall) (check_info_bp_many_syscalls): Remove global gdb_prompt. (check_call_to_syscall): Likewise. Add global decimal. Improve testing regex. (check_return_from_syscall): Likewise. (check_continue, insert_catch_syscall_with_arg): Remove global gdb_prompt. (insert_catch_syscall_with_many_args): Likewise. Add global decimal. Fix $filter_str. Improve testing regex. (check_for_program_end): Remove global gdb_prompt. (test_catch_syscall_without_args): Likewise. Add global decimal. Improve testing regex. (test_catch_syscall_with_args, test_catch_syscall_with_many_args) (test_catch_syscall_with_wrong_args) (test_catch_syscall_restarting_inferior) (test_catch_syscall_fail_nodatadir): Remove global gdb_prompt. (do_syscall_tests): Likewise. Remove global srcdir. (test_catch_syscall_without_args_noxml): Remove global gdb_prompt. Add global last_syscall_number. Test for the exact syscall number to be caught. (test_catch_syscall_with_args_noxml): Remove global gdb_prompt. Add global all_syscalls_numbers. Test each syscall number to be caught, instead of only testing "close". (test_catch_syscall_with_wrong_args_noxml): Remove global gdb_prompt. (do_syscall_tests_without_xml): Likewise. Remove global srcdir. Remove stale comment. (fill_all_syscalls_numbers): Add global last_syscall_number. Fill the correct syscall numbers using information from the inferior. --- diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0f685e1..e36e835 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,41 @@ +2013-12-18 Sergio Durigan Junior + + * gdb.base/catch-syscall.c: Include . + (close_syscall, chroot_syscall, exit_group_syscall): New + variables. + * gdb.base/catch-syscall.exp: Replace gdb_compile by + prepare_for_testing. Call fill_all_syscalls_numbers before + starting. Replace gdb_exit, gdb_start, gdb_reinitialize_dir and + gdb_load by clean_restart. + (check_info_bp_any_syscall, check_info_bp_specific_syscall) + (check_info_bp_many_syscalls): Remove global gdb_prompt. + (check_call_to_syscall): Likewise. Add global decimal. Improve + testing regex. + (check_return_from_syscall): Likewise. + (check_continue, insert_catch_syscall_with_arg): Remove global + gdb_prompt. + (insert_catch_syscall_with_many_args): Likewise. Add global + decimal. Fix $filter_str. Improve testing regex. + (check_for_program_end): Remove global gdb_prompt. + (test_catch_syscall_without_args): Likewise. Add global decimal. + Improve testing regex. + (test_catch_syscall_with_args, test_catch_syscall_with_many_args) + (test_catch_syscall_with_wrong_args) + (test_catch_syscall_restarting_inferior) + (test_catch_syscall_fail_nodatadir): Remove global gdb_prompt. + (do_syscall_tests): Likewise. Remove global srcdir. + (test_catch_syscall_without_args_noxml): Remove global gdb_prompt. + Add global last_syscall_number. Test for the exact syscall number + to be caught. + (test_catch_syscall_with_args_noxml): Remove global gdb_prompt. + Add global all_syscalls_numbers. Test each syscall number to be + caught, instead of only testing "close". + (test_catch_syscall_with_wrong_args_noxml): Remove global gdb_prompt. + (do_syscall_tests_without_xml): Likewise. Remove global srcdir. + Remove stale comment. + (fill_all_syscalls_numbers): Add global last_syscall_number. Fill + the correct syscall numbers using information from the inferior. + 2013-12-17 Pedro Alves * gdb.trace/circ.exp: Expect frame info to be printed when diff --git a/gdb/testsuite/gdb.base/catch-syscall.c b/gdb/testsuite/gdb.base/catch-syscall.c index 64850de..8f94191 100644 --- a/gdb/testsuite/gdb.base/catch-syscall.c +++ b/gdb/testsuite/gdb.base/catch-syscall.c @@ -8,9 +8,16 @@ September, 2008 */ #include +#include #include #include +/* These are the syscalls numbers used by the test. */ + +static int close_syscall = SYS_close; +static int chroot_syscall = SYS_chroot; +static int exit_group_syscall = SYS_exit_group; + int main (void) { diff --git a/gdb/testsuite/gdb.base/catch-syscall.exp b/gdb/testsuite/gdb.base/catch-syscall.exp index 7f1bd29..fd7d2db 100644 --- a/gdb/testsuite/gdb.base/catch-syscall.exp +++ b/gdb/testsuite/gdb.base/catch-syscall.exp @@ -24,7 +24,7 @@ if { [is_remote target] || ![isnative] } then { } # Until "catch syscall" is implemented on other targets... -if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then { +if { ![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"] } { continue } @@ -40,26 +40,26 @@ if { ![istarget "x86_64-*-linux*"] && ![istarget "i\[34567\]86-*-linux*"] 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_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 -} +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 "". set thistest "catch syscall appears in 'info breakpoints'" @@ -70,8 +70,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 } @@ -80,7 +78,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 { @@ -95,25 +92,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, @@ -127,50 +122,48 @@ 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 gdb_continue_to_end - } proc test_catch_syscall_without_args {} { - global gdb_prompt all_syscalls last_syscall + global all_syscalls last_syscall decimal with_test_prefix "without arguments" { # Trying to set the syscall. - gdb_test "catch syscall" "Catchpoint .*(syscall).*" + gdb_test "catch syscall" "Catchpoint $decimal \\(any syscall\\)" check_info_bp_any_syscall @@ -190,8 +183,6 @@ proc test_catch_syscall_without_args {} { proc test_catch_syscall_with_args {} { with_test_prefix "with arguments" { - global gdb_prompt - set syscall_name "close" insert_catch_syscall_with_arg $syscall_name @@ -205,7 +196,7 @@ proc test_catch_syscall_with_args {} { proc test_catch_syscall_with_many_args {} { with_test_prefix "with many arguments" { - global gdb_prompt all_syscalls all_syscalls_numbers + global all_syscalls all_syscalls_numbers insert_catch_syscall_with_many_args $all_syscalls $all_syscalls_numbers @@ -221,8 +212,6 @@ proc test_catch_syscall_with_many_args {} { proc test_catch_syscall_with_wrong_args {} { with_test_prefix "wrong args" { - global gdb_prompt - # mlock is not called from the source set syscall_name "mlock" insert_catch_syscall_with_arg $syscall_name @@ -237,8 +226,6 @@ proc test_catch_syscall_with_wrong_args {} { proc test_catch_syscall_restarting_inferior {} { with_test_prefix "restarting inferior" { - global gdb_prompt - set syscall_name "chroot" with_test_prefix "entry" { @@ -263,8 +250,6 @@ proc test_catch_syscall_restarting_inferior {} { proc test_catch_syscall_fail_nodatadir {} { with_test_prefix "fail no datadir" { - global gdb_prompt - # Sanitizing. delete_breakpoints @@ -289,8 +274,6 @@ proc test_catch_syscall_fail_nodatadir {} { } proc do_syscall_tests {} { - global gdb_prompt srcdir - # NOTE: We don't have to point gdb at the correct data-directory. # For the build tree that is handled by INTERNAL_GDBFLAGS. @@ -332,7 +315,7 @@ proc test_catch_syscall_without_args_noxml {} { 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 gdb_prompt all_syscalls last_syscall + global all_syscalls last_syscall_number all_syscalls_numbers delete_breakpoints @@ -340,19 +323,15 @@ proc test_catch_syscall_without_args_noxml {} { # 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. + foreach name $all_syscalls number $all_syscalls_numbers { with_test_prefix "$name" { - check_continue "\[0-9\]*" + check_continue $number } } # At last but not least, we check if the inferior has called # the last (exit) syscall. - check_call_to_syscall "\[0-9\]*" + check_call_to_syscall $last_syscall_number delete_breakpoints } @@ -360,25 +339,19 @@ proc test_catch_syscall_without_args_noxml {} { proc test_catch_syscall_with_args_noxml {} { with_test_prefix "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" - } + global all_syscalls_numbers 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 } @@ -386,8 +359,6 @@ proc test_catch_syscall_with_args_noxml {} { proc test_catch_syscall_with_wrong_args_noxml {} { with_test_prefix "with wrong args noxml" { - global gdb_prompt - delete_breakpoints # Even without XML support, GDB should not accept unknown @@ -400,8 +371,6 @@ proc test_catch_syscall_with_wrong_args_noxml {} { } 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_no_output "set data-directory /the/path/to/nowhere" @@ -413,12 +382,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, @@ -429,46 +392,31 @@ 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, SPARC64 and ARM, - # 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*"] - || [istarget "arm*-linux*"] } { - set all_syscalls_numbers { "6" "61" } - } -} + global all_syscalls_numbers last_syscall_number -# Start with a fresh gdb + set close_syscall [get_integer_valueof "close_syscall" -1] + set chroot_syscall [get_integer_valueof "chroot_syscall" -1] + set all_syscalls_numbers [list $close_syscall $chroot_syscall] + 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.