This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 1/4] Fix PR breakpoints/16494: add dprintf-style "agent-call"(gdb)
- From: Hui Zhu <hui_zhu at mentor dot com>
- To: gdb-patches ml <gdb-patches at sourceware dot org>
- Date: Wed, 5 Mar 2014 00:29:40 +0800
- Subject: [PATCH 1/4] Fix PR breakpoints/16494: add dprintf-style "agent-call"(gdb)
- Authentication-results: sourceware.org; auth=none
Because current GDB rsp packet already has the support to put the function
address and channel to gdbserver:
printf (0x34) numargs string â
Do a formatted print, in the style of the C function printf). The value of numargs is the number of arguments to expect on the stack, while string is the format string, prefixed with a two-byte length. The last byte of the string must be zero, and is included in the length. The format string includes escaped sequences just as it appears in C source, so for instance the format string "\t%d\n" is six characters long, and the output will consist of a tab character, a decimal number, and a newline. At the top of the stack, above the values to be printed, this bytecode will pop a âfunctionâ and âchannelâ. If the function is nonzero, then the target may treat it as a function and call it, passing the channel as a first argument, as with the C function fprintf. If the function is zero, then the target may simply call a standard formatted print function of its choice. In all, this bytecode pops 2 + numargs stack elements, and pushes nothing.
This patch doesn't need add anything to this part but a feature support packet "DprintfAgentCall" to make sure if gdbserver support agent-call or not.
I add a new style "agent-call" to GDB send function address and channel
to gdbserver when it send dprintf to gdbserver.
Thanks,
Hui
2014-03-04 Hui Zhu <hui@codesourcery.com>
PR breakpoint/16494
* breakpoint.c (infcall.h): New.
(dprintf_style_agent_call): New.
(dprintf_style_enums): Add dprintf_style_agent_call.
(parse_cmd_to_aexpr): Update comments and arguments.
(build_target_command_list): Add "dprintf_style_agent_call".
(update_dprintf_command_list): Ditto.
* remote.c (remote_state): Add dprintf_agent_call.
(PACKET_DprintfAgentCall): New.
(remote_dprintf_agent_call_feature): New.
(remote_protocol_features): Add "DprintfAgentCall".
(remote_can_run_dprintf_agent_call): New.
(init_remote_ops): Add remote_can_run_dprintf_agent_call.
(_initialize_remote): Add "dprintf-agent-call".
* target-delegates.c: Rebuild.
* target.h (target_ops): Add "to_can_run_dprintf_agent_call".
(target_can_run_dprintf_agent_call): New.
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -68,6 +68,7 @@
#include "skip.h"
#include "ax-gdb.h"
#include "dummy-frame.h"
+#include "infcall.h"
#include "format.h"
@@ -311,10 +312,12 @@ struct breakpoint_ops dprintf_breakpoint
static const char dprintf_style_gdb[] = "gdb";
static const char dprintf_style_call[] = "call";
static const char dprintf_style_agent[] = "agent";
+static const char dprintf_style_agent_call[] = "agent-call";
static const char *const dprintf_style_enums[] = {
dprintf_style_gdb,
dprintf_style_call,
dprintf_style_agent,
+ dprintf_style_agent_call,
NULL
};
static const char *dprintf_style = dprintf_style_gdb;
@@ -2193,10 +2196,11 @@ build_target_condition_list (struct bp_l
/* Parses a command described by string CMD into an agent expression
bytecode suitable for evaluation by the bytecode interpreter.
+ FUNCTION and CHANNEL is for the dprintf.
Return NULL if there was any error during parsing. */
static struct agent_expr *
-parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
+parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd, char *function, char *channel)
{
struct cleanup *old_cleanups = 0;
struct expression *expr, **argvec;
@@ -2206,6 +2210,9 @@ parse_cmd_to_aexpr (CORE_ADDR scope, cha
const char *format_start, *format_end;
struct format_piece *fpieces;
int nargs;
+ CORE_ADDR function_addr = 0;
+ LONGEST channel_val = 0;
+ struct value *val;
struct gdbarch *gdbarch = get_current_arch ();
if (!cmd)
@@ -2258,11 +2265,29 @@ parse_cmd_to_aexpr (CORE_ADDR scope, cha
++cmdrest;
}
+ /* Get address of FUNCTION . */
+ if (function != NULL && strlen (function) > 0)
+ {
+ expr = parse_expression (function);
+ make_cleanup (free_current_contents, &expr);
+ val = evaluate_expression (expr);
+ function_addr = find_function_addr(val, NULL);
+ }
+
+ /* Get value of channel. */
+ if (channel != NULL && strlen (channel) > 0)
+ {
+ expr = parse_expression (channel);
+ make_cleanup (free_current_contents, &expr);
+ val = evaluate_expression (expr);
+ channel_val = value_as_long(val);
+ }
+
/* We don't want to stop processing, so catch any errors
that may show up. */
TRY_CATCH (ex, RETURN_MASK_ERROR)
{
- aexpr = gen_printf (scope, gdbarch, 0, 0,
+ aexpr = gen_printf (scope, gdbarch, function_addr, channel_val,
format_start, format_end - format_start,
fpieces, nargs, argvec);
}
@@ -2298,12 +2323,17 @@ build_target_command_list (struct bp_loc
/* For now, limit to agent-style dprintf breakpoints. */
if (bl->owner->type != bp_dprintf
- || strcmp (dprintf_style, dprintf_style_agent) != 0)
+ || (strcmp (dprintf_style, dprintf_style_agent) != 0
+ && strcmp (dprintf_style, dprintf_style_agent_call) != 0))
return;
if (!target_can_run_breakpoint_commands ())
return;
+ if (strcmp (dprintf_style, dprintf_style_agent_call) == 0
+ && !target_can_run_dprintf_agent_call ())
+ error (_("Target cannot run dprintf agent call."));
+
/* Do a first pass to check for locations with no assigned
conditions or conditions that fail to parse to a valid agent expression
bytecode. If any of these happen, then it's no use to send conditions
@@ -2322,8 +2352,15 @@ build_target_command_list (struct bp_loc
case we already freed the command bytecodes (see
force_breakpoint_reinsertion). We just
need to parse the command to bytecodes again. */
- aexpr = parse_cmd_to_aexpr (bl->address,
- loc->owner->extra_string);
+ if (strcmp (dprintf_style, dprintf_style_agent_call) == 0)
+ aexpr = parse_cmd_to_aexpr (bl->address,
+ loc->owner->extra_string,
+ dprintf_function,
+ dprintf_channel);
+ else
+ aexpr = parse_cmd_to_aexpr (bl->address,
+ loc->owner->extra_string,
+ NULL, NULL);
loc->cmd_bytecode = aexpr;
if (!aexpr)
@@ -9127,6 +9164,16 @@ update_dprintf_command_list (struct brea
printf_line = xstrprintf ("printf %s", dprintf_args);
}
}
+ else if (strcmp (dprintf_style, dprintf_style_agent_call) == 0)
+ {
+ if (target_can_run_dprintf_agent_call ())
+ printf_line = xstrprintf ("agent-printf %s", dprintf_args);
+ else
+ {
+ warning (_("Target cannot run dprintf agent call, falling back to GDB printf"));
+ printf_line = xstrprintf ("printf %s", dprintf_args);
+ }
+ }
else
internal_error (__FILE__, __LINE__,
_("Invalid dprintf style."));
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -340,6 +340,9 @@ struct remote_state
commands. */
int breakpoint_commands;
+ /* True if the stub reports support for dprintf agent call. */
+ int dprintf_agent_call;
+
/* True if the stub reports support for fast tracepoints. */
int fast_tracepoints;
@@ -1353,6 +1356,7 @@ enum {
PACKET_ConditionalTracepoints,
PACKET_ConditionalBreakpoints,
PACKET_BreakpointCommands,
+ PACKET_DprintfAgentCall,
PACKET_FastTracepoints,
PACKET_StaticTracepoints,
PACKET_InstallInTrace,
@@ -3912,6 +3916,16 @@ remote_breakpoint_commands_feature (cons
}
static void
+remote_dprintf_agent_call_feature (const struct protocol_feature *feature,
+ enum packet_support support,
+ const char *value)
+{
+ struct remote_state *rs = get_remote_state ();
+
+ rs->dprintf_agent_call = (support == PACKET_ENABLE);
+}
+
+static void
remote_fast_tracepoint_feature (const struct protocol_feature *feature,
enum packet_support support,
const char *value)
@@ -4023,6 +4037,8 @@ static const struct protocol_feature rem
PACKET_ConditionalBreakpoints },
{ "BreakpointCommands", PACKET_DISABLE, remote_breakpoint_commands_feature,
PACKET_BreakpointCommands },
+ { "DprintfAgentCall", PACKET_DISABLE, remote_dprintf_agent_call_feature,
+ PACKET_DprintfAgentCall },
{ "FastTracepoints", PACKET_DISABLE, remote_fast_tracepoint_feature,
PACKET_FastTracepoints },
{ "StaticTracepoints", PACKET_DISABLE, remote_static_tracepoint_feature,
@@ -10402,6 +10418,14 @@ remote_download_command_source (int num,
}
}
+static int
+remote_can_run_dprintf_agent_call (struct target_ops *self)
+{
+ struct remote_state *rs = get_remote_state ();
+
+ return rs->dprintf_agent_call;
+}
+
static void
remote_download_tracepoint (struct target_ops *self, struct bp_location *loc)
{
@@ -11462,6 +11486,8 @@ Specify the serial device it is connecte
remote_ops.to_supports_string_tracing = remote_supports_string_tracing;
remote_ops.to_supports_evaluation_of_breakpoint_conditions = remote_supports_cond_breakpoints;
remote_ops.to_can_run_breakpoint_commands = remote_can_run_breakpoint_commands;
+ remote_ops.to_can_run_dprintf_agent_call
+ = remote_can_run_dprintf_agent_call;
remote_ops.to_trace_init = remote_trace_init;
remote_ops.to_download_tracepoint = remote_download_tracepoint;
remote_ops.to_can_download_tracepoint = remote_can_download_tracepoint;
@@ -12050,6 +12076,10 @@ Show the maximum size of the address (in
"BreakpointCommands",
"breakpoint-commands", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_DprintfAgentCall],
+ "DprintfAgentCall",
+ "dprintf-agent-call", 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_FastTracepoints],
"FastTracepoints", "fast-tracepoints", 0);
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -920,6 +920,19 @@ tdefault_can_run_breakpoint_commands (st
return 0;
}
+static int
+delegate_can_run_dprintf_agent_call (struct target_ops *self)
+{
+ self = self->beneath;
+ return self->to_can_run_dprintf_agent_call (self);
+}
+
+static int
+tdefault_can_run_dprintf_agent_call (struct target_ops *self)
+{
+ return 0;
+}
+
static struct gdbarch *
delegate_thread_architecture (struct target_ops *self, ptid_t arg1)
{
@@ -1768,6 +1781,8 @@ install_delegators (struct target_ops *o
ops->to_supports_evaluation_of_breakpoint_conditions = delegate_supports_evaluation_of_breakpoint_conditions;
if (ops->to_can_run_breakpoint_commands == NULL)
ops->to_can_run_breakpoint_commands = delegate_can_run_breakpoint_commands;
+ if (ops->to_can_run_dprintf_agent_call == NULL)
+ ops->to_can_run_dprintf_agent_call = delegate_can_run_dprintf_agent_call;
if (ops->to_thread_architecture == NULL)
ops->to_thread_architecture = delegate_thread_architecture;
if (ops->to_trace_init == NULL)
@@ -1961,6 +1976,7 @@ install_dummy_methods (struct target_ops
ops->to_supports_string_tracing = tdefault_supports_string_tracing;
ops->to_supports_evaluation_of_breakpoint_conditions = tdefault_supports_evaluation_of_breakpoint_conditions;
ops->to_can_run_breakpoint_commands = tdefault_can_run_breakpoint_commands;
+ ops->to_can_run_dprintf_agent_call = tdefault_can_run_dprintf_agent_call;
ops->to_thread_architecture = default_thread_architecture;
ops->to_trace_init = tdefault_trace_init;
ops->to_download_tracepoint = tdefault_download_tracepoint;
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -734,6 +734,11 @@ struct target_ops
int (*to_can_run_breakpoint_commands) (struct target_ops *)
TARGET_DEFAULT_RETURN (0);
+ /* Does this target support evaluation of dprintf agent call on its
+ end? */
+ int (*to_can_run_dprintf_agent_call) (struct target_ops *)
+ TARGET_DEFAULT_RETURN (0);
+
/* Determine current architecture of thread PTID.
The target is supposed to determine the architecture of the code where
@@ -1242,6 +1247,12 @@ int target_supports_disable_randomizatio
#define target_can_run_breakpoint_commands() \
(*current_target.to_can_run_breakpoint_commands) (¤t_target)
+/* Return true if this target can handle dprintf agent call
+ on its end. */
+
+#define target_can_run_dprintf_agent_call() \
+ (*current_target.to_can_run_dprintf_agent_call) (¤t_target)
+
extern int target_read_string (CORE_ADDR, char **, int, int *);
extern int target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr,