2011-10-31 Yao Qi Pedro Alves gdb/testsuite/ * gdb.trace/trace-break.c: New. * gdb.trace/trace-break.exp: New. --- gdb/testsuite/gdb.trace/trace-break.c | 58 +++++++ gdb/testsuite/gdb.trace/trace-break.exp | 240 ++++++++++++++++++++++++++++++++ 2 files changed, 298 insertions(+) create mode 100644 gdb/testsuite/gdb.trace/trace-break.c create mode 100644 gdb/testsuite/gdb.trace/trace-break.exp Index: src/gdb/testsuite/gdb.trace/trace-break.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gdb/testsuite/gdb.trace/trace-break.c 2011-10-31 12:46:57.470047614 +0000 @@ -0,0 +1,58 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2011 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifdef SYMBOL_PREFIX +#define SYMBOL(str) SYMBOL_PREFIX #str +#else +#define SYMBOL(str) #str +#endif + +/* Called from asm. */ +static void __attribute__((used)) +func (void) +{} + +static void +marker (void) +{ + /* Some code to make sure `b marker' and `b set_point' set + breakpoints at different addresses. */ + int a = 0; + int b = a; + + /* `set_point' is the label where we'll set multiple tracepoints and + breakpoints at. The insn at the label must the large enough to + fit a fast tracepoint jump. */ + asm (" .global " SYMBOL(set_point) "\n" + SYMBOL(set_point) ":\n" +#if (defined __x86_64__ || defined __i386__) + " call " SYMBOL(func) "\n" +#endif + ); +} + +static void +end (void) +{} + +int +main () +{ + marker (); + end (); + return 0; +} Index: src/gdb/testsuite/gdb.trace/trace-break.exp =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gdb/testsuite/gdb.trace/trace-break.exp 2011-10-31 12:46:57.470047614 +0000 @@ -0,0 +1,240 @@ +# Copyright 2011 Free Software Foundation, Inc. +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +load_lib "trace-support.exp"; + +set testfile "trace-break" +set executable $testfile +set srcfile $testfile.c +set binfile $objdir/$subdir/$testfile +set expfile $testfile.exp + +# Some targets have leading underscores on assembly symbols. +set additional_flags [gdb_target_symbol_prefix_flags] + +if [prepare_for_testing $expfile $executable $srcfile \ + [list debug $additional_flags]] { + untested "failed to prepare for trace tests" + return -1 +} + +if ![runto_main] { + fail "Can't run to main to check for trace support" + return -1 +} + +if ![gdb_target_supports_trace] { + unsupported "target does not support trace" + return -1; +} + +# Set breakpoint and tracepoint at the same address. + +proc break_trace_same_addr_1 { trace_type option } { + global executable + global pf_prefix + global hex + + set old_pf_prefix $pf_prefix + set pf_prefix "$pf_prefix 1 $trace_type $option:" + + # Start with a fresh gdb. + clean_restart ${executable} + if ![runto_main] { + fail "Can't run to main" + set pf_prefix $old_pf_prefix + return -1 + } + + gdb_test_no_output "set breakpoint always-inserted ${option}" + + gdb_test "break end" "Breakpoint \[0-9\] at $hex: file.*" + + gdb_test "break set_point" "Breakpoint \[0-9\] at $hex: file.*" + gdb_test "${trace_type} set_point" "\(Fast t|T\)racepoint \[0-9\] at $hex: file.*" + + gdb_test_no_output "tstart" + + gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" "continue to set_point" + + gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" "continue to end" + gdb_test_no_output "tstop" + + gdb_test "tfind" "Found trace frame 0, tracepoint .*" "tfind frame 0" + gdb_test "tfind" "Target failed to find requested trace frame\\..*" + + set pf_prefix $old_pf_prefix +} + +# Set multiple tracepoints at the same address. + +proc break_trace_same_addr_2 { trace_type1 trace_type2 option } { + global executable + global pf_prefix + global hex + + set old_pf_prefix $pf_prefix + set pf_prefix "$pf_prefix 2 $trace_type1 $trace_type2 $option:" + + # Start with a fresh gdb. + clean_restart ${executable} + if ![runto_main] { + fail "Can't run to main" + set pf_prefix $old_pf_prefix + return -1 + } + + gdb_test_no_output "set breakpoint always-inserted ${option}" + + gdb_test "break end" "Breakpoint \[0-9\] at $hex: file.*" + + gdb_test "${trace_type1} set_point" \ + "\(Fast t|T\)racepoint \[0-9\] at $hex: file.*" \ + "${trace_type1} set_point (1)" + + gdb_test "${trace_type2} set_point" \ + "\(Fast t|T\)racepoint \[0-9\] at $hex: file.*" \ + "${trace_type2} set_point (2)" + + gdb_test_no_output "tstart" + gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" "continue to end" + + gdb_test_no_output "tstop" + + gdb_test "tfind" "Found trace frame 0, tracepoint .*" "tfind frame 0" + gdb_test "tfind" "Found trace frame 1, tracepoint .*" "tfind frame 1" + gdb_test "tfind" "Target failed to find requested trace frame\\..*" + + set pf_prefix $old_pf_prefix +} + +# Set breakpoint and tracepoint at the same address. Delete breakpoint, and verify +# that tracepoint still works. + +proc break_trace_same_addr_3 { trace_type option } { + global executable + global pf_prefix + global hex + + set old_pf_prefix $pf_prefix + set pf_prefix "$pf_prefix 3 $trace_type $option:" + + # Start with a fresh gdb. + clean_restart ${executable} + if ![runto_main] { + fail "Can't run to main" + set pf_prefix $old_pf_prefix + return -1 + } + + gdb_test_no_output "set breakpoint always-inserted ${option}" + gdb_test "break marker" "Breakpoint \[0-9\] at $hex: file.*" + gdb_test "break end" "Breakpoint \[0-9\] at $hex: file.*" + + gdb_test "break set_point" "Breakpoint \[0-9\] at $hex: file.*" + gdb_test "${trace_type} set_point" "\(Fast t|T\)racepoint \[0-9\] at $hex: file.*" + + gdb_test_no_output "tstart" + + gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" "continue to marker" + gdb_test "delete break 4" + + gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" "continue to end" + gdb_test_no_output "tstop" + + gdb_test "tfind" "Found trace frame 0, tracepoint .*" "tfind frame 0" + gdb_test "tfind" "Target failed to find requested trace frame\\..*" + + set pf_prefix $old_pf_prefix +} + +# Set breakpoint and tracepoint at the same address. Delete tracepoint, and verify +# that breakpoint still works. + +proc break_trace_same_addr_4 { trace_type option } { + global executable + global pf_prefix + global hex + + set old_pf_prefix $pf_prefix + set pf_prefix "$pf_prefix 4 $trace_type $option:" + + # Start with a fresh gdb. + clean_restart ${executable} + if ![runto_main] { + fail "Can't run to main" + set pf_prefix $old_pf_prefix + return -1 + } + + gdb_test_no_output "set breakpoint always-inserted ${option}" + gdb_test "break marker" "Breakpoint \[0-9\] at $hex: file.*" + gdb_test "break end" "Breakpoint \[0-9\] at $hex: file.*" + + gdb_test "break set_point" "Breakpoint \[0-9\] at $hex: file.*" + gdb_test "${trace_type} set_point" "\(Fast t|T\)racepoint \[0-9\] at $hex: file.*" + + gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" "continue to marker" + # Delete tracepoint set on set_point. + gdb_test "delete trace 5" + + gdb_test "tstart" "No tracepoints defined, not starting trace.*" + + gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" "continue to set_point" + gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" "continue to end" + gdb_test "tstop" "Trace is not running.*" + + gdb_test "tfind" "Target failed to find requested trace frame\\..*" + + set pf_prefix $old_pf_prefix +} + +foreach break_always_inserted { "on" "off" } { + break_trace_same_addr_1 "trace" ${break_always_inserted} + break_trace_same_addr_2 "trace" "trace" ${break_always_inserted} + break_trace_same_addr_3 "trace" ${break_always_inserted} + break_trace_same_addr_4 "trace" ${break_always_inserted} +} + +set libipa $objdir/../gdbserver/libinproctrace.so +gdb_load_shlibs $libipa + +# Can't use prepare_for_testing, because that splits compiling into +# building objects and then linking, and we'd fail with "linker input +# file unused because linking not done" when building the object. + +if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable [list debug $additional_flags shlib=$libipa] ] != "" } { + untested "failed to compile ftrace tests" + return -1 +} +clean_restart ${executable} + +if ![runto_main] { + fail "Can't run to main for ftrace tests" + return 0 +} + +gdb_reinitialize_dir $srcdir/$subdir +if { [gdb_test "info sharedlibrary" ".*libinproctrace\.so.*" "IPA loaded"] != 0 } { + untested "Could not find IPA lib loaded" +} else { + foreach break_always_inserted { "on" "off" } { + break_trace_same_addr_1 "ftrace" ${break_always_inserted} + break_trace_same_addr_2 "trace" "ftrace" ${break_always_inserted} + break_trace_same_addr_2 "ftrace" "trace" ${break_always_inserted} + break_trace_same_addr_3 "ftrace" ${break_always_inserted} + break_trace_same_addr_4 "ftrace" ${break_always_inserted} + } +}