mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-23 20:19:49 +00:00
gdb/
Conditional tracepoints. * ax-gdb.h (gen_eval_for_expr): Declare. * ax-gdb.c (gen_expr): Generate bytecodes for BINOP_EQUAL and other comparisons. (gen_eval_for_expr): New function. (agent_eval_command): New maintenance command. (_initialize_ax_gdb): Define the command. * remote.c (struct remote_state): New field cond_tracepoints. (PACKET_ConditionalTracepoints): New packet config type. (remote_cond_tracepoint_feature): New function. (remote_protocol_features): Add ConditionalTracepoints. (remote_supports_cond_tracepoints): New function. (_initialize_remote): Add ConditionalTracepoints. * tracepoint.c (download_tracepoint): Add conditional. * NEWS: Mention conditional tracepoints. gdb/doc/ * gdb.texinfo (Tracepoint Conditions): New section. (General Query Packets): Describe ConditionalTracepoints. (Tracepoint Packets): Describe condition field. (Maintenance Commands): Describe maint agent-eval. * agentexpr.texi (Using Agent Expressions): Mention eval usage. gdb/testsuite/ * gdb.trace/tracecmd.exp: Add basic test of tracepoint conditions.
This commit is contained in:
parent
f662c3bce4
commit
782b2b0784
@ -1,3 +1,21 @@
|
||||
2009-07-14 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
Conditional tracepoints.
|
||||
* ax-gdb.h (gen_eval_for_expr): Declare.
|
||||
* ax-gdb.c (gen_expr): Generate bytecodes for BINOP_EQUAL
|
||||
and other comparisons.
|
||||
(gen_eval_for_expr): New function.
|
||||
(agent_eval_command): New maintenance command.
|
||||
(_initialize_ax_gdb): Define the command.
|
||||
* remote.c (struct remote_state): New field cond_tracepoints.
|
||||
(PACKET_ConditionalTracepoints): New packet config type.
|
||||
(remote_cond_tracepoint_feature): New function.
|
||||
(remote_protocol_features): Add ConditionalTracepoints.
|
||||
(remote_supports_cond_tracepoints): New function.
|
||||
(_initialize_remote): Add ConditionalTracepoints.
|
||||
* tracepoint.c (download_tracepoint): Add conditional.
|
||||
* NEWS: Mention conditional tracepoints.
|
||||
|
||||
2009-07-14 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* objfiles.c (objfile_relocate): Do not relocate the same
|
||||
|
6
gdb/NEWS
6
gdb/NEWS
@ -3,6 +3,12 @@
|
||||
|
||||
*** Changes since GDB 6.8
|
||||
|
||||
* Tracepoints may now be conditional. The syntax is as for
|
||||
breakpoints; either an "if" clause appended to the "trace" command,
|
||||
or the "condition" command is available. GDB sends the condition to
|
||||
the target for evaluation using the same bytecode format as is used
|
||||
for tracepoint actions.
|
||||
|
||||
* "disassemble" command with a /r modifier, print the raw instructions
|
||||
in hex as well as in symbolic form."
|
||||
|
||||
|
119
gdb/ax-gdb.c
119
gdb/ax-gdb.c
@ -1468,6 +1468,12 @@ gen_expr (struct expression *exp, union exp_element **pc,
|
||||
case BINOP_BITWISE_AND:
|
||||
case BINOP_BITWISE_IOR:
|
||||
case BINOP_BITWISE_XOR:
|
||||
case BINOP_EQUAL:
|
||||
case BINOP_NOTEQUAL:
|
||||
case BINOP_LESS:
|
||||
case BINOP_GTR:
|
||||
case BINOP_LEQ:
|
||||
case BINOP_GEQ:
|
||||
(*pc)++;
|
||||
gen_expr (exp, pc, ax, &value1);
|
||||
gen_usual_unary (exp, ax, &value1);
|
||||
@ -1537,6 +1543,47 @@ gen_expr (struct expression *exp, union exp_element **pc,
|
||||
aop_bit_xor, aop_bit_xor, 0, "bitwise exclusive-or");
|
||||
break;
|
||||
|
||||
case BINOP_EQUAL:
|
||||
gen_binop (ax, value, &value1, &value2,
|
||||
aop_equal, aop_equal, 0, "equal");
|
||||
break;
|
||||
|
||||
case BINOP_NOTEQUAL:
|
||||
gen_binop (ax, value, &value1, &value2,
|
||||
aop_equal, aop_equal, 0, "equal");
|
||||
gen_logical_not (ax, value,
|
||||
language_bool_type (exp->language_defn,
|
||||
exp->gdbarch));
|
||||
break;
|
||||
|
||||
case BINOP_LESS:
|
||||
gen_binop (ax, value, &value1, &value2,
|
||||
aop_less_signed, aop_less_unsigned, 0, "less than");
|
||||
break;
|
||||
|
||||
case BINOP_GTR:
|
||||
ax_simple (ax, aop_swap);
|
||||
gen_binop (ax, value, &value1, &value2,
|
||||
aop_less_signed, aop_less_unsigned, 0, "less than");
|
||||
break;
|
||||
|
||||
case BINOP_LEQ:
|
||||
ax_simple (ax, aop_swap);
|
||||
gen_binop (ax, value, &value1, &value2,
|
||||
aop_less_signed, aop_less_unsigned, 0, "less than");
|
||||
gen_logical_not (ax, value,
|
||||
language_bool_type (exp->language_defn,
|
||||
exp->gdbarch));
|
||||
break;
|
||||
|
||||
case BINOP_GEQ:
|
||||
gen_binop (ax, value, &value1, &value2,
|
||||
aop_less_signed, aop_less_unsigned, 0, "less than");
|
||||
gen_logical_not (ax, value,
|
||||
language_bool_type (exp->language_defn,
|
||||
exp->gdbarch));
|
||||
break;
|
||||
|
||||
default:
|
||||
/* We should only list operators in the outer case statement
|
||||
that we actually handle in the inner case statement. */
|
||||
@ -1756,6 +1803,37 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr)
|
||||
return ax;
|
||||
}
|
||||
|
||||
/* Given a GDB expression EXPR, return a bytecode sequence that will
|
||||
evaluate and return a result. The bytecodes will do a direct
|
||||
evaluation, using the current data on the target, rather than
|
||||
recording blocks of memory and registers for later use, as
|
||||
gen_trace_for_expr does. The generated bytecode sequence leaves
|
||||
the result of expression evaluation on the top of the stack. */
|
||||
|
||||
struct agent_expr *
|
||||
gen_eval_for_expr (CORE_ADDR scope, struct expression *expr)
|
||||
{
|
||||
struct cleanup *old_chain = 0;
|
||||
struct agent_expr *ax = new_agent_expr (scope);
|
||||
union exp_element *pc;
|
||||
struct axs_value value;
|
||||
|
||||
old_chain = make_cleanup_free_agent_expr (ax);
|
||||
|
||||
pc = expr->elts;
|
||||
trace_kludge = 0;
|
||||
gen_expr (expr, &pc, ax, &value);
|
||||
|
||||
/* Oh, and terminate. */
|
||||
ax_simple (ax, aop_end);
|
||||
|
||||
/* We have successfully built the agent expr, so cancel the cleanup
|
||||
request. If we add more cleanups that we always want done, this
|
||||
will have to get more complicated. */
|
||||
discard_cleanups (old_chain);
|
||||
return ax;
|
||||
}
|
||||
|
||||
static void
|
||||
agent_command (char *exp, int from_tty)
|
||||
{
|
||||
@ -1786,6 +1864,41 @@ agent_command (char *exp, int from_tty)
|
||||
do_cleanups (old_chain);
|
||||
dont_repeat ();
|
||||
}
|
||||
|
||||
/* Parse the given expression, compile it into an agent expression
|
||||
that does direct evaluation, and display the resulting
|
||||
expression. */
|
||||
|
||||
static void
|
||||
agent_eval_command (char *exp, int from_tty)
|
||||
{
|
||||
struct cleanup *old_chain = 0;
|
||||
struct expression *expr;
|
||||
struct agent_expr *agent;
|
||||
struct frame_info *fi = get_current_frame (); /* need current scope */
|
||||
|
||||
/* We don't deal with overlay debugging at the moment. We need to
|
||||
think more carefully about this. If you copy this code into
|
||||
another command, change the error message; the user shouldn't
|
||||
have to know anything about agent expressions. */
|
||||
if (overlay_debugging)
|
||||
error (_("GDB can't do agent expression translation with overlays."));
|
||||
|
||||
if (exp == 0)
|
||||
error_no_arg (_("expression to translate"));
|
||||
|
||||
expr = parse_expression (exp);
|
||||
old_chain = make_cleanup (free_current_contents, &expr);
|
||||
agent = gen_eval_for_expr (get_frame_pc (fi), expr);
|
||||
make_cleanup_free_agent_expr (agent);
|
||||
ax_print (gdb_stdout, agent);
|
||||
|
||||
/* It would be nice to call ax_reqs here to gather some general info
|
||||
about the expression, and then print out the result. */
|
||||
|
||||
do_cleanups (old_chain);
|
||||
dont_repeat ();
|
||||
}
|
||||
|
||||
|
||||
/* Initialization code. */
|
||||
@ -1795,6 +1908,10 @@ void
|
||||
_initialize_ax_gdb (void)
|
||||
{
|
||||
add_cmd ("agent", class_maintenance, agent_command,
|
||||
_("Translate an expression into remote agent bytecode."),
|
||||
_("Translate an expression into remote agent bytecode for tracing."),
|
||||
&maintenancelist);
|
||||
|
||||
add_cmd ("agent-eval", class_maintenance, agent_eval_command,
|
||||
_("Translate an expression into remote agent bytecode for evaluation."),
|
||||
&maintenancelist);
|
||||
}
|
||||
|
@ -99,4 +99,6 @@ struct axs_value
|
||||
function to discover which registers the expression uses. */
|
||||
extern struct agent_expr *gen_trace_for_expr (CORE_ADDR, struct expression *);
|
||||
|
||||
extern struct agent_expr *gen_eval_for_expr (CORE_ADDR, struct expression *);
|
||||
|
||||
#endif /* AX_GDB_H */
|
||||
|
@ -1,3 +1,11 @@
|
||||
2009-07-14 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
* gdb.texinfo (Tracepoint Conditions): New section.
|
||||
(General Query Packets): Describe ConditionalTracepoints.
|
||||
(Tracepoint Packets): Describe condition field.
|
||||
(Maintenance Commands): Describe maint agent-eval.
|
||||
* agentexpr.texi (Using Agent Expressions): Mention eval usage.
|
||||
|
||||
2009-07-11 Hui Zhu <teawater@gmail.com>
|
||||
|
||||
* gdb.texinfo (disassemble): Add a new modifier /r
|
||||
|
@ -7,13 +7,11 @@
|
||||
|
||||
@c This file is part of the GDB manual.
|
||||
@c
|
||||
@c Copyright (C) 2003, 2004, 2005, 2006
|
||||
@c Copyright (C) 2003, 2004, 2005, 2006, 2009
|
||||
@c Free Software Foundation, Inc.
|
||||
@c
|
||||
@c See the file gdb.texinfo for copying conditions.
|
||||
|
||||
@c Revision: $Id$
|
||||
|
||||
@node Agent Expressions
|
||||
@appendix The GDB Agent Expression Mechanism
|
||||
|
||||
@ -473,8 +471,20 @@ address, and the top of the stack is the lvalue's size, in bytes.
|
||||
@node Using Agent Expressions
|
||||
@section Using Agent Expressions
|
||||
|
||||
Here is a sketch of a full non-stop debugging cycle, showing how agent
|
||||
expressions fit into the process.
|
||||
Agent expressions can be used in several different ways by @value{GDBN},
|
||||
and the debugger can generate different bytecode sequences as appropriate.
|
||||
|
||||
One possibility is to do expression evaluation on the target rather
|
||||
than the host, such as for the conditional of a conditional
|
||||
tracepoint. In such a case, @value{GDBN} compiles the source
|
||||
expression into a bytecode sequence that simply gets values from
|
||||
registers or memory, does arithmetic, and returns a result.
|
||||
|
||||
Another way to use agent expressions is for tracepoint data
|
||||
collection. @value{GDBN} generates a different bytecode sequence for
|
||||
collection; in addition to bytecodes that do the calculation,
|
||||
@value{GDBN} adds @code{trace} bytecodes to save the pieces of
|
||||
memory that were used.
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
|
@ -8932,6 +8932,7 @@ conditions and actions.
|
||||
* Create and Delete Tracepoints::
|
||||
* Enable and Disable Tracepoints::
|
||||
* Tracepoint Passcounts::
|
||||
* Tracepoint Conditions::
|
||||
* Tracepoint Actions::
|
||||
* Listing Tracepoints::
|
||||
* Starting and Stopping Trace Experiments::
|
||||
@ -8971,6 +8972,13 @@ Here are some examples of using the @code{trace} command:
|
||||
@noindent
|
||||
You can abbreviate @code{trace} as @code{tr}.
|
||||
|
||||
@item trace @var{location} if @var{cond}
|
||||
Set a tracepoint with condition @var{cond}; evaluate the expression
|
||||
@var{cond} each time the tracepoint is reached, and collect data only
|
||||
if the value is nonzero---that is, if @var{cond} evaluates as true.
|
||||
@xref{Tracepoint Conditions, ,Tracepoint Conditions}, for more
|
||||
information on tracepoint conditions.
|
||||
|
||||
@vindex $tpnum
|
||||
@cindex last tracepoint number
|
||||
@cindex recent tracepoint number
|
||||
@ -9053,6 +9061,44 @@ Examples:
|
||||
@end smallexample
|
||||
@end table
|
||||
|
||||
@node Tracepoint Conditions
|
||||
@subsection Tracepoint Conditions
|
||||
@cindex conditional tracepoints
|
||||
@cindex tracepoint conditions
|
||||
|
||||
The simplest sort of tracepoint collects data every time your program
|
||||
reaches a specified place. You can also specify a @dfn{condition} for
|
||||
a tracepoint. A condition is just a Boolean expression in your
|
||||
programming language (@pxref{Expressions, ,Expressions}). A
|
||||
tracepoint with a condition evaluates the expression each time your
|
||||
program reaches it, and data collection happens only if the condition
|
||||
is true.
|
||||
|
||||
Tracepoint conditions can be specified when a tracepoint is set, by
|
||||
using @samp{if} in the arguments to the @code{trace} command.
|
||||
@xref{Create and Delete Tracepoints, ,Setting Tracepoints}. They can
|
||||
also be set or changed at any time with the @code{condition} command,
|
||||
just as with breakpoints.
|
||||
|
||||
Unlike breakpoint conditions, @value{GDBN} does not actually evaluate
|
||||
the conditional expression itself. Instead, @value{GDBN} encodes the
|
||||
expression into an agent expression (@pxref{Agent Expressions}
|
||||
suitable for execution on the target, independently of @value{GDBN}.
|
||||
Global variables become raw memory locations, locals become stack
|
||||
accesses, and so forth.
|
||||
|
||||
For instance, suppose you have a function that is usually called
|
||||
frequently, but should not be called after an error has occurred. You
|
||||
could use the following tracepoint command to collect data about calls
|
||||
of that function that happen while the error code is propagating
|
||||
through the program; an unconditional tracepoint could end up
|
||||
collecting thousands of useless trace frames that you would have to
|
||||
search through.
|
||||
|
||||
@smallexample
|
||||
(@value{GDBP}) @kbd{trace normal_operation if errcode > 0}
|
||||
@end smallexample
|
||||
|
||||
@node Tracepoint Actions
|
||||
@subsection Tracepoint Action Lists
|
||||
|
||||
@ -26534,10 +26580,19 @@ messages, see @ref{Debugging Output}.)
|
||||
|
||||
@table @code
|
||||
@kindex maint agent
|
||||
@kindex maint agent-eval
|
||||
@item maint agent @var{expression}
|
||||
@itemx maint agent-eval @var{expression}
|
||||
Translate the given @var{expression} into remote agent bytecodes.
|
||||
This command is useful for debugging the Agent Expression mechanism
|
||||
(@pxref{Agent Expressions}).
|
||||
(@pxref{Agent Expressions}). The @samp{agent} version produces an
|
||||
expression useful for data collection, such as by tracepoints, while
|
||||
@samp{maint agent-eval} produces an expression that evaluates directly
|
||||
to a result. For instance, a collection expression for @code{globa +
|
||||
globb} will include bytecodes to record four bytes of memory at each
|
||||
of the addresses of @code{globa} and @code{globb}, while discarding
|
||||
the result of the addition, while an evaluation expression will do the
|
||||
addition and return the sum.
|
||||
|
||||
@kindex maint info breakpoints
|
||||
@item @anchor{maint info breakpoints}maint info breakpoints
|
||||
@ -28415,6 +28470,11 @@ These are the currently defined stub features and their properties:
|
||||
@tab @samp{-}
|
||||
@tab No
|
||||
|
||||
@item @samp{ConditionalTracepoints}
|
||||
@tab No
|
||||
@tab @samp{-}
|
||||
@tab No
|
||||
|
||||
@end multitable
|
||||
|
||||
These are the currently defined stub features, in more detail:
|
||||
@ -28492,6 +28552,10 @@ indicated it supports them in its @samp{qSupported} request.
|
||||
The remote stub understands the @samp{qXfer:osdata:read} packet
|
||||
((@pxref{qXfer osdata read}).
|
||||
|
||||
@item ConditionalTracepoints
|
||||
The remote stub accepts and implements conditional expressions defined
|
||||
for tracepoints (@pxref{Tracepoint Conditions}).
|
||||
|
||||
@end table
|
||||
|
||||
@item qSymbol::
|
||||
@ -28804,11 +28868,14 @@ tracepoints (@pxref{Tracepoints}).
|
||||
|
||||
@table @samp
|
||||
|
||||
@item QTDP:@var{n}:@var{addr}:@var{ena}:@var{step}:@var{pass}@r{[}-@r{]}
|
||||
@item QTDP:@var{n}:@var{addr}:@var{ena}:@var{step}:@var{pass}[:X@var{len},@var{bytes}]@r{[}-@r{]}
|
||||
Create a new tracepoint, number @var{n}, at @var{addr}. If @var{ena}
|
||||
is @samp{E}, then the tracepoint is enabled; if it is @samp{D}, then
|
||||
the tracepoint is disabled. @var{step} is the tracepoint's step
|
||||
count, and @var{pass} is its pass count. If the trailing @samp{-} is
|
||||
count, and @var{pass} is its pass count. If an @samp{X} is present,
|
||||
it introduces a tracepoint condition, which consists of a hexadecimal
|
||||
length, followed by a comma and hex-encoded bytes, in a manner similar
|
||||
to action encodings as described below. If the trailing @samp{-} is
|
||||
present, further @samp{QTDP} packets will follow to specify this
|
||||
tracepoint's actions.
|
||||
|
||||
|
25
gdb/remote.c
25
gdb/remote.c
@ -294,6 +294,9 @@ struct remote_state
|
||||
|
||||
/* True if the stub reports support for vCont;t. */
|
||||
int support_vCont_t;
|
||||
|
||||
/* True if the stub reports support for conditional tracepoints. */
|
||||
int cond_tracepoints;
|
||||
};
|
||||
|
||||
/* Returns true if the multi-process extensions are in effect. */
|
||||
@ -993,6 +996,7 @@ enum {
|
||||
PACKET_qXfer_siginfo_read,
|
||||
PACKET_qXfer_siginfo_write,
|
||||
PACKET_qAttached,
|
||||
PACKET_ConditionalTracepoints,
|
||||
PACKET_MAX
|
||||
};
|
||||
|
||||
@ -3015,6 +3019,15 @@ remote_non_stop_feature (const struct protocol_feature *feature,
|
||||
rs->non_stop_aware = (support == PACKET_ENABLE);
|
||||
}
|
||||
|
||||
static void
|
||||
remote_cond_tracepoint_feature (const struct protocol_feature *feature,
|
||||
enum packet_support support,
|
||||
const char *value)
|
||||
{
|
||||
struct remote_state *rs = get_remote_state ();
|
||||
rs->cond_tracepoints = (support == PACKET_ENABLE);
|
||||
}
|
||||
|
||||
static struct protocol_feature remote_protocol_features[] = {
|
||||
{ "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
|
||||
{ "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet,
|
||||
@ -3041,6 +3054,8 @@ static struct protocol_feature remote_protocol_features[] = {
|
||||
PACKET_qXfer_siginfo_read },
|
||||
{ "qXfer:siginfo:write", PACKET_DISABLE, remote_supported_packet,
|
||||
PACKET_qXfer_siginfo_write },
|
||||
{ "ConditionalTracepoints", PACKET_DISABLE, remote_cond_tracepoint_feature,
|
||||
PACKET_ConditionalTracepoints },
|
||||
};
|
||||
|
||||
static void
|
||||
@ -8740,6 +8755,13 @@ remote_supports_multi_process (void)
|
||||
return remote_multi_process_p (rs);
|
||||
}
|
||||
|
||||
int
|
||||
remote_supports_cond_tracepoints (void)
|
||||
{
|
||||
struct remote_state *rs = get_remote_state ();
|
||||
return rs->cond_tracepoints;
|
||||
}
|
||||
|
||||
static void
|
||||
init_remote_ops (void)
|
||||
{
|
||||
@ -9183,6 +9205,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
|
||||
add_packet_config_cmd (&remote_protocol_packets[PACKET_qAttached],
|
||||
"qAttached", "query-attached", 0);
|
||||
|
||||
add_packet_config_cmd (&remote_protocol_packets[PACKET_ConditionalTracepoints],
|
||||
"ConditionalTracepoints", "conditional-tracepoints", 0);
|
||||
|
||||
/* Keep the old ``set remote Z-packet ...'' working. Each individual
|
||||
Z sub-packet has its own set and show commands, but users may
|
||||
have sets to this variable in their .gdbinit files (or in their
|
||||
|
@ -1,3 +1,7 @@
|
||||
2009-07-14 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
* gdb.trace/tracecmd.exp: Add basic test of tracepoint conditions.
|
||||
|
||||
2009-07-14 Michael Snyder <msnyder@vmware.com>
|
||||
|
||||
* gdb.reverse/step-reverse.exp (stepi into function call):
|
||||
|
@ -153,7 +153,12 @@ gdb_test "trace" "No default breakpoint address now." \
|
||||
# deferred to limits test module
|
||||
|
||||
# 1.11 tracepoint conditions
|
||||
# conditions on tracepoints not implemented
|
||||
gdb_delete_tracepoints
|
||||
gdb_test "trace gdb_recursion_test if q1 > 0" \
|
||||
"Tracepoint $decimal at $hex: file.*$srcfile, line $testline1." \
|
||||
"1.11a: conditional tracepoint"
|
||||
gdb_test "info trace" "in gdb_recursion_test.*$srcfile:$testline1.*trace only if q1 > 0" \
|
||||
"1.11b: verify conditional tracepoint"
|
||||
|
||||
# 1.12 set tracepoint in prologue
|
||||
# [see tfind.exp]
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "breakpoint.h"
|
||||
#include "tracepoint.h"
|
||||
#include "remote.h"
|
||||
extern int remote_supports_cond_tracepoints (void);
|
||||
#include "linespec.h"
|
||||
#include "regcache.h"
|
||||
#include "completer.h"
|
||||
@ -1311,12 +1312,31 @@ download_tracepoint (struct breakpoint *t)
|
||||
char **stepping_actions;
|
||||
int ndx;
|
||||
struct cleanup *old_chain = NULL;
|
||||
struct agent_expr *aexpr;
|
||||
struct cleanup *aexpr_chain = NULL;
|
||||
|
||||
sprintf_vma (tmp, (t->loc ? t->loc->address : 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);
|
||||
/* 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)
|
||||
strcat (buf, "-");
|
||||
|
Loading…
Reference in New Issue
Block a user