Make tracepoint operations go through target vector.

* target.h (enum trace_find_type): New enum.
	(struct target_ops): New fields to_trace_init,
	to_download_tracepoint, to_download_trace_state_variable,
	to_trace_set_readonly_regions, to_trace_start, to_get_trace_status,
	to_trace_stop, to_trace_find, to_get_trace_state_variable_value,
	to_set_disconnected_tracing.
	(target_trace_init): New macro.
	(target_download_tracepoint): New macro.
	(target_download_trace_state_variable): New macro.
	(target_trace_start): New macro.
	(target_trace_set_readonly_regions): New macro.
	(target_get_trace_status): New macro.
	(target_trace_stop): New macro.
	(target_trace_find): New macro.
	(target_get_trace_state_variable_value): New macro.
	(target_set_disconnected_tracing): New macro.
	* target.c (update_current_target): Inherit and set defaults for
	tracepoint operations.
	* tracepoint.c (default_collect): Make globally visible.
	(target_is_remote): Remove, along with all calls.
	(tvariables_info): Call target_get_trace_state_variable_value.
	(remote_set_transparent_ranges): Remove.
	(trace_start_command): Call target_trace_init,
	target_download_tracepoint, etc.
	(download_tracepoint): Remove.
	(trace_stop_command): Simplify.
	(stop_tracing): Call target_trace_stop.
	(get_trace_status): Call target_get_trace_status.
	(trace_status_command): Add case for targets that cannot trace.
	(finish_tfind_command): Change to take numerical arguments, call
	target_trace_find.
	(trace_find_command): Update call to finish_tfind_command.
	(trace_find_pc_command): Ditto.
	(trace_find_tracepoint_command): Ditto.
	(trace_find_line_command): Ditto.
	(trace_find_range_command): Ditto.
	(trace_find_outside_command): Ditto.
	(set_disconnected_tracing_value): Call
	target_set_disconnected_tracing.
	* remote.c: Add protocol encoding bits from tracepoint.c.
	(trace_error): Move from tracepoint.c.
	(remote_get_noisy_reply): Ditto.
	(free_actions_list_cleanup_wrapper): Ditto.
	(free_actions_list): Ditto.
	(remote_trace_init): New function.
	(remote_download_tracepoint): New function.
	(remote_download_trace_state_variable): New function.
	(remote_trace_set_readonly_regions): New function.
	(remote_trace_start): New function.
	(remote_get_trace_status): New function.
	(remote_trace_stop): New function.
	(remote_trace_find): New function.
	(remote_download_trace_state_variable): New function.
	(remote_set_disconnected_tracing): New function.
	(init_remote_ops): Add tracepoint operations.
This commit is contained in:
Stan Shebs 2010-01-07 19:17:46 +00:00
parent 3f08eb3589
commit 35b1e5cca0
6 changed files with 847 additions and 656 deletions

View File

@ -1,5 +1,62 @@
2010-01-07 Stan Shebs <stan@codesourcery.com> 2010-01-07 Stan Shebs <stan@codesourcery.com>
Make tracepoint operations go through target vector.
* target.h (enum trace_find_type): New enum.
(struct target_ops): New fields to_trace_init,
to_download_tracepoint, to_download_trace_state_variable,
to_trace_set_readonly_regions, to_trace_start, to_get_trace_status,
to_trace_stop, to_trace_find, to_get_trace_state_variable_value,
to_set_disconnected_tracing.
(target_trace_init): New macro.
(target_download_tracepoint): New macro.
(target_download_trace_state_variable): New macro.
(target_trace_start): New macro.
(target_trace_set_readonly_regions): New macro.
(target_get_trace_status): New macro.
(target_trace_stop): New macro.
(target_trace_find): New macro.
(target_get_trace_state_variable_value): New macro.
(target_set_disconnected_tracing): New macro.
* target.c (update_current_target): Inherit and set defaults for
tracepoint operations.
* tracepoint.c (default_collect): Make globally visible.
(target_is_remote): Remove, along with all calls.
(tvariables_info): Call target_get_trace_state_variable_value.
(remote_set_transparent_ranges): Remove.
(trace_start_command): Call target_trace_init,
target_download_tracepoint, etc.
(download_tracepoint): Remove.
(trace_stop_command): Simplify.
(stop_tracing): Call target_trace_stop.
(get_trace_status): Call target_get_trace_status.
(trace_status_command): Add case for targets that cannot trace.
(finish_tfind_command): Change to take numerical arguments, call
target_trace_find.
(trace_find_command): Update call to finish_tfind_command.
(trace_find_pc_command): Ditto.
(trace_find_tracepoint_command): Ditto.
(trace_find_line_command): Ditto.
(trace_find_range_command): Ditto.
(trace_find_outside_command): Ditto.
(set_disconnected_tracing_value): Call
target_set_disconnected_tracing.
* remote.c: Add protocol encoding bits from tracepoint.c.
(trace_error): Move from tracepoint.c.
(remote_get_noisy_reply): Ditto.
(free_actions_list_cleanup_wrapper): Ditto.
(free_actions_list): Ditto.
(remote_trace_init): New function.
(remote_download_tracepoint): New function.
(remote_download_trace_state_variable): New function.
(remote_trace_set_readonly_regions): New function.
(remote_trace_start): New function.
(remote_get_trace_status): New function.
(remote_trace_stop): New function.
(remote_trace_find): New function.
(remote_download_trace_state_variable): New function.
(remote_set_disconnected_tracing): New function.
(init_remote_ops): Add tracepoint operations.
* tracepoint.c (trace_dump_command): Don't decr_pc_after_break. * tracepoint.c (trace_dump_command): Don't decr_pc_after_break.
2010-01-07 Tristan Gingold <gingold@adacore.com> 2010-01-07 Tristan Gingold <gingold@adacore.com>

View File

@ -63,6 +63,17 @@
#include "memory-map.h" #include "memory-map.h"
#include "tracepoint.h"
#include "ax.h"
#include "ax-gdb.h"
/* temp hacks for tracepoint encoding migration */
static char *target_buf;
static long target_buf_size;
/*static*/ void
encode_actions (struct breakpoint *t, char ***tdp_actions,
char ***stepping_actions);
/* The size to align memory write packets, when practical. The protocol /* The size to align memory write packets, when practical. The protocol
does not guarantee any alignment, and gdb will generate short does not guarantee any alignment, and gdb will generate short
writes and unaligned writes, but even as a best-effort attempt this writes and unaligned writes, but even as a best-effort attempt this
@ -368,6 +379,52 @@ struct remote_arch_state
long remote_packet_size; long remote_packet_size;
}; };
long sizeof_pkt = 2000;
/* Utility: generate error from an incoming stub packet. */
static void
trace_error (char *buf)
{
if (*buf++ != 'E')
return; /* not an error msg */
switch (*buf)
{
case '1': /* malformed packet error */
if (*++buf == '0') /* general case: */
error (_("remote.c: error in outgoing packet."));
else
error (_("remote.c: error in outgoing packet at field #%ld."),
strtol (buf, NULL, 16));
case '2':
error (_("trace API error 0x%s."), ++buf);
default:
error (_("Target returns error code '%s'."), buf);
}
}
/* Utility: wait for reply from stub, while accepting "O" packets. */
static char *
remote_get_noisy_reply (char **buf_p,
long *sizeof_buf)
{
do /* Loop on reply from remote stub. */
{
char *buf;
QUIT; /* allow user to bail out with ^C */
getpkt (buf_p, sizeof_buf, 0);
buf = *buf_p;
if (buf[0] == 0)
error (_("Target does not support this command."));
else if (buf[0] == 'E')
trace_error (buf);
else if (buf[0] == 'O' &&
buf[1] != 'K')
remote_console_output (buf + 1); /* 'O' message from stub */
else
return buf; /* here's the actual reply */
}
while (1);
}
/* Handle for retreving the remote protocol data from gdbarch. */ /* Handle for retreving the remote protocol data from gdbarch. */
static struct gdbarch_data *remote_gdbarch_data_handle; static struct gdbarch_data *remote_gdbarch_data_handle;
@ -8942,6 +8999,331 @@ remote_supports_fast_tracepoints (void)
return rs->fast_tracepoints; return rs->fast_tracepoints;
} }
static void
remote_trace_init ()
{
putpkt ("QTinit");
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Target does not support this command."));
}
static void free_actions_list (char **actions_list);
static void free_actions_list_cleanup_wrapper (void *);
static void
free_actions_list_cleanup_wrapper (void *al)
{
free_actions_list (al);
}
static void
free_actions_list (char **actions_list)
{
int ndx;
if (actions_list == 0)
return;
for (ndx = 0; actions_list[ndx]; ndx++)
xfree (actions_list[ndx]);
xfree (actions_list);
}
static void
remote_download_tracepoint (struct breakpoint *t)
{
CORE_ADDR tpaddr;
char tmp[40];
char buf[2048];
char **tdp_actions;
char **stepping_actions;
int ndx;
struct cleanup *old_chain = NULL;
struct agent_expr *aexpr;
struct cleanup *aexpr_chain = NULL;
char *pkt;
encode_actions (t, &tdp_actions, &stepping_actions);
old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
tdp_actions);
(void) make_cleanup (free_actions_list_cleanup_wrapper, stepping_actions);
tpaddr = t->loc->address;
sprintf_vma (tmp, (t->loc ? tpaddr : 0));
sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number,
tmp, /* address */
(t->enable_state == bp_enabled ? 'E' : 'D'),
t->step_count, t->pass_count);
/* Fast tracepoints are mostly handled by the target, but we can
tell the target how big of an instruction block should be moved
around. */
if (t->type == bp_fast_tracepoint)
{
/* Only test for support at download time; we may not know
target capabilities at definition time. */
if (remote_supports_fast_tracepoints ())
{
int isize;
if (gdbarch_fast_tracepoint_valid_at (target_gdbarch,
tpaddr, &isize, NULL))
sprintf (buf + strlen (buf), ":F%x", isize);
else
/* If it passed validation at definition but fails now,
something is very wrong. */
internal_error (__FILE__, __LINE__,
"Fast tracepoint not valid during download");
}
else
/* Fast tracepoints are functionally identical to regular
tracepoints, so don't take lack of support as a reason to
give up on the trace run. */
warning (_("Target does not support fast tracepoints, downloading %d as regular tracepoint"), t->number);
}
/* If the tracepoint has a conditional, make it into an agent
expression and append to the definition. */
if (t->loc->cond)
{
/* Only test support at download time, we may not know target
capabilities at definition time. */
if (remote_supports_cond_tracepoints ())
{
aexpr = gen_eval_for_expr (t->loc->address, t->loc->cond);
aexpr_chain = make_cleanup_free_agent_expr (aexpr);
sprintf (buf + strlen (buf), ":X%x,", aexpr->len);
pkt = buf + strlen (buf);
for (ndx = 0; ndx < aexpr->len; ++ndx)
pkt = pack_hex_byte (pkt, aexpr->buf[ndx]);
*pkt = '\0';
do_cleanups (aexpr_chain);
}
else
warning (_("Target does not support conditional tracepoints, ignoring tp %d cond"), t->number);
}
if (t->actions || *default_collect)
strcat (buf, "-");
putpkt (buf);
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Target does not support tracepoints."));
if (!t->actions && !*default_collect)
return;
/* do_single_steps (t); */
if (tdp_actions)
{
for (ndx = 0; tdp_actions[ndx]; ndx++)
{
QUIT; /* allow user to bail out with ^C */
sprintf (buf, "QTDP:-%x:%s:%s%c",
t->number, tmp, /* address */
tdp_actions[ndx],
((tdp_actions[ndx + 1] || stepping_actions)
? '-' : 0));
putpkt (buf);
remote_get_noisy_reply (&target_buf,
&target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Error on target while setting tracepoints."));
}
}
if (stepping_actions)
{
for (ndx = 0; stepping_actions[ndx]; ndx++)
{
QUIT; /* allow user to bail out with ^C */
sprintf (buf, "QTDP:-%x:%s:%s%s%s",
t->number, tmp, /* address */
((ndx == 0) ? "S" : ""),
stepping_actions[ndx],
(stepping_actions[ndx + 1] ? "-" : ""));
putpkt (buf);
remote_get_noisy_reply (&target_buf,
&target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Error on target while setting tracepoints."));
}
}
do_cleanups (old_chain);
return;
}
static void
remote_download_trace_state_variable (struct trace_state_variable *tsv)
{
struct remote_state *rs = get_remote_state ();
sprintf (rs->buf, "QTDV:%x:%s",
tsv->number, phex ((ULONGEST) tsv->initial_value, 8));
putpkt (rs->buf);
remote_get_noisy_reply (&target_buf, &target_buf_size);
}
static void
remote_trace_set_readonly_regions ()
{
asection *s;
bfd_size_type size;
bfd_vma lma;
int anysecs = 0;
if (!exec_bfd)
return; /* No information to give. */
strcpy (target_buf, "QTro");
for (s = exec_bfd->sections; s; s = s->next)
{
char tmp1[40], tmp2[40];
if ((s->flags & SEC_LOAD) == 0 ||
/* (s->flags & SEC_CODE) == 0 || */
(s->flags & SEC_READONLY) == 0)
continue;
anysecs = 1;
lma = s->lma;
size = bfd_get_section_size (s);
sprintf_vma (tmp1, lma);
sprintf_vma (tmp2, lma + size);
sprintf (target_buf + strlen (target_buf),
":%s,%s", tmp1, tmp2);
}
if (anysecs)
{
putpkt (target_buf);
getpkt (&target_buf, &target_buf_size, 0);
}
}
static void
remote_trace_start ()
{
putpkt ("QTStart");
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Bogus reply from target: %s"), target_buf);
}
static int
remote_get_trace_status (int *stop_reason)
{
putpkt ("qTStatus");
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (target_buf[0] != 'T' ||
(target_buf[1] != '0' && target_buf[1] != '1'))
error (_("Bogus trace status reply from target: %s"), target_buf);
return (target_buf[1] == '1');
}
static void
remote_trace_stop ()
{
putpkt ("QTStop");
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Bogus reply from target: %s"), target_buf);
}
static int
remote_trace_find (enum trace_find_type type, int num,
ULONGEST addr1, ULONGEST addr2,
int *tpp)
{
struct remote_state *rs = get_remote_state ();
char *p, *reply;
int target_frameno = -1, target_tracept = -1;
p = rs->buf;
strcpy (p, "QTFrame:");
p = strchr (p, '\0');
switch (type)
{
case tfind_number:
sprintf (p, "%x", num);
break;
case tfind_pc:
sprintf (p, "pc:%s", paddress (target_gdbarch, addr1));
break;
case tfind_tp:
sprintf (p, "tdp:%x", num);
break;
case tfind_range:
sprintf (p, "range:%s:%s", paddress (target_gdbarch, addr1), paddress (target_gdbarch, addr2));
break;
case tfind_outside:
sprintf (p, "outside:%s:%s", paddress (target_gdbarch, addr1), paddress (target_gdbarch, addr2));
break;
default:
error ("Unknown trace find type %d", type);
}
putpkt (rs->buf);
reply = remote_get_noisy_reply (&(rs->buf), &sizeof_pkt);
while (reply && *reply)
switch (*reply)
{
case 'F':
if ((target_frameno = (int) strtol (++reply, &reply, 16)) == -1)
error (_("Target failed to find requested trace frame."));
break;
case 'T':
if ((target_tracept = (int) strtol (++reply, &reply, 16)) == -1)
error (_("Target failed to find requested trace frame."));
break;
case 'O': /* "OK"? */
if (reply[1] == 'K' && reply[2] == '\0')
reply += 2;
else
error (_("Bogus reply from target: %s"), reply);
break;
default:
error (_("Bogus reply from target: %s"), reply);
}
if (tpp)
*tpp = target_tracept;
return target_frameno;
}
static int
remote_get_trace_state_variable_value (int tsvnum, LONGEST *val)
{
struct remote_state *rs = get_remote_state ();
char *reply;
ULONGEST uval;
sprintf (rs->buf, "qTV:%x", tsvnum);
putpkt (rs->buf);
reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
if (reply && *reply)
{
if (*reply == 'V')
{
unpack_varlen_hex (reply + 1, &uval);
*val = (LONGEST) uval;
return 1;
}
}
return 0;
}
static void
remote_set_disconnected_tracing (int val)
{
struct remote_state *rs = get_remote_state ();
sprintf (rs->buf, "QTDisconnected:%x", val);
putpkt (rs->buf);
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Target does not support this command."));
}
static void static void
init_remote_ops (void) init_remote_ops (void)
{ {
@ -9005,6 +9387,16 @@ Specify the serial device it is connected to\n\
remote_ops.to_terminal_ours = remote_terminal_ours; remote_ops.to_terminal_ours = remote_terminal_ours;
remote_ops.to_supports_non_stop = remote_supports_non_stop; remote_ops.to_supports_non_stop = remote_supports_non_stop;
remote_ops.to_supports_multi_process = remote_supports_multi_process; remote_ops.to_supports_multi_process = remote_supports_multi_process;
remote_ops.to_trace_init = remote_trace_init;
remote_ops.to_download_tracepoint = remote_download_tracepoint;
remote_ops.to_download_trace_state_variable = remote_download_trace_state_variable;
remote_ops.to_trace_set_readonly_regions = remote_trace_set_readonly_regions;
remote_ops.to_trace_start = remote_trace_start;
remote_ops.to_get_trace_status = remote_get_trace_status;
remote_ops.to_trace_stop = remote_trace_stop;
remote_ops.to_trace_find = remote_trace_find;
remote_ops.to_get_trace_state_variable_value = remote_get_trace_state_variable_value;
remote_ops.to_set_disconnected_tracing = remote_set_disconnected_tracing;
} }
/* Set up the extended remote vector by making a copy of the standard /* Set up the extended remote vector by making a copy of the standard
@ -9227,7 +9619,6 @@ remote_get_tracing_state (struct remote_state *rs)
struct uploaded_tp *utp; struct uploaded_tp *utp;
struct breakpoint *t; struct breakpoint *t;
extern void get_trace_status (); extern void get_trace_status ();
extern unsigned long trace_running_p;
get_trace_status (); get_trace_status ();
if (trace_running_p) if (trace_running_p)
@ -9646,4 +10037,7 @@ Show the remote pathname for \"run\""), NULL, NULL, NULL,
magic_null_ptid = ptid_build (42000, 1, -1); magic_null_ptid = ptid_build (42000, 1, -1);
not_sent_ptid = ptid_build (42000, 1, -2); not_sent_ptid = ptid_build (42000, 1, -2);
any_thread_ptid = ptid_build (42000, 1, 0); any_thread_ptid = ptid_build (42000, 1, 0);
target_buf_size = 2048;
target_buf = xmalloc (target_buf_size);
} }

View File

@ -685,6 +685,16 @@ update_current_target (void)
INHERIT (to_get_ada_task_ptid, t); INHERIT (to_get_ada_task_ptid, t);
/* Do not inherit to_search_memory. */ /* Do not inherit to_search_memory. */
INHERIT (to_supports_multi_process, t); INHERIT (to_supports_multi_process, t);
INHERIT (to_trace_init, t);
INHERIT (to_download_tracepoint, t);
INHERIT (to_download_trace_state_variable, t);
INHERIT (to_trace_set_readonly_regions, t);
INHERIT (to_trace_start, t);
INHERIT (to_get_trace_status, t);
INHERIT (to_trace_stop, t);
INHERIT (to_trace_find, t);
INHERIT (to_get_trace_state_variable_value, t);
INHERIT (to_set_disconnected_tracing, t);
INHERIT (to_magic, t); INHERIT (to_magic, t);
/* Do not inherit to_memory_map. */ /* Do not inherit to_memory_map. */
/* Do not inherit to_flash_erase. */ /* Do not inherit to_flash_erase. */
@ -833,6 +843,36 @@ update_current_target (void)
de_fault (to_supports_multi_process, de_fault (to_supports_multi_process,
(int (*) (void)) (int (*) (void))
return_zero); return_zero);
de_fault (to_trace_init,
(void (*) (void))
tcomplain);
de_fault (to_download_tracepoint,
(void (*) (struct breakpoint *))
tcomplain);
de_fault (to_download_trace_state_variable,
(void (*) (struct trace_state_variable *))
tcomplain);
de_fault (to_trace_set_readonly_regions,
(void (*) (void))
tcomplain);
de_fault (to_trace_start,
(void (*) (void))
tcomplain);
de_fault (to_get_trace_status,
(int (*) (int *))
return_minus_one);
de_fault (to_trace_stop,
(void (*) (void))
tcomplain);
de_fault (to_trace_find,
(int (*) (enum trace_find_type, int, ULONGEST, ULONGEST, int *))
return_zero);
de_fault (to_get_trace_state_variable_value,
(int (*) (int, LONGEST *))
return_zero);
de_fault (to_set_disconnected_tracing,
(void (*) (int))
tcomplain);
#undef de_fault #undef de_fault
/* Finally, position the target-stack beneath the squashed /* Finally, position the target-stack beneath the squashed

View File

@ -31,6 +31,7 @@ struct target_ops;
struct bp_target_info; struct bp_target_info;
struct regcache; struct regcache;
struct target_section_table; struct target_section_table;
struct trace_state_variable;
/* This include file defines the interface between the main part /* This include file defines the interface between the main part
of the debugger, and the part which is target-specific, or of the debugger, and the part which is target-specific, or
@ -258,6 +259,18 @@ enum target_object
/* Possible future objects: TARGET_OBJECT_FILE, ... */ /* Possible future objects: TARGET_OBJECT_FILE, ... */
}; };
/* Enumeration of the kinds of traceframe searches that a target may
be able to perform. */
enum trace_find_type
{
tfind_number,
tfind_pc,
tfind_tp,
tfind_range,
tfind_outside,
};
/* Request that OPS transfer up to LEN 8-bit bytes of the target's /* Request that OPS transfer up to LEN 8-bit bytes of the target's
OBJECT. The OFFSET, for a seekable object, specifies the OBJECT. The OFFSET, for a seekable object, specifies the
starting point. The ANNEX can be used to provide additional starting point. The ANNEX can be used to provide additional
@ -597,6 +610,47 @@ struct target_ops
struct address_space *(*to_thread_address_space) (struct target_ops *, struct address_space *(*to_thread_address_space) (struct target_ops *,
ptid_t); ptid_t);
/* Tracepoint-related operations. */
/* Prepare the target for a tracing run. */
void (*to_trace_init) (void);
/* Send full details of a tracepoint to the target. */
void (*to_download_tracepoint) (struct breakpoint *t);
/* Send full details of a trace state variable to the target. */
void (*to_download_trace_state_variable) (struct trace_state_variable *tsv);
/* Inform the target info of memory regions that are readonly
(such as text sections), and so it should return data from
those rather than look in the trace buffer. */
void (*to_trace_set_readonly_regions) (void);
/* Start a trace run. */
void (*to_trace_start) (void);
/* Get the current status of a tracing run. */
int (*to_get_trace_status) (int *stop_reason);
/* Stop a trace run. */
void (*to_trace_stop) (void);
/* Ask the target to find a trace frame of the given type TYPE,
using NUM, ADDR1, and ADDR2 as search parameters. Returns the
number of the trace frame, and also the tracepoint number at
TPP. */
int (*to_trace_find) (enum trace_find_type type, int num,
ULONGEST addr1, ULONGEST addr2, int *tpp);
/* Get the value of the trace state variable number TSV, returning
1 if the value is known and writing the value itself into the
location pointed to by VAL, else returning 0. */
int (*to_get_trace_state_variable_value) (int tsv, LONGEST *val);
/* Set the target's tracing behavior in response to unexpected
disconnection - set VAL to 1 to keep tracing, 0 to stop. */
void (*to_set_disconnected_tracing) (int val);
int to_magic; int to_magic;
/* Need sub-structure for target machine related rather than comm related? /* Need sub-structure for target machine related rather than comm related?
*/ */
@ -1238,6 +1292,38 @@ extern int target_search_memory (CORE_ADDR start_addr,
ULONGEST pattern_len, ULONGEST pattern_len,
CORE_ADDR *found_addrp); CORE_ADDR *found_addrp);
/* Tracepoint-related operations. */
#define target_trace_init() \
(*current_target.to_trace_init) ()
#define target_download_tracepoint(t) \
(*current_target.to_download_tracepoint) (t)
#define target_download_trace_state_variable(tsv) \
(*current_target.to_download_trace_state_variable) (tsv)
#define target_trace_start() \
(*current_target.to_trace_start) ()
#define target_trace_set_readonly_regions() \
(*current_target.to_trace_set_readonly_regions) ()
#define target_get_trace_status(stop_reason) \
(*current_target.to_get_trace_status) (stop_reason)
#define target_trace_stop() \
(*current_target.to_trace_stop) ()
#define target_trace_find(type,num,addr1,addr2,tpp) \
(*current_target.to_trace_find) ((type), (num), (addr1), (addr2), (tpp))
#define target_get_trace_state_variable_value(tsv,val) \
(*current_target.to_get_trace_state_variable_value) ((tsv), (val))
#define target_set_disconnected_tracing(val) \
(*current_target.to_set_disconnected_tracing) (val)
/* Command logging facility. */ /* Command logging facility. */
#define target_log_command(p) \ #define target_log_command(p) \

View File

@ -32,10 +32,6 @@
#include "inferior.h" #include "inferior.h"
#include "breakpoint.h" #include "breakpoint.h"
#include "tracepoint.h" #include "tracepoint.h"
#include "remote.h"
extern int remote_supports_cond_tracepoints (void);
extern int remote_supports_fast_tracepoints (void);
extern char *unpack_varlen_hex (char *buff, ULONGEST *result);
#include "linespec.h" #include "linespec.h"
#include "regcache.h" #include "regcache.h"
#include "completer.h" #include "completer.h"
@ -46,6 +42,7 @@ extern char *unpack_varlen_hex (char *buff, ULONGEST *result);
#include "valprint.h" #include "valprint.h"
#include "gdbcore.h" #include "gdbcore.h"
#include "objfiles.h" #include "objfiles.h"
#include "filenames.h"
#include "ax.h" #include "ax.h"
#include "ax-gdb.h" #include "ax-gdb.h"
@ -144,13 +141,10 @@ static struct symtab_and_line traceframe_sal;
static struct cmd_list_element *tfindlist; static struct cmd_list_element *tfindlist;
/* List of expressions to collect by default at each tracepoint hit. */ /* List of expressions to collect by default at each tracepoint hit. */
static char *default_collect = ""; char *default_collect = "";
static int disconnected_tracing; static int disconnected_tracing;
static char *target_buf;
static long target_buf_size;
/* ======= Important command functions: ======= */ /* ======= Important command functions: ======= */
static void trace_actions_command (char *, int); static void trace_actions_command (char *, int);
static void trace_start_command (char *, int); static void trace_start_command (char *, int);
@ -173,70 +167,11 @@ static char *mem2hex (gdb_byte *, char *, int);
static void add_register (struct collection_list *collection, static void add_register (struct collection_list *collection,
unsigned int regno); unsigned int regno);
static struct cleanup *make_cleanup_free_actions (struct breakpoint *t); static struct cleanup *make_cleanup_free_actions (struct breakpoint *t);
static void free_actions_list (char **actions_list);
static void free_actions_list_cleanup_wrapper (void *);
extern void send_disconnected_tracing_value (int value); extern void send_disconnected_tracing_value (int value);
extern void _initialize_tracepoint (void); extern void _initialize_tracepoint (void);
/* Utility: returns true if "target remote" */
static int
target_is_remote (void)
{
if (current_target.to_shortname &&
(strcmp (current_target.to_shortname, "remote") == 0
|| strcmp (current_target.to_shortname, "extended-remote") == 0))
return 1;
else
return 0;
}
/* Utility: generate error from an incoming stub packet. */
static void
trace_error (char *buf)
{
if (*buf++ != 'E')
return; /* not an error msg */
switch (*buf)
{
case '1': /* malformed packet error */
if (*++buf == '0') /* general case: */
error (_("tracepoint.c: error in outgoing packet."));
else
error (_("tracepoint.c: error in outgoing packet at field #%ld."),
strtol (buf, NULL, 16));
case '2':
error (_("trace API error 0x%s."), ++buf);
default:
error (_("Target returns error code '%s'."), buf);
}
}
/* Utility: wait for reply from stub, while accepting "O" packets. */
static char *
remote_get_noisy_reply (char **buf_p,
long *sizeof_buf)
{
do /* Loop on reply from remote stub. */
{
char *buf;
QUIT; /* allow user to bail out with ^C */
getpkt (buf_p, sizeof_buf, 0);
buf = *buf_p;
if (buf[0] == 0)
error (_("Target does not support this command."));
else if (buf[0] == 'E')
trace_error (buf);
else if (buf[0] == 'O' &&
buf[1] != 'K')
remote_console_output (buf + 1); /* 'O' message from stub */
else
return buf; /* here's the actual reply */
}
while (1);
}
/* Set traceframe number to NUM. */ /* Set traceframe number to NUM. */
static void static void
set_traceframe_num (int num) set_traceframe_num (int num)
@ -449,37 +384,17 @@ tvariables_info (char *args, int from_tty)
char *reply; char *reply;
ULONGEST tval; ULONGEST tval;
if (target_is_remote ())
{
char buf[20];
for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
{
/* We don't know anything about the value until we get a
valid packet. */
tsv->value_known = 0;
sprintf (buf, "qTV:%x", tsv->number);
putpkt (buf);
reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
if (reply && *reply)
{
if (*reply == 'V')
{
unpack_varlen_hex (reply + 1, &tval);
tsv->value = (LONGEST) tval;
tsv->value_known = 1;
}
/* FIXME say anything about oddball replies? */
}
}
}
if (VEC_length (tsv_s, tvariables) == 0) if (VEC_length (tsv_s, tvariables) == 0)
{ {
printf_filtered (_("No trace state variables.\n")); printf_filtered (_("No trace state variables.\n"));
return; return;
} }
/* Try to acquire values from the target. */
for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
tsv->value_known = target_get_trace_state_variable_value (tsv->number,
&(tsv->value));
printf_filtered (_("Name\t\t Initial\tCurrent\n")); printf_filtered (_("Name\t\t Initial\tCurrent\n"));
for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix) for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
@ -1293,28 +1208,8 @@ stringify_collection_list (struct collection_list *list, char *string)
return *str_list; return *str_list;
} }
static void
free_actions_list_cleanup_wrapper (void *al)
{
free_actions_list (al);
}
static void
free_actions_list (char **actions_list)
{
int ndx;
if (actions_list == 0)
return;
for (ndx = 0; actions_list[ndx]; ndx++)
xfree (actions_list[ndx]);
xfree (actions_list);
}
/* Render all actions into gdb protocol. */ /* Render all actions into gdb protocol. */
static void /*static*/ void
encode_actions (struct breakpoint *t, char ***tdp_actions, encode_actions (struct breakpoint *t, char ***tdp_actions,
char ***stepping_actions) char ***stepping_actions)
{ {
@ -1583,49 +1478,6 @@ add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
collect->next_aexpr_elt++; collect->next_aexpr_elt++;
} }
/* Set "transparent" memory ranges
Allow trace mechanism to treat text-like sections
(and perhaps all read-only sections) transparently,
i.e. don't reject memory requests from these address ranges
just because they haven't been collected. */
static void
remote_set_transparent_ranges (void)
{
asection *s;
bfd_size_type size;
bfd_vma lma;
int anysecs = 0;
if (!exec_bfd)
return; /* No information to give. */
strcpy (target_buf, "QTro");
for (s = exec_bfd->sections; s; s = s->next)
{
char tmp1[40], tmp2[40];
if ((s->flags & SEC_LOAD) == 0 ||
/* (s->flags & SEC_CODE) == 0 || */
(s->flags & SEC_READONLY) == 0)
continue;
anysecs = 1;
lma = s->lma;
size = bfd_get_section_size (s);
sprintf_vma (tmp1, lma);
sprintf_vma (tmp2, lma + size);
sprintf (target_buf + strlen (target_buf),
":%s,%s", tmp1, tmp2);
}
if (anysecs)
{
putpkt (target_buf);
getpkt (&target_buf, &target_buf_size, 0);
}
}
/* tstart command: /* tstart command:
Tell target to clear any previous trace experiment. Tell target to clear any previous trace experiment.
@ -1633,8 +1485,6 @@ remote_set_transparent_ranges (void)
to the target. If no errors, to the target. If no errors,
Tell target to start a new trace experiment. */ Tell target to start a new trace experiment. */
int download_tracepoint (struct breakpoint *t);
static void static void
trace_start_command (char *args, int from_tty) trace_start_command (char *args, int from_tty)
{ {
@ -1647,23 +1497,16 @@ trace_start_command (char *args, int from_tty)
dont_repeat (); /* Like "run", dangerous to repeat accidentally. */ dont_repeat (); /* Like "run", dangerous to repeat accidentally. */
if (target_is_remote ()) target_trace_init ();
{
putpkt ("QTinit");
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Target does not support this command."));
tp_vec = all_tracepoints (); tp_vec = all_tracepoints ();
for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++) for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
{ {
t->number_on_target = 0; t->number_on_target = 0;
if (download_tracepoint (t)) target_download_tracepoint (t);
{
t->number_on_target = t->number; t->number_on_target = t->number;
any_downloaded = 1; any_downloaded = 1;
} }
}
VEC_free (breakpoint_p, tp_vec); VEC_free (breakpoint_p, tp_vec);
/* No point in tracing without any tracepoints... */ /* No point in tracing without any tracepoints... */
@ -1671,206 +1514,61 @@ trace_start_command (char *args, int from_tty)
error ("No tracepoints downloaded, not starting trace"); error ("No tracepoints downloaded, not starting trace");
/* Init any trace state variables that start with nonzero values. */ /* Init any trace state variables that start with nonzero values. */
for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix) for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
{ {
if (tsv->initial_value != 0) if (tsv->initial_value != 0)
{ target_download_trace_state_variable (tsv);
sprintf (buf, "QTDV:%x:%s",
tsv->number, phex ((ULONGEST) tsv->initial_value, 8));
putpkt (buf);
remote_get_noisy_reply (&target_buf, &target_buf_size);
}
} }
/* Tell target to treat text-like sections as transparent. */ /* Tell target to treat text-like sections as transparent. */
remote_set_transparent_ranges (); target_trace_set_readonly_regions ();
/* Now insert traps and begin collecting data. */ /* Now insert traps and begin collecting data. */
putpkt ("QTStart"); target_trace_start ();
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK")) /* Reset our local state. */
error (_("Bogus reply from target: %s"), target_buf); set_traceframe_num (-1);
set_traceframe_num (-1); /* All old traceframes invalidated. */
set_tracepoint_num (-1); set_tracepoint_num (-1);
set_traceframe_context (NULL); set_traceframe_context (NULL);
trace_running_p = 1; trace_running_p = 1;
if (deprecated_trace_start_stop_hook)
deprecated_trace_start_stop_hook (1, from_tty);
}
else
error (_("Trace can only be run on remote targets."));
}
/* Send the definition of a single tracepoint to the target. Return 1
if successful, 0 if not. */
int
download_tracepoint (struct breakpoint *t)
{
CORE_ADDR tpaddr;
char tmp[40];
char buf[2048];
char **tdp_actions;
char **stepping_actions;
int ndx;
struct cleanup *old_chain = NULL;
struct agent_expr *aexpr;
struct cleanup *aexpr_chain = NULL;
tpaddr = t->loc->address;
sprintf_vma (tmp, (t->loc ? tpaddr : 0));
sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number,
tmp, /* address */
(t->enable_state == bp_enabled ? 'E' : 'D'),
t->step_count, t->pass_count);
/* Fast tracepoints are mostly handled by the target, but we can
tell the target how big of an instruction block should be moved
around. */
if (t->type == bp_fast_tracepoint)
{
/* Only test for support at download time; we may not know
target capabilities at definition time. */
if (remote_supports_fast_tracepoints ())
{
int isize;
if (gdbarch_fast_tracepoint_valid_at (get_current_arch (),
tpaddr, &isize, NULL))
sprintf (buf + strlen (buf), ":F%x", isize);
else
/* If it passed validation at definition but fails now,
something is very wrong. */
internal_error (__FILE__, __LINE__,
"Fast tracepoint not valid during download");
}
else
/* Fast tracepoints are functionally identical to regular
tracepoints, so don't take lack of support as a reason to
give up on the trace run. */
warning (_("Target does not support fast tracepoints, downloading %d as regular tracepoint"), t->number);
}
/* If the tracepoint has a conditional, make it into an agent
expression and append to the definition. */
if (t->loc->cond)
{
/* Only test support at download time, we may not know target
capabilities at definition time. */
if (remote_supports_cond_tracepoints ())
{
aexpr = gen_eval_for_expr (t->loc->address, t->loc->cond);
aexpr_chain = make_cleanup_free_agent_expr (aexpr);
sprintf (buf + strlen (buf), ":X%x,", aexpr->len);
mem2hex (aexpr->buf, buf + strlen (buf), aexpr->len);
do_cleanups (aexpr_chain);
}
else
warning (_("Target does not support conditional tracepoints, ignoring tp %d cond"), t->number);
}
if (t->actions || *default_collect)
strcat (buf, "-");
putpkt (buf);
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Target does not support tracepoints."));
if (!t->actions && !*default_collect)
return 1;
encode_actions (t, &tdp_actions, &stepping_actions);
old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
tdp_actions);
(void) make_cleanup (free_actions_list_cleanup_wrapper, stepping_actions);
/* do_single_steps (t); */
if (tdp_actions)
{
for (ndx = 0; tdp_actions[ndx]; ndx++)
{
QUIT; /* allow user to bail out with ^C */
sprintf (buf, "QTDP:-%x:%s:%s%c",
t->number, tmp, /* address */
tdp_actions[ndx],
((tdp_actions[ndx + 1] || stepping_actions)
? '-' : 0));
putpkt (buf);
remote_get_noisy_reply (&target_buf,
&target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Error on target while setting tracepoints."));
}
}
if (stepping_actions)
{
for (ndx = 0; stepping_actions[ndx]; ndx++)
{
QUIT; /* allow user to bail out with ^C */
sprintf (buf, "QTDP:-%x:%s:%s%s%s",
t->number, tmp, /* address */
((ndx == 0) ? "S" : ""),
stepping_actions[ndx],
(stepping_actions[ndx + 1] ? "-" : ""));
putpkt (buf);
remote_get_noisy_reply (&target_buf,
&target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Error on target while setting tracepoints."));
}
}
do_cleanups (old_chain);
return 1;
} }
/* tstop command */ /* tstop command */
static void static void
trace_stop_command (char *args, int from_tty) trace_stop_command (char *args, int from_tty)
{
if (target_is_remote ())
{ {
stop_tracing (); stop_tracing ();
if (deprecated_trace_start_stop_hook)
deprecated_trace_start_stop_hook (0, from_tty);
}
else
error (_("Trace can only be run on remote targets."));
} }
void void
stop_tracing () stop_tracing ()
{ {
putpkt ("QTStop"); target_trace_stop ();
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Bogus reply from target: %s"), target_buf);
trace_running_p = 0; trace_running_p = 0;
} }
unsigned long trace_running_p; unsigned long trace_running_p;
void int
get_trace_status () get_trace_status ()
{ {
putpkt ("qTStatus"); int status = target_get_trace_status (NULL);
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (target_buf[0] != 'T' ||
(target_buf[1] != '0' && target_buf[1] != '1'))
error (_("Bogus trace status reply from target: %s"), target_buf);
/* exported for use by the GUI */ /* exported for use by the GUI */
trace_running_p = (target_buf[1] == '1'); trace_running_p = (status > 0);
return status;
} }
/* tstatus command */ /* tstatus command */
static void static void
trace_status_command (char *args, int from_tty) trace_status_command (char *args, int from_tty)
{ {
if (target_is_remote ()) int status = get_trace_status ();
{
get_trace_status ();
if (trace_running_p) if (status < 0)
printf_filtered (_("Trace can not be run on the target.\n"));
else if (trace_running_p)
{ {
printf_filtered (_("Trace is running on the target.\n")); printf_filtered (_("Trace is running on the target.\n"));
if (disconnected_tracing) if (disconnected_tracing)
@ -1886,10 +1584,6 @@ trace_status_command (char *args, int from_tty)
traceframe_number, tracepoint_number); traceframe_number, tracepoint_number);
else else
printf_filtered (_("Not looking at any trace frame.\n")); printf_filtered (_("Not looking at any trace frame.\n"));
}
else
error (_("Trace can only be run on remote targets."));
} }
void void
@ -1912,8 +1606,8 @@ disconnect_or_stop_tracing (int from_tty)
/* Worker function for the various flavors of the tfind command. */ /* Worker function for the various flavors of the tfind command. */
static void static void
finish_tfind_command (char **msg, finish_tfind_command (enum trace_find_type type, int num,
long *sizeof_msg, ULONGEST addr1, ULONGEST addr2,
int from_tty) int from_tty)
{ {
int target_frameno = -1, target_tracept = -1; int target_frameno = -1, target_tracept = -1;
@ -1923,14 +1617,16 @@ finish_tfind_command (char **msg,
old_frame_id = get_frame_id (get_current_frame ()); old_frame_id = get_frame_id (get_current_frame ());
putpkt (*msg); target_frameno = target_trace_find (type, num, addr1, addr2,
reply = remote_get_noisy_reply (msg, sizeof_msg); &target_tracept);
while (reply && *reply) if (type == tfind_number
switch (*reply) && num == -1
&& target_frameno == -1)
{ {
case 'F': /* We told the target to get out of tfind mode, and it did. */
if ((target_frameno = (int) strtol (++reply, &reply, 16)) == -1) }
else if (target_frameno == -1)
{ {
/* A request for a non-existant trace frame has failed. /* A request for a non-existant trace frame has failed.
Our response will be different, depending on FROM_TTY: Our response will be different, depending on FROM_TTY:
@ -1959,27 +1655,13 @@ finish_tfind_command (char **msg,
{ {
if (info_verbose) if (info_verbose)
printf_filtered ("End of trace buffer.\n"); printf_filtered ("End of trace buffer.\n");
#if 0 /* dubious now? */
/* The following will not recurse, since it's /* The following will not recurse, since it's
special-cased. */ special-cased. */
trace_find_command ("-1", from_tty); trace_find_command ("-1", from_tty);
reply = NULL; /* Break out of loop #endif
(avoid recursive nonsense). */
} }
} }
break;
case 'T':
if ((target_tracept = (int) strtol (++reply, &reply, 16)) == -1)
error (_("Target failed to find requested trace frame."));
break;
case 'O': /* "OK"? */
if (reply[1] == 'K' && reply[2] == '\0')
reply += 2;
else
error (_("Bogus reply from target: %s"), reply);
break;
default:
error (_("Bogus reply from target: %s"), reply);
}
tp = get_tracepoint_by_number_on_target (target_tracept); tp = get_tracepoint_by_number_on_target (target_tracept);
@ -2033,14 +1715,9 @@ trace_find_command (char *args, int from_tty)
{ /* this should only be called with a numeric argument */ { /* this should only be called with a numeric argument */
int frameno = -1; int frameno = -1;
if (target_is_remote ())
{
if (trace_running_p) if (trace_running_p)
error ("May not look at trace frames while trace is running."); error ("May not look at trace frames while trace is running.");
if (deprecated_trace_find_hook)
deprecated_trace_find_hook (args, from_tty);
if (args == 0 || *args == 0) if (args == 0 || *args == 0)
{ /* TFIND with no args means find NEXT trace frame. */ { /* TFIND with no args means find NEXT trace frame. */
if (traceframe_number == -1) if (traceframe_number == -1)
@ -2057,17 +1734,16 @@ trace_find_command (char *args, int from_tty)
frameno = traceframe_number - 1; frameno = traceframe_number - 1;
} }
/* A hack to work around eval's need for fp to have been collected. */
else if (0 == strcmp (args, "-1"))
frameno = -1;
else else
frameno = parse_and_eval_long (args); frameno = parse_and_eval_long (args);
if (frameno < -1) if (frameno < -1)
error (_("invalid input (%d is less than zero)"), frameno); error (_("invalid input (%d is less than zero)"), frameno);
sprintf (target_buf, "QTFrame:%x", frameno); finish_tfind_command (tfind_number, frameno, 0, 0, from_tty);
finish_tfind_command (&target_buf, &target_buf_size, from_tty);
}
else
error (_("Trace can only be run on remote targets."));
} }
/* tfind end */ /* tfind end */
@ -2098,8 +1774,6 @@ trace_find_pc_command (char *args, int from_tty)
CORE_ADDR pc; CORE_ADDR pc;
char tmp[40]; char tmp[40];
if (target_is_remote ())
{
if (trace_running_p) if (trace_running_p)
error ("May not look at trace frames while trace is running."); error ("May not look at trace frames while trace is running.");
@ -2108,12 +1782,7 @@ trace_find_pc_command (char *args, int from_tty)
else else
pc = parse_and_eval_address (args); pc = parse_and_eval_address (args);
sprintf_vma (tmp, pc); finish_tfind_command (tfind_pc, 0, pc, 0, from_tty);
sprintf (target_buf, "QTFrame:pc:%s", tmp);
finish_tfind_command (&target_buf, &target_buf_size, from_tty);
}
else
error (_("Trace can only be run on remote targets."));
} }
/* tfind tracepoint command */ /* tfind tracepoint command */
@ -2123,8 +1792,6 @@ trace_find_tracepoint_command (char *args, int from_tty)
int tdp; int tdp;
struct breakpoint *tp; struct breakpoint *tp;
if (target_is_remote ())
{
if (trace_running_p) if (trace_running_p)
error ("May not look at trace frames while trace is running."); error ("May not look at trace frames while trace is running.");
@ -2145,11 +1812,7 @@ trace_find_tracepoint_command (char *args, int from_tty)
if (tp) if (tp)
tdp = tp->number_on_target; tdp = tp->number_on_target;
sprintf (target_buf, "QTFrame:tdp:%x", tdp); finish_tfind_command (tfind_tp, tdp, 0, 0, from_tty);
finish_tfind_command (&target_buf, &target_buf_size, from_tty);
}
else
error (_("Trace can only be run on remote targets."));
} }
/* TFIND LINE command: /* TFIND LINE command:
@ -2169,8 +1832,6 @@ trace_find_line_command (char *args, int from_tty)
struct cleanup *old_chain; struct cleanup *old_chain;
char startpc_str[40], endpc_str[40]; char startpc_str[40], endpc_str[40];
if (target_is_remote ())
{
if (trace_running_p) if (trace_running_p)
error ("May not look at trace frames while trace is running."); error ("May not look at trace frames while trace is running.");
@ -2191,8 +1852,6 @@ trace_find_line_command (char *args, int from_tty)
old_chain = make_cleanup (xfree, sals.sals); old_chain = make_cleanup (xfree, sals.sals);
if (sal.symtab == 0) if (sal.symtab == 0)
{ {
struct gdbarch *gdbarch = get_current_arch ();
printf_filtered ("TFIND: No line number information available"); printf_filtered ("TFIND: No line number information available");
if (sal.pc != 0) if (sal.pc != 0)
{ {
@ -2201,7 +1860,7 @@ trace_find_line_command (char *args, int from_tty)
have the symbolic address. */ have the symbolic address. */
printf_filtered (" for address "); printf_filtered (" for address ");
wrap_here (" "); wrap_here (" ");
print_address (gdbarch, sal.pc, gdb_stdout); print_address (get_current_arch (), sal.pc, gdb_stdout);
printf_filtered (";\n -- will attempt to find by PC. \n"); printf_filtered (";\n -- will attempt to find by PC. \n");
} }
else else
@ -2213,21 +1872,19 @@ trace_find_line_command (char *args, int from_tty)
else if (sal.line > 0 else if (sal.line > 0
&& find_line_pc_range (sal, &start_pc, &end_pc)) && find_line_pc_range (sal, &start_pc, &end_pc))
{ {
struct gdbarch *gdbarch = get_objfile_arch (sal.symtab->objfile);
if (start_pc == end_pc) if (start_pc == end_pc)
{ {
printf_filtered ("Line %d of \"%s\"", printf_filtered ("Line %d of \"%s\"",
sal.line, sal.symtab->filename); sal.line, sal.symtab->filename);
wrap_here (" "); wrap_here (" ");
printf_filtered (" is at address "); printf_filtered (" is at address ");
print_address (gdbarch, start_pc, gdb_stdout); print_address (get_current_arch (), start_pc, gdb_stdout);
wrap_here (" "); wrap_here (" ");
printf_filtered (" but contains no code.\n"); printf_filtered (" but contains no code.\n");
sal = find_pc_line (start_pc, 0); sal = find_pc_line (start_pc, 0);
if (sal.line > 0 && if (sal.line > 0
find_line_pc_range (sal, &start_pc, &end_pc) && && find_line_pc_range (sal, &start_pc, &end_pc)
start_pc != end_pc) && start_pc != end_pc)
printf_filtered ("Attempting to find line %d instead.\n", printf_filtered ("Attempting to find line %d instead.\n",
sal.line); sal.line);
else else
@ -2241,23 +1898,13 @@ trace_find_line_command (char *args, int from_tty)
error (_("Line number %d is out of range for \"%s\"."), error (_("Line number %d is out of range for \"%s\"."),
sal.line, sal.symtab->filename); sal.line, sal.symtab->filename);
sprintf_vma (startpc_str, start_pc);
sprintf_vma (endpc_str, end_pc - 1);
/* Find within range of stated line. */ /* Find within range of stated line. */
if (args && *args) if (args && *args)
sprintf (target_buf, "QTFrame:range:%s:%s", finish_tfind_command (tfind_range, 0, start_pc, end_pc - 1, from_tty);
startpc_str, endpc_str);
/* Find OUTSIDE OF range of CURRENT line. */
else else
sprintf (target_buf, "QTFrame:outside:%s:%s", finish_tfind_command (tfind_outside, 0, start_pc, end_pc - 1, from_tty);
startpc_str, endpc_str);
finish_tfind_command (&target_buf, &target_buf_size,
from_tty);
do_cleanups (old_chain); do_cleanups (old_chain);
} }
else
error (_("Trace can only be run on remote targets."));
}
/* tfind range command */ /* tfind range command */
static void static void
@ -2267,8 +1914,6 @@ trace_find_range_command (char *args, int from_tty)
char start_str[40], stop_str[40]; char start_str[40], stop_str[40];
char *tmp; char *tmp;
if (target_is_remote ())
{
if (trace_running_p) if (trace_running_p)
error ("May not look at trace frames while trace is running."); error ("May not look at trace frames while trace is running.");
@ -2292,13 +1937,7 @@ trace_find_range_command (char *args, int from_tty)
stop = start + 1; /* ??? */ stop = start + 1; /* ??? */
} }
sprintf_vma (start_str, start); finish_tfind_command (tfind_range, 0, start, stop, from_tty);
sprintf_vma (stop_str, stop);
sprintf (target_buf, "QTFrame:range:%s:%s", start_str, stop_str);
finish_tfind_command (&target_buf, &target_buf_size, from_tty);
}
else
error (_("Trace can only be run on remote targets."));
} }
/* tfind outside command */ /* tfind outside command */
@ -2309,8 +1948,6 @@ trace_find_outside_command (char *args, int from_tty)
char start_str[40], stop_str[40]; char start_str[40], stop_str[40];
char *tmp; char *tmp;
if (target_is_remote ())
{
if (trace_running_p) if (trace_running_p)
error ("May not look at trace frames while trace is running."); error ("May not look at trace frames while trace is running.");
@ -2334,13 +1971,7 @@ trace_find_outside_command (char *args, int from_tty)
stop = start + 1; /* ??? */ stop = start + 1; /* ??? */
} }
sprintf_vma (start_str, start); finish_tfind_command (tfind_outside, 0, start, stop, from_tty);
sprintf_vma (stop_str, stop);
sprintf (target_buf, "QTFrame:outside:%s:%s", start_str, stop_str);
finish_tfind_command (&target_buf, &target_buf_size, from_tty);
}
else
error (_("Trace can only be run on remote targets."));
} }
/* info scope command: list the locals for a scope. */ /* info scope command: list the locals for a scope. */
@ -2511,12 +2142,6 @@ trace_dump_command (char *args, int from_tty)
int stepping_actions = 0; int stepping_actions = 0;
int stepping_frame = 0; int stepping_frame = 0;
if (!target_is_remote ())
{
error (_("Trace can only be run on remote targets."));
return;
}
if (tracepoint_number == -1) if (tracepoint_number == -1)
{ {
warning (_("No current trace frame.")); warning (_("No current trace frame."));
@ -2620,17 +2245,7 @@ trace_dump_command (char *args, int from_tty)
void void
send_disconnected_tracing_value (int value) send_disconnected_tracing_value (int value)
{ {
char buf[30]; target_set_disconnected_tracing (value);
/* No need to do anything special if target not active. */
if (!target_is_remote ())
return;
sprintf (buf, "QTDisconnected:%x", value);
putpkt (buf);
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Target does not support this command."));
} }
static void static void
@ -2847,7 +2462,4 @@ trace data collected in the meantime."),
NULL, NULL,
&setlist, &setlist,
&showlist); &showlist);
target_buf_size = 2048;
target_buf = xmalloc (target_buf_size);
} }

View File

@ -65,6 +65,8 @@ struct trace_state_variable
extern unsigned long trace_running_p; extern unsigned long trace_running_p;
extern char *default_collect;
/* A hook used to notify the UI of tracepoint operations. */ /* A hook used to notify the UI of tracepoint operations. */
extern void (*deprecated_trace_find_hook) (char *arg, int from_tty); extern void (*deprecated_trace_find_hook) (char *arg, int from_tty);