gdb/
* breakpoint.c (create_breakpoint): Produce query message according to breakpoint's type. Allocate tracepoint per correct type. Don't check SALs for pending fast tracepoints. * tracepoint.c (process_tracepoint_on_disconnect): New. (disconnect_tracing): Call process_tracepoint_on_disconnect. gdb/doc/ * gdb.texinfo (Create and Delete Tracepoints): Mention pending tracepoint. gdb/testsuite/ * gdb.trace/pending.exp: New. * gdb.trace/pending.c: New. * gdb.trace/pendshr1.c: New. * gdb.trace/pendshr2.c: New. * gdb.trace/change-loc.exp (tracepoint_change_loc_1): Check one tracepoint location becomes pending. (tracepoint_change_loc_2): New.
This commit is contained in:
parent
3ea46bff73
commit
bfccc43c12
11 changed files with 875 additions and 18 deletions
|
@ -1,3 +1,12 @@
|
|||
2011-11-18 Yao Qi <yao@codesourcery.com>
|
||||
|
||||
* breakpoint.c (create_breakpoint): Produce query message according to
|
||||
breakpoint's type.
|
||||
Allocate tracepoint per correct type.
|
||||
Don't check SALs for pending fast tracepoints.
|
||||
* tracepoint.c (process_tracepoint_on_disconnect): New.
|
||||
(disconnect_tracing): Call process_tracepoint_on_disconnect.
|
||||
|
||||
2011-11-18 Yao Qi <yao@codesourcery.com>
|
||||
|
||||
* breakpoint.c (install_breakpoint): Add one more parameter so that
|
||||
|
|
|
@ -7836,8 +7836,8 @@ create_breakpoint (struct gdbarch *gdbarch,
|
|||
/* If pending breakpoint support is auto query and the user
|
||||
selects no, then simply return the error code. */
|
||||
if (pending_break_support == AUTO_BOOLEAN_AUTO
|
||||
&& !nquery (_("Make breakpoint pending on "
|
||||
"future shared library load? ")))
|
||||
&& !nquery (_("Make %s pending on future shared library load? "),
|
||||
bptype_string (type_wanted)))
|
||||
return 0;
|
||||
|
||||
/* At this point, either the user was queried about setting
|
||||
|
@ -7894,7 +7894,7 @@ create_breakpoint (struct gdbarch *gdbarch,
|
|||
breakpoint_sals_to_pc (&sals);
|
||||
|
||||
/* Fast tracepoints may have additional restrictions on location. */
|
||||
if (type_wanted == bp_fast_tracepoint)
|
||||
if (!pending && type_wanted == bp_fast_tracepoint)
|
||||
check_fast_tracepoint_sals (gdbarch, &sals);
|
||||
|
||||
/* Verify that condition can be parsed, before setting any
|
||||
|
@ -7981,9 +7981,18 @@ create_breakpoint (struct gdbarch *gdbarch,
|
|||
|
||||
make_cleanup (xfree, copy_arg);
|
||||
|
||||
b = set_raw_breakpoint_without_location (gdbarch, type_wanted, ops);
|
||||
set_breakpoint_number (internal, b);
|
||||
b->thread = -1;
|
||||
if (is_tracepoint_type (type_wanted))
|
||||
{
|
||||
struct tracepoint *t;
|
||||
|
||||
t = XCNEW (struct tracepoint);
|
||||
b = &t->base;
|
||||
}
|
||||
else
|
||||
b = XNEW (struct breakpoint);
|
||||
|
||||
init_raw_breakpoint_without_location (b, gdbarch, type_wanted, ops);
|
||||
|
||||
b->addr_string = canonical.canonical[0];
|
||||
b->cond_string = NULL;
|
||||
b->ignore_count = ignore_count;
|
||||
|
@ -7991,18 +8000,13 @@ create_breakpoint (struct gdbarch *gdbarch,
|
|||
b->condition_not_parsed = 1;
|
||||
b->enable_state = enabled ? bp_enabled : bp_disabled;
|
||||
b->pspace = current_program_space;
|
||||
b->py_bp_object = NULL;
|
||||
|
||||
if (enabled && b->pspace->executing_startup
|
||||
&& (b->type == bp_breakpoint
|
||||
|| b->type == bp_hardware_breakpoint))
|
||||
b->enable_state = bp_startup_disabled;
|
||||
|
||||
if (!internal)
|
||||
/* Do not mention breakpoints with a negative number,
|
||||
but do notify observers. */
|
||||
mention (b);
|
||||
observer_notify_breakpoint_created (b);
|
||||
install_breakpoint (internal, b, 0);
|
||||
}
|
||||
|
||||
if (sals.nelts > 1)
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2011-11-18 Yao Qi <yao@codesourcery.com>
|
||||
|
||||
* gdb.texinfo (Create and Delete Tracepoints): Mention pending
|
||||
tracepoint.
|
||||
|
||||
2011-11-15 Doug Evans <dje@google.com>
|
||||
|
||||
* gdb.texinfo (Files): Document basenames-may-differ.
|
||||
|
|
|
@ -10340,7 +10340,15 @@ in tracing}).
|
|||
If remote stub doesn't support the @samp{InstallInTrace} feature, all
|
||||
these changes don't take effect until the next @code{tstart}
|
||||
command, and once a trace experiment is running, further changes will
|
||||
not have any effect until the next trace experiment starts.
|
||||
not have any effect until the next trace experiment starts. In addition,
|
||||
@value{GDBN} supports @dfn{pending tracepoints}---tracepoints whose
|
||||
address is not yet resolved. (This is similar to pending breakpoints.)
|
||||
Pending tracepoints are not downloaded to the target and not installed
|
||||
until they are resolved. The resolution of pending tracepoints requires
|
||||
@value{GDBN} support---when debugging with the remote target, and
|
||||
@value{GDBN} disconnects from the remote stub (@pxref{disconnected
|
||||
tracing}), pending tracepoints can not be resolved (and downloaded to
|
||||
the remote stub) while @value{GDBN} is disconnected.
|
||||
|
||||
Here are some examples of using the @code{trace} command:
|
||||
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
2011-11-18 Yao Qi <yao@codesourcery.com>
|
||||
|
||||
* gdb.trace/pending.exp: New.
|
||||
* gdb.trace/pending.c: New.
|
||||
* gdb.trace/pendshr1.c: New.
|
||||
* gdb.trace/pendshr2.c: New.
|
||||
* gdb.trace/change-loc.exp (tracepoint_change_loc_1): Check one
|
||||
tracepoint location becomes pending.
|
||||
(tracepoint_change_loc_2): New.
|
||||
|
||||
2011-11-16 David S. Miller <davem@davemloft.net>
|
||||
|
||||
* lib/gdb.exp (can_single_step_to_signal_handler): Return zero when
|
||||
|
|
|
@ -118,27 +118,145 @@ proc tracepoint_change_loc_1 { trace_type } {
|
|||
\[0-9\]+\[\t \]+\(|fast \)tracepoint\[ \]+keep y.*\<MULTIPLE\>.*4\.1.* in func4.*4\.2.* in func4.*" \
|
||||
"tracepoint with two locations"
|
||||
|
||||
setup_kfail "gdb/13392" x86_64-*-*
|
||||
gdb_test "continue" ".*Breakpoint.*marker.*at.*$srcfile.*" \
|
||||
"continue to marker 2"
|
||||
|
||||
gdb_test_multiple "continue" "continue to marker 2" {
|
||||
-re ".*Breakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
|
||||
pass "continue to marker 2"
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
kfail "gdb/13392" "continue to marker 2"
|
||||
set pf_prefix $old_pf_prefix
|
||||
return
|
||||
}
|
||||
}
|
||||
# tracepoint has three locations after shlib change-loc-2 is loaded.
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(|fast \)tracepoint\[ \]+keep y.*\<MULTIPLE\>.*4\.1.* in func4.*4\.2.* in func4.*4\.3.* in func4 .*" \
|
||||
"tracepoint with three locations"
|
||||
|
||||
gdb_test "continue" ".*Breakpoint.*marker.*at.*$srcfile.*" \
|
||||
"continue to marker 3"
|
||||
|
||||
# shlib is unloaded, there are still three locations, but one is pending.
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(|fast \)tracepoint\[ \]+keep y.*\<MULTIPLE\>.*4\.1.* in func4.*4\.2.* in func4.*4\.3.* \<PENDING\>\[\t \]+set_tracepoint.*" \
|
||||
"tracepoint with two locations (unload)"
|
||||
|
||||
gdb_test_no_output "tstop"
|
||||
|
||||
setup_kfail "gdb/13392" x86_64-*-*
|
||||
gdb_test "tfind" "Found trace frame 0, tracepoint 4.*" "tfind frame 0"
|
||||
gdb_test "tfind" "Target failed to find requested trace frame\\..*"
|
||||
|
||||
set pf_prefix $old_pf_prefix
|
||||
}
|
||||
|
||||
# Set pending tracepoint.
|
||||
|
||||
proc tracepoint_change_loc_2 { trace_type } {
|
||||
global srcdir
|
||||
global srcfile
|
||||
global subdir
|
||||
global pcreg
|
||||
global binfile
|
||||
global gdb_prompt
|
||||
global pf_prefix
|
||||
|
||||
set old_pf_prefix $pf_prefix
|
||||
set pf_prefix "$pf_prefix 2 $trace_type:"
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
|
||||
gdb_test_multiple "${trace_type} set_tracepoint" "set pending tracepoint" {
|
||||
-re ".*Make \(|fast \)tracepoint pending.*y or \\\[n\\\]. $" {
|
||||
gdb_test "y" "\(Fast t|T\)racepoint.*set_tracepoint.*pending." "set pending tracepoint"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_trace_setactions "set action for tracepoint" "" \
|
||||
"collect \$$pcreg" "^$"
|
||||
|
||||
# tracepoint has no location information now.
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(|fast \)tracepoint\[ \]+keep y.*PENDING.*set_tracepoint.*" \
|
||||
"single pending tracepoint info (without symbols)"
|
||||
|
||||
gdb_load ${binfile}
|
||||
# tracepoint has one location after executable is loaded.
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(|fast \)tracepoint\[ \]+keep y.*func4.*" \
|
||||
"tracepoint with one location"
|
||||
|
||||
set main_bp 0
|
||||
gdb_test_multiple "break main" "set breakpoint on main" {
|
||||
-re "Breakpoint (\[0-9\]*) at .*, line.*$gdb_prompt $" {
|
||||
set main_bp $expect_out(1,string)
|
||||
}
|
||||
}
|
||||
gdb_run_cmd
|
||||
|
||||
gdb_test "" \
|
||||
".*Breakpoint.*main.*at.*$srcfile.*" \
|
||||
"run to main"
|
||||
gdb_test_no_output "delete break $main_bp"
|
||||
|
||||
# tracepoint has two locations after shlib change-loc-1 is loaded.
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(|fast \)tracepoint\[ \]+keep y.*\<MULTIPLE\>.*1\.1.* in func4.*1\.2.* in func4.*" \
|
||||
"tracepoint with two locations"
|
||||
|
||||
gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
|
||||
"breakpoint on marker"
|
||||
|
||||
# tracepoint with two locations will be downloaded and installed.
|
||||
gdb_test_no_output "tstart"
|
||||
|
||||
gdb_test_multiple "continue" "continue to marker 1" {
|
||||
-re ".*Breakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
|
||||
pass "continue to marker 1"
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
kfail "gdb/13392" "continue to marker 1"
|
||||
set pf_prefix $old_pf_prefix
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "continue" ".*Breakpoint.*marker.*at.*$srcfile.*" \
|
||||
"continue to marker 2"
|
||||
|
||||
# tracepoint has three locations after shlib change-loc-2 is loaded.
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(|fast \)tracepoint\[ \]+keep y.*\<MULTIPLE\>.*1\.1.* in func4.*1\.2.* in func4.*1\.3.* in func4 .*" \
|
||||
"tracepoint with three locations"
|
||||
|
||||
gdb_test "continue" ".*Breakpoint.*marker.*at.*$srcfile.*" \
|
||||
"continue to marker 3"
|
||||
|
||||
# shlib is unloaded, there are still three locations, but one is pending.
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(|fast \)tracepoint\[ \]+keep y.*\<MULTIPLE\>.*1\.1.* in func4.*1\.2.* in func4.*1\.3.* \<PENDING\>\[\t \]+set_tracepoint.*" \
|
||||
"tracepoint with two locations (unload)"
|
||||
|
||||
gdb_test_no_output "tstop"
|
||||
|
||||
gdb_test "tfind" "Found trace frame 0, tracepoint 1.*" "tfind frame 0"
|
||||
gdb_test "tfind" "Found trace frame 1, tracepoint 1.*" "tfind frame 1"
|
||||
gdb_test "tfind" "Found trace frame 2, tracepoint 1.*" "tfind frame 2"
|
||||
gdb_test "tfind" "Target failed to find requested trace frame\\..*"
|
||||
|
||||
set pf_prefix $old_pf_prefix
|
||||
}
|
||||
|
||||
tracepoint_change_loc_1 "trace"
|
||||
tracepoint_change_loc_2 "trace"
|
||||
|
||||
# Re-compile test case with IPA.
|
||||
set libipa $objdir/../gdbserver/libinproctrace.so
|
||||
|
@ -151,3 +269,4 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile executable \
|
|||
}
|
||||
|
||||
tracepoint_change_loc_1 "ftrace"
|
||||
tracepoint_change_loc_2 "ftrace"
|
||||
|
|
50
gdb/testsuite/gdb.trace/pending.c
Normal file
50
gdb/testsuite/gdb.trace/pending.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
extern void pendfunc (int x);
|
||||
|
||||
static void
|
||||
marker () {}
|
||||
|
||||
int main()
|
||||
{
|
||||
const char *libname = "pendshr2.sl";
|
||||
void *h;
|
||||
int (*p_func) (int);
|
||||
|
||||
pendfunc (3);
|
||||
pendfunc (4);
|
||||
pendfunc (3);
|
||||
|
||||
marker ();
|
||||
|
||||
h = dlopen (libname, RTLD_LAZY);
|
||||
if (h == NULL) return 1;
|
||||
|
||||
p_func = dlsym (h, "pendfunc2");
|
||||
if (p_func == NULL) return 2;
|
||||
|
||||
(*p_func) (4);
|
||||
|
||||
marker ();
|
||||
|
||||
dlclose (h);
|
||||
return 0;
|
||||
}
|
525
gdb/testsuite/gdb.trace/pending.exp
Normal file
525
gdb/testsuite/gdb.trace/pending.exp
Normal file
|
@ -0,0 +1,525 @@
|
|||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib "trace-support.exp";
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
if {[skip_shlib_tests]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
set testfile "pending"
|
||||
set libfile1 "pendshr1"
|
||||
set libfile2 "pendshr2"
|
||||
set executable $testfile
|
||||
set srcfile $testfile.c
|
||||
set libsrc1 $srcdir/$subdir/$libfile1.c
|
||||
set libsrc2 $srcdir/$subdir/$libfile2.c
|
||||
set binfile $objdir/$subdir/$testfile
|
||||
set lib_sl1 $objdir/$subdir/$libfile1.sl
|
||||
set lib_sl2 $objdir/$subdir/$libfile2.sl
|
||||
|
||||
set lib_opts [gdb_target_symbol_prefix_flags]
|
||||
|
||||
if { [gdb_compile_shlib $libsrc1 $lib_sl1 $lib_opts] != ""
|
||||
|| [gdb_compile_shlib $libsrc2 $lib_sl2 $lib_opts] != ""} {
|
||||
untested "Could not compile either $libsrc1 or $libsrc2"
|
||||
return -1
|
||||
}
|
||||
|
||||
set exec_opts [list debug shlib=$lib_sl1 shlib_load]
|
||||
if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != "" } {
|
||||
untested "Failed to compile $srcfile"
|
||||
return -1
|
||||
}
|
||||
|
||||
clean_restart $executable
|
||||
|
||||
gdb_load_shlibs $lib_sl1
|
||||
gdb_load_shlibs $lib_sl2
|
||||
|
||||
if ![runto_main] {
|
||||
fail "Can't run to main to check for trace support"
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![gdb_target_supports_trace] {
|
||||
unsupported "Current target does not support trace"
|
||||
return -1;
|
||||
}
|
||||
|
||||
# Verify pending tracepoint is resolved to running to main.
|
||||
|
||||
proc pending_tracepoint_resolved { trace_type } {
|
||||
global srcdir
|
||||
global subdir
|
||||
global binfile
|
||||
global srcfile
|
||||
global lib_sl1
|
||||
global pf_prefix
|
||||
|
||||
set old_pf_prefix $pf_prefix
|
||||
lappend pf_prefix "$trace_type" "resolved:"
|
||||
|
||||
# Start with a fresh gdb.
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
|
||||
gdb_test_multiple "$trace_type set_point1" "set pending tracepoint" {
|
||||
-re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
|
||||
gdb_test "y" "\(Fast t|T\)racepoint.*set_point1.*pending." \
|
||||
"set pending tracepoint (without symbols)"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point1.*" \
|
||||
"single pending tracepoint info (without symbols)"
|
||||
|
||||
gdb_load ${binfile}
|
||||
|
||||
gdb_test "break main" "Breakpoint.*at.* file .*$srcfile, line.*" \
|
||||
"breakpoint function"
|
||||
|
||||
gdb_run_cmd
|
||||
gdb_test "" "Breakpoint 2, main.*"
|
||||
|
||||
# Run to main which should resolve a pending tracepoint
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc.*" \
|
||||
"single tracepoint info"
|
||||
|
||||
set pf_prefix $old_pf_prefix
|
||||
}
|
||||
|
||||
# Verify pending tracepoint is resolved and works as expected.
|
||||
|
||||
proc pending_tracepoint_works { trace_type } {
|
||||
global executable
|
||||
global srcfile
|
||||
global lib_sl1
|
||||
global pf_prefix
|
||||
global gdb_prompt
|
||||
|
||||
set old_pf_prefix $pf_prefix
|
||||
lappend pf_prefix "$trace_type" "works:"
|
||||
|
||||
# Restart with a fresh gdb.
|
||||
clean_restart $executable
|
||||
|
||||
# Test setting and querying pending tracepoints
|
||||
|
||||
gdb_test_multiple "$trace_type set_point1" "set pending tracepoint" {
|
||||
-re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
|
||||
gdb_test "y" "\(Fast t|T\)racepoint.*set_point1.*pending." "set pending tracepoint"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point1.*" \
|
||||
"single pending tracepoint info"
|
||||
|
||||
# Run to main which should resolve a pending tracepoint
|
||||
gdb_test "break main" "Breakpoint.*at.* file .*$srcfile, line.*" \
|
||||
"breakpoint function"
|
||||
gdb_run_cmd
|
||||
gdb_test "" "Breakpoint 2, main.*"
|
||||
|
||||
gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
|
||||
"breakpoint on marker"
|
||||
|
||||
gdb_test_no_output "tstart" "start trace experiment"
|
||||
|
||||
gdb_test_multiple "continue" "continue to marker" {
|
||||
-re "Continuing.\r\n\r\nBreakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
|
||||
pass "continue to marker"
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
kfail "gdb/13392" "continue to marker"
|
||||
set pf_prefix $old_pf_prefix
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "tstop" "\[\r\n\]+" "stop trace experiment"
|
||||
|
||||
gdb_test "tfind start" "#0 .*" "tfind test frame 0"
|
||||
gdb_test "tfind" "Found trace frame 1, tracepoint 1.*" "tfind test frame 1"
|
||||
gdb_test "tfind" "Found trace frame 2, tracepoint 1.*" "tfind test frame 2"
|
||||
gdb_test "tfind" "Target failed to find requested trace frame..*" "tfind test frame"
|
||||
|
||||
set pf_prefix $old_pf_prefix
|
||||
}
|
||||
|
||||
# Verify pending tracepoint is resolved during trace.
|
||||
|
||||
proc pending_tracepoint_resolved_during_trace { trace_type } {
|
||||
global executable
|
||||
global srcfile
|
||||
global gdb_prompt
|
||||
global lib_sl1
|
||||
global pf_prefix
|
||||
|
||||
set old_pf_prefix $pf_prefix
|
||||
lappend pf_prefix "$trace_type" "resolved_in_trace:"
|
||||
|
||||
# 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_multiple "$trace_type set_point2" "set pending tracepoint on set_point2" {
|
||||
-re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
|
||||
gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \
|
||||
"set pending tracepoint (without symbols)"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point2.*" \
|
||||
"single pending tracepoint on set_point2"
|
||||
|
||||
gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
|
||||
"breakpoint on marker"
|
||||
|
||||
gdb_test_no_output "tstart" "start trace experiment"
|
||||
|
||||
gdb_test "continue" "Continuing.\r\n\r\nBreakpoint.*marker.*at.*pending.c.*" \
|
||||
"continue to marker 1"
|
||||
|
||||
gdb_test_multiple "continue" "continue to marker 2" {
|
||||
-re "Continuing.\r\n\r\nBreakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
|
||||
pass "continue to marker 2"
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
kfail "gdb/13392" "continue to marker 2"
|
||||
set pf_prefix $old_pf_prefix
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "tstop" "\[\r\n\]+" "stop trace experiment"
|
||||
|
||||
# tracepoint should be resolved.
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc2.*" \
|
||||
"tracepoint is resolved"
|
||||
|
||||
gdb_test "tfind start" "#0 .*" "tfind test frame 0"
|
||||
gdb_test "tfind" "Target failed to find requested trace frame..*" "tfind test frame"
|
||||
|
||||
set pf_prefix $old_pf_prefix
|
||||
}
|
||||
|
||||
# Verify pending tracepoint is resolved and installed during trace.
|
||||
|
||||
proc pending_tracepoint_installed_during_trace { trace_type } {
|
||||
global executable
|
||||
global srcfile
|
||||
global lib_sl1
|
||||
global gdb_prompt
|
||||
global pf_prefix
|
||||
global hex
|
||||
|
||||
set old_pf_prefix $pf_prefix
|
||||
lappend pf_prefix "$trace_type" "installed_in_trace:"
|
||||
|
||||
# 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 "next" ".*"
|
||||
gdb_test "trace main" "Tracepoint \[0-9\] at .*" "set tracepoint on main"
|
||||
|
||||
gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
|
||||
"breakpoint on marker"
|
||||
|
||||
gdb_test_no_output "tstart" "start trace experiment"
|
||||
|
||||
gdb_test "continue" "Continuing.\r\n\r\nBreakpoint.*marker.*at.*${srcfile}.*" \
|
||||
"continue to marker 1"
|
||||
|
||||
# Set a pending tracepoint during a tracing experiment.
|
||||
gdb_test_multiple "$trace_type set_point2" "set pending tracepoint on set_point2" {
|
||||
-re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
|
||||
gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \
|
||||
"set pending tracepoint"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \t\]+keep y.*PENDING.*set_point2.*" \
|
||||
"single pending tracepoint on set_point2"
|
||||
|
||||
gdb_test_multiple "continue" "continue to marker 2" {
|
||||
-re "Continuing.\r\n\r\nBreakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
|
||||
pass "continue to marker 2"
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
kfail "gdb/13392" "continue to marker 2"
|
||||
set pf_prefix $old_pf_prefix
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "tstop" "\[\r\n\]+" "stop trace experiment"
|
||||
|
||||
# tracepoint should be resolved.
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc2.*" \
|
||||
"tracepoint is resolved"
|
||||
|
||||
gdb_test "tfind start" "#0 $hex in pendfunc2 .*" "tfind test frame 0"
|
||||
gdb_test "tfind" "Target failed to find requested trace frame..*" "tfind test frame"
|
||||
|
||||
set pf_prefix $old_pf_prefix
|
||||
}
|
||||
|
||||
|
||||
# Verify pending tracepoint will no longer work if we disconnect during tracing.
|
||||
|
||||
proc pending_tracepoint_disconnect_during_trace { trace_type } {
|
||||
global executable
|
||||
global srcfile
|
||||
global lib_sl1
|
||||
global pf_prefix
|
||||
global gdb_prompt
|
||||
|
||||
set old_pf_prefix $pf_prefix
|
||||
lappend pf_prefix "$trace_type" "disconn:"
|
||||
|
||||
# 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_multiple "trace pendfunc3" "set pending tracepoint on set_point2" {
|
||||
-re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
|
||||
gdb_test "y" "\(Fast t|T\)racepoint.*pendfunc3.*pending." \
|
||||
"set pending tracepoint on pendfun3"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
|
||||
"breakpoint on marker"
|
||||
|
||||
gdb_test_no_output "tstart" "start trace experiment"
|
||||
|
||||
gdb_test "continue" "Continuing.\r\n\r\nBreakpoint.*marker.*at.*pending.c.*" \
|
||||
"continue to marker"
|
||||
|
||||
set test "disconnect with pending tracepoint"
|
||||
gdb_test_multiple "disconnect" $test {
|
||||
-re "warning: Pending tracepoints will not be resolved while GDB is disconnected.*Trace is running but will stop on detach; detach anyway\\? \\(y or n\\) $" {
|
||||
pass $test
|
||||
|
||||
set test "disconnected"
|
||||
gdb_test_multiple "y" $test {
|
||||
-re "$gdb_prompt $" {
|
||||
pass "$test"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set pf_prefix $old_pf_prefix
|
||||
}
|
||||
|
||||
|
||||
# Verify disconnect after pending tracepoint has been resolved.
|
||||
|
||||
proc pending_tracepoint_disconnect_after_resolved { trace_type } {
|
||||
global executable
|
||||
global srcfile
|
||||
global lib_sl1
|
||||
global gdb_prompt
|
||||
global pf_prefix
|
||||
|
||||
set old_pf_prefix $pf_prefix
|
||||
lappend pf_prefix "$trace_type" "disconn_resolved:"
|
||||
|
||||
# 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_multiple "trace set_point2" "set pending tracepoint on set_point2" {
|
||||
-re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
|
||||
gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \
|
||||
"set pending tracepoint on pendfun2"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
|
||||
"breakpoint on marker"
|
||||
|
||||
gdb_test_no_output "tstart" "start trace experiment"
|
||||
|
||||
gdb_test "continue" "Continuing.\r\n\r\nBreakpoint.*marker.*at.*pending.c.*" \
|
||||
"continue to marker 1"
|
||||
gdb_test "continue" "Continuing.\r\n\r\nBreakpoint.*marker.*at.*pending.c.*" \
|
||||
"continue to marker 2"
|
||||
|
||||
# There should be no pending tracepoint, so no warning should be emitted.
|
||||
set test "disconnect with resolved tracepoint"
|
||||
gdb_test_multiple "disconnect" $test {
|
||||
-re "warning: Pending tracepoints will not be resolved while GDB is disconnected.*Trace is running but will stop on detach; detach anyway\\? \\(y or n\\) $" {
|
||||
fail $test
|
||||
}
|
||||
-re "Trace is running but will stop on detach; detach anyway\\? \\(y or n\\) $" {
|
||||
pass $test
|
||||
}
|
||||
}
|
||||
set test "disconnected"
|
||||
gdb_test_multiple "y" $test {
|
||||
-re "$gdb_prompt $" {
|
||||
pass "$test"
|
||||
}
|
||||
}
|
||||
|
||||
set pf_prefix $old_pf_prefix
|
||||
}
|
||||
|
||||
# Verify action works properly in resolved tracepoint.
|
||||
|
||||
proc pending_tracepoint_with_action_resolved { trace_type } {
|
||||
global executable
|
||||
global srcfile
|
||||
global lib_sl1
|
||||
global gdb_prompt
|
||||
global pf_prefix
|
||||
|
||||
set old_pf_prefix $pf_prefix
|
||||
lappend pf_prefix "$trace_type" "action_resolved:"
|
||||
|
||||
# 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_multiple "$trace_type set_point2" "set pending tracepoint on set_point2" {
|
||||
-re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
|
||||
gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \
|
||||
"set pending tracepoint (without symbols)"
|
||||
}
|
||||
}
|
||||
|
||||
set pcreg "pc"
|
||||
if [is_amd64_regs_target] {
|
||||
set pcreg "rip"
|
||||
} elseif [is_x86_like_target] {
|
||||
set pcreg "eip"
|
||||
}
|
||||
|
||||
gdb_trace_setactions "set action for pending tracepoint" "" \
|
||||
"collect \$$pcreg" "^$"
|
||||
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point2.*" \
|
||||
"single pending tracepoint on set_point2"
|
||||
|
||||
gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
|
||||
"breakpoint on marker"
|
||||
|
||||
gdb_test_no_output "tstart" "start trace experiment"
|
||||
|
||||
gdb_test "continue" "Continuing.\r\n\r\nBreakpoint.*marker.*at.*pending.c.*" \
|
||||
"continue to marker 1"
|
||||
|
||||
gdb_test_multiple "continue" "continue to marker 2" {
|
||||
-re "Continuing.\r\n\r\nBreakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
|
||||
pass "continue to marker 2"
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
kfail "gdb/13392" "continue to marker 2"
|
||||
set pf_prefix $old_pf_prefix
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "tstop" "\[\r\n\]+" "stop trace experiment"
|
||||
|
||||
# tracepoint should be resolved.
|
||||
gdb_test "info trace" \
|
||||
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
|
||||
\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc2.*" \
|
||||
"tracepoint is resolved"
|
||||
|
||||
gdb_test "tfind start" "#0 .*" "tfind test frame 0"
|
||||
gdb_test "tdump" "Data collected at tracepoint .*, trace frame \[0-9\]:.*\\$${pcreg} = .*"
|
||||
gdb_test "tfind" "Target failed to find requested trace frame..*" "tfind test frame"
|
||||
|
||||
set pf_prefix $old_pf_prefix
|
||||
}
|
||||
|
||||
pending_tracepoint_resolved "trace"
|
||||
|
||||
pending_tracepoint_works "trace"
|
||||
|
||||
pending_tracepoint_resolved_during_trace "trace"
|
||||
|
||||
pending_tracepoint_disconnect_during_trace "trace"
|
||||
|
||||
pending_tracepoint_disconnect_after_resolved "trace"
|
||||
|
||||
pending_tracepoint_with_action_resolved "trace"
|
||||
|
||||
pending_tracepoint_installed_during_trace "trace"
|
||||
|
||||
# Re-compile test case with IPA.
|
||||
set libipa $objdir/../gdbserver/libinproctrace.so
|
||||
gdb_load_shlibs $libipa
|
||||
|
||||
lappend exec_opts "shlib=$libipa"
|
||||
|
||||
if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != "" } {
|
||||
untested "Failed to compile $srcfile"
|
||||
return -1
|
||||
}
|
||||
|
||||
pending_tracepoint_resolved "ftrace"
|
||||
pending_tracepoint_works "ftrace"
|
||||
pending_tracepoint_resolved_during_trace "ftrace"
|
||||
pending_tracepoint_disconnect_during_trace "ftrace"
|
||||
pending_tracepoint_disconnect_after_resolved "ftrace"
|
||||
pending_tracepoint_with_action_resolved "ftrace"
|
||||
pending_tracepoint_installed_during_trace "ftrace"
|
43
gdb/testsuite/gdb.trace/pendshr1.c
Normal file
43
gdb/testsuite/gdb.trace/pendshr1.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef SYMBOL_PREFIX
|
||||
#define SYMBOL(str) SYMBOL_PREFIX #str
|
||||
#else
|
||||
#define SYMBOL(str) #str
|
||||
#endif
|
||||
|
||||
static void
|
||||
pendfunc1 (void)
|
||||
{
|
||||
int x = 0;
|
||||
int y = x + 4;
|
||||
}
|
||||
|
||||
void
|
||||
pendfunc (int x)
|
||||
{
|
||||
/* `set_point1' 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_point1) "\n"
|
||||
SYMBOL(set_point1) ":\n"
|
||||
#if (defined __x86_64__ || defined __i386__)
|
||||
" call " SYMBOL(pendfunc1) "\n"
|
||||
#endif
|
||||
);
|
||||
}
|
40
gdb/testsuite/gdb.trace/pendshr2.c
Normal file
40
gdb/testsuite/gdb.trace/pendshr2.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef SYMBOL_PREFIX
|
||||
#define SYMBOL(str) SYMBOL_PREFIX #str
|
||||
#else
|
||||
#define SYMBOL(str) #str
|
||||
#endif
|
||||
|
||||
static void
|
||||
foo ()
|
||||
{}
|
||||
|
||||
void
|
||||
pendfunc2 (int x)
|
||||
{
|
||||
/* `set_point2' 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_point2) "\n"
|
||||
SYMBOL(set_point2) ":\n"
|
||||
#if (defined __x86_64__ || defined __i386__)
|
||||
" call " SYMBOL(foo) "\n"
|
||||
#endif
|
||||
);
|
||||
}
|
|
@ -1642,6 +1642,48 @@ add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
|
|||
collect->next_aexpr_elt++;
|
||||
}
|
||||
|
||||
static void
|
||||
process_tracepoint_on_disconnect (void)
|
||||
{
|
||||
VEC(breakpoint_p) *tp_vec = NULL;
|
||||
int ix;
|
||||
struct breakpoint *b;
|
||||
int has_pending_p = 0;
|
||||
|
||||
/* Check whether we still have pending tracepoint. If we have, warn the
|
||||
user that pending tracepoint will no longer work. */
|
||||
tp_vec = all_tracepoints ();
|
||||
for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
|
||||
{
|
||||
if (b->loc == NULL)
|
||||
{
|
||||
has_pending_p = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct bp_location *loc1;
|
||||
|
||||
for (loc1 = b->loc; loc1; loc1 = loc1->next)
|
||||
{
|
||||
if (loc1->shlib_disabled)
|
||||
{
|
||||
has_pending_p = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_pending_p)
|
||||
break;
|
||||
}
|
||||
}
|
||||
VEC_free (breakpoint_p, tp_vec);
|
||||
|
||||
if (has_pending_p)
|
||||
warning (_("Pending tracepoints will not be resolved while"
|
||||
" GDB is disconnected\n"));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
start_tracing (void)
|
||||
|
@ -2020,6 +2062,8 @@ disconnect_tracing (int from_tty)
|
|||
disconnected-tracing. */
|
||||
if (current_trace_status ()->running && from_tty)
|
||||
{
|
||||
process_tracepoint_on_disconnect ();
|
||||
|
||||
if (current_trace_status ()->disconnected_tracing)
|
||||
{
|
||||
if (!query (_("Trace is running and will "
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue