+2012-03-08 Yao Qi <yao@codesourcery.com>
+ Pedro Alves <palves@redhat.com>
+
+ Fix PR server/13392.
+ * linux-x86-low.c (amd64_install_fast_tracepoint_jump_pad): Check
+ offset of JMP insn.
+ * tracepoint.c (remove_tracepoint): New.
+ (cmd_qtdp): Call remove_tracepoint when failed to install.
+
2012-03-07 Pedro Alves <palves@redhat.com>
* linux-low.c (get_detach_signal): New.
#include <stddef.h>
#include <signal.h>
#include <limits.h>
+#include <inttypes.h>
#include "server.h"
#include "linux-low.h"
#include "i387-fp.h"
{
unsigned char buf[40];
int i, offset;
+ int64_t loffset;
+
CORE_ADDR buildaddr = *jump_entry;
/* Build the jump pad. */
*adjusted_insn_addr_end = buildaddr;
/* Finally, write a jump back to the program. */
- offset = (tpaddr + orig_size) - (buildaddr + sizeof (jump_insn));
+
+ loffset = (tpaddr + orig_size) - (buildaddr + sizeof (jump_insn));
+ if (loffset > INT_MAX || loffset < INT_MIN)
+ {
+ sprintf (err,
+ "E.Jump back from jump pad too far from tracepoint "
+ "(offset 0x%" PRIx64 " > int32).", loffset);
+ return 1;
+ }
+
+ offset = (int) loffset;
memcpy (buf, jump_insn, sizeof (jump_insn));
memcpy (buf + 1, &offset, 4);
append_insns (&buildaddr, sizeof (jump_insn), buf);
is always done last (by our caller actually), so that we can
install fast tracepoints with threads running. This relies on
the agent's atomic write support. */
- offset = *jump_entry - (tpaddr + sizeof (jump_insn));
+ loffset = *jump_entry - (tpaddr + sizeof (jump_insn));
+ if (loffset > INT_MAX || loffset < INT_MIN)
+ {
+ sprintf (err,
+ "E.Jump pad too far from tracepoint "
+ "(offset 0x%" PRIx64 " > int32).", loffset);
+ return 1;
+ }
+
+ offset = (int) loffset;
+
memcpy (buf, jump_insn, sizeof (jump_insn));
memcpy (buf + 1, &offset, 4);
memcpy (jjump_pad_insn, buf, sizeof (jump_insn));
return NULL;
}
+/* Remove TPOINT from global list. */
+
+static void
+remove_tracepoint (struct tracepoint *tpoint)
+{
+ struct tracepoint *tp, *tp_prev;
+
+ for (tp = tracepoints, tp_prev = NULL; tp && tp != tpoint;
+ tp_prev = tp, tp = tp->next)
+ ;
+
+ if (tp)
+ {
+ if (tp_prev)
+ tp_prev->next = tp->next;
+ else
+ tracepoints = tp->next;
+
+ xfree (tp);
+ }
+}
+
/* There may be several tracepoints with the same number (because they
are "locations", in GDB parlance); return the next one after the
given tracepoint, or search from the beginning of the list if the
download_tracepoint (tpoint);
install_tracepoint (tpoint, own_buf);
+ if (strcmp (own_buf, "OK") != 0)
+ remove_tracepoint (tpoint);
unpause_all (1);
return;
+2012-03-08 Yao Qi <yao@codesourcery.com>
+ Pedro Alves <palves@redhat.com>
+
+ Fix PR server/13392.
+ * gdb.trace/change-loc.exp (tracepoint_change_loc_1): Remove kfail.
+ (tracepoint_change_loc_2): Remove kfail. Return if failed to
+ download tracepoints.
+ * gdb.trace/pending.exp (pending_tracepoint_works): Likewise.
+ (pending_tracepoint_resolved_during_trace): Likewise.
+ (pending_tracepoint_installed_during_trace): Likewise.
+ (pending_tracepoint_with_action_resolved): Likewise.
+
2012-03-08 Keith Seitz <keiths@redhat.com>
* gdb.ada/array_bounds.exp: Get breakpoint for line
gdb_test "continue" ".*Breakpoint.*marker.*at.*$srcfile.*" \
"continue to marker 1"
# Set a tracepoint during tracing.
- gdb_test "${trace_type} set_tracepoint" ".*" "set tracepoint on set_tracepoint"
+ set test "set tracepoint on set_tracepoint"
+ gdb_test_multiple "${trace_type} set_tracepoint" $test {
+ -re "Target returns error code .* too far .*$gdb_prompt $" {
+ if [string equal $trace_type "ftrace"] {
+ # The target was unable to install the fast tracepoint
+ # (e.g., jump pad too far from tracepoint).
+ pass "$test (too far)"
+ } else {
+ fail $test
+ }
+ }
+ -re "\r\n$gdb_prompt $" {
+ pass $test
+ }
+ }
gdb_trace_setactions "set action for tracepoint" "" \
"collect \$$pcreg" "^$"
\[0-9\]+\[\t \]+\(|fast \)tracepoint\[ \]+keep y.*\<MULTIPLE\>.*4\.1.* in func4.*4\.2.* in func4.*" \
"tracepoint with two locations"
- 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"
- return
- }
+ set test "continue to marker 2"
+ gdb_test_multiple "continue" $test {
+ -re "Target returns error code .* too far .*$gdb_prompt $" {
+ if [string equal $trace_type "ftrace"] {
+ # Expected if the target was unable to install the
+ # fast tracepoint (e.g., jump pad too far from
+ # tracepoint).
+ pass "$test (too far)"
+ # Skip the rest of the tests.
+ return
+ } else {
+ fail "continue to marker 2"
+ fail $test
+ }
+
+ }
+ -re ".*Breakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
+ pass "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.*
"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"
- return
+ set test "tstart"
+ gdb_test_multiple "tstart" $test {
+ -re "^tstart\r\n$gdb_prompt $" {
+ pass "tstart"
+ }
+ -re "Target returns error code .* too far .*$gdb_prompt $" {
+ if [string equal $trace_type "ftrace"] {
+ # The target was unable to install the fast tracepoint
+ # (e.g., jump pad too far from tracepoint).
+ pass "$test (too far)"
+ # Skip the rest of the tests.
+ return
+ } else {
+ fail $test
+ }
}
}
+ gdb_test "continue" ".*Breakpoint.*marker.*at.*$srcfile.*" \
+ "continue to marker 1"
+
gdb_test "continue" ".*Breakpoint.*marker.*at.*$srcfile.*" \
"continue to marker 2"
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"
+ set test "start trace experiment"
+ gdb_test_multiple "tstart" $test {
+ -re "^tstart\r\n$gdb_prompt $" {
+ pass $test
}
- -re ".*$gdb_prompt $" {
- kfail "gdb/13392" "continue to marker"
- return
+ -re "Target returns error code .* too far .*$gdb_prompt $" {
+ if [string equal $trace_type "ftrace"] {
+ # The target was unable to install the fast tracepoint
+ # (e.g., jump pad too far from tracepoint).
+ pass "$test (too far)"
+ # Skip the rest of the tests.
+ return
+ } else {
+ fail $test
+ }
}
+
}
+ gdb_test "continue" "Continuing.\r\n\r\nBreakpoint.*marker.*at.*$srcfile.*" \
+ "continue to marker"
+
gdb_test "tstop" "\[\r\n\]+" "stop trace experiment"
gdb_test "tfind start" "#0 .*" "tfind test frame 0"
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"
+ set test "continue to marker 2"
+ gdb_test_multiple "continue" $test {
+ -re "Target returns error code .* too far .*$gdb_prompt $" {
+ if [string equal $trace_type "ftrace"] {
+ # Expected if the target was unable to install the
+ # fast tracepoint (e.g., jump pad too far from
+ # tracepoint).
+ pass "$test (too far)"
+ # Skip the rest of the tests.
+ return
+ } else {
+ fail $test
+ }
}
- -re ".*$gdb_prompt $" {
- kfail "gdb/13392" "continue to marker 2"
- return
+ -re "Continuing.\r\n\r\nBreakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
+ pass $test
}
}
\[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"
- return
+ set test "continue to marker 2"
+ gdb_test_multiple "continue" $test {
+ -re "Target returns error code .* too far .*$gdb_prompt $" {
+ if [string equal $trace_type "ftrace"] {
+ # Expected if the target was unable to install the
+ # fast tracepoint (e.g., jump pad too far from
+ # tracepoint).
+ pass "$test (too far)"
+ # Skip the rest of the tests.
+ return
+ } else {
+ fail $test
+ }
}
+ -re "Continuing.\r\n\r\nBreakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
+ pass $test
+ }
}
gdb_test "tstop" "\[\r\n\]+" "stop 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" {
+ set test "continue to marker 2"
+ gdb_test_multiple "continue" $test {
+ -re "Target returns error code .* too far .*$gdb_prompt $" {
+ if [string equal $trace_type "ftrace"] {
+ # Expected if the target was unable to install the
+ # fast tracepoint (e.g., jump pad too far from
+ # tracepoint).
+ pass "$test (too far)"
+ # Skip the rest of the tests.
+ return
+ } else {
+ fail $test
+ }
+ }
-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"
- return
- }
+
}
gdb_test "tstop" "\[\r\n\]+" "stop trace experiment"