* target.h (struct target_ops) <to_use_agent>: New field.
(struct target_ops) <to_can_use_agent>: New field.
(target_use_agent, target_can_use_agent): New macro.
* target.c (update_current_target): Update.
* remote.c: New enum `PACKET_QAgent'.
(remote_protocol_features): Add a new element.
(remote_use_agent, remote_can_use_agent): New.
(init_remote_ops): Initialize field `can_use_agent' with
remote_can_use_agent. Intiailize field `use_agent' with
remote_use_agent.
* common/agent.c (use_agent): New global.
* common/agent.h: Declare it.
* tracepoint.c (info_static_tracepoint_markers_command): Add
comment.
* Makefile.in (SFILES): Add common/agent.c and agent.c.
(COMMON_OBS): Add common/agent.o and agent.o
(common-agent.o): New rule.
* agent.c: New.
gdb/doc:
* gdb.texinfo (In-Process Agent): New node.
Document new commands.
(General Query Packets): Add packet `QAgent'.
gdb/gdbserver:
* linux-low.c (linux_supports_agent): New.
(linux_target_ops): Initialize field `supports_agent' with
linux_supports_agent.
* target.h (struct target_ops) <supports_agent>: New.
(target_supports_agent): New macro.
* server.c (handle_general_set): Handle packet 'QAgent'.
(handle_query): Send `QAgent+'.
* Makefile.in (server.o): Depends on agent.h.
+2012-03-03 Yao Qi <yao@codesourcery.com>
+
+ * target.h (struct target_ops) <to_use_agent>: New field.
+ (struct target_ops) <to_can_use_agent>: New field.
+ (target_use_agent, target_can_use_agent): New macro.
+ * target.c (update_current_target): Update.
+ * remote.c: New enum `PACKET_QAgent'.
+ (remote_protocol_features): Add a new element.
+ (remote_use_agent, remote_can_use_agent): New.
+ (init_remote_ops): Initialize field `can_use_agent' with
+ remote_can_use_agent. Intiailize field `use_agent' with
+ remote_use_agent.
+ * common/agent.c (use_agent): New global.
+ * common/agent.h: Declare it.
+ * tracepoint.c (info_static_tracepoint_markers_command): Add
+ comment.
+ * Makefile.in (SFILES): Add common/agent.c and agent.c.
+ (COMMON_OBS): Add common/agent.o and agent.o
+ (common-agent.o): New rule.
+ * agent.c: New.
+
2012-03-03 Yao Qi <yao@codesourcery.com>
* common/agent.c: New.
SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
addrmap.c \
auxv.c ax-general.c ax-gdb.c \
+ agent.c \
bcache.c \
bfd-target.c \
block.c blockframe.c breakpoint.c buildsym.c \
annotate.c common/signals.c copying.c dfp.c gdb.c inf-child.c \
regset.c sol-thread.c windows-termcap.c \
common/common-utils.c common/xml-utils.c \
- common/ptid.c common/buffer.c gdb-dlfcn.c
+ common/ptid.c common/buffer.c gdb-dlfcn.c common/agent.c
LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
annotate.o \
addrmap.o \
auxv.o \
+ agent.o \
bfd-target.o \
blockframe.o breakpoint.o findvar.o regcache.o \
charset.o continuations.o corelow.o disasm.o dummy-frame.o dfp.o \
target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
jit.o progspace.o skip.o \
- common-utils.o buffer.o ptid.o gdb-dlfcn.o
+ common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o
TSOBS = inflow.o
$(COMPILE) $(srcdir)/common/linux-procfs.c
$(POSTCOMPILE)
+common-agent.o: $(srcdir)/common/agent.c
+ $(COMPILE) $(srcdir)/common/agent.c
+ $(POSTCOMPILE)
+
#
# gdb/tui/ dependencies
#
--- /dev/null
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "agent.h"
+
+/* Enum strings for "set|show agent". */
+
+static const char can_use_agent_on[] = "on";
+static const char can_use_agent_off[] = "off";
+static const char *can_use_agent_enum[] =
+{
+ can_use_agent_on,
+ can_use_agent_off,
+ NULL,
+};
+
+static const char *can_use_agent = can_use_agent_off;
+
+static void
+show_can_use_agent (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file,
+ _("Debugger's willingness to use agent in inferior "
+ "as a helper is %s.\n"), value);
+}
+
+static void
+set_can_use_agent (char *args, int from_tty, struct cmd_list_element *c)
+{
+ if (target_use_agent (can_use_agent == can_use_agent_on) == 0)
+ /* Something wrong during setting, set flag to default value. */
+ can_use_agent = can_use_agent_off;
+}
+
+/* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_agent;
+
+void
+_initialize_agent (void)
+{
+ add_setshow_enum_cmd ("agent", class_run,
+ can_use_agent_enum,
+ &can_use_agent, _("\
+Set debugger's willingness to use agent as a helper."), _("\
+Show debugger's willingness to use agent as a helper."), _("\
+If on, GDB will delegate some of the debugging operations to the\n\
+agent, if the target supports it. This will speed up those\n\
+operations that are supported by the agent.\n\
+If off, GDB will not use agent, even if such is supported by the\n\
+target."),
+ set_can_use_agent,
+ show_can_use_agent,
+ &setlist, &showlist);
+}
fprintf_unfiltered (gdb_stdlog, fmt, ##args);
#endif
+/* Global flag to determine using agent or not. */
+int use_agent = 0;
+
/* Addresses of in-process agent's symbols both GDB and GDBserver cares
about. */
extern int debug_agent;
+extern int use_agent;
+2012-03-03 Yao Qi <yao@codesourcery.com>
+
+ * gdb.texinfo (In-Process Agent): New node.
+ Document new commands.
+ (General Query Packets): Add packet `QAgent'.
+
2012-03-01 Maciej W. Rozycki <macro@codesourcery.com>
* gdb.texinfo (MIPS Features): Add org.gnu.gdb.mips.dsp.
* GDB/MI:: @value{GDBN}'s Machine Interface.
* Annotations:: @value{GDBN}'s annotation interface.
* JIT Interface:: Using the JIT debugging interface.
+* In-Process Agent:: In-Process Agent
* GDB Bugs:: Reporting bugs in @value{GDBN}
frame. Both have a callback (@code{target_read}) to read bytes off the
target's address space.
+@node In-Process Agent
+@chapter In-Process Agent
+@cindex debugging agent
+The traditional debugging model is conceptually low-speed, but works fine,
+because most bugs can be reproduced in debugging-mode execution. However,
+as multi-core or many-core processors are becoming mainstream, and
+multi-threaded programs become more and more popular, there should be more
+and more bugs that only manifest themselves at normal-mode execution, for
+example, thread races, because debugger's interference with the program's
+timing may conceal the bugs. On the other hand, in some applications,
+it is not feasible for the debugger to interrupt the program's execution
+long enough for the developer to learn anything helpful about its behavior.
+If the program's correctness depends on its real-time behavior, delays
+introduced by a debugger might cause the program to fail, even when the
+code itself is correct. It is useful to be able to observe the program's
+behavior without interrupting it.
+
+Therefore, traditional debugging model is too intrusive to reproduce
+some bugs. In order to reduce the interference with the program, we can
+reduce the number of operations performed by debugger. The
+@dfn{In-Process Agent}, a shared library, is running within the same
+process with inferior, and is able to perform some debugging operations
+itself. As a result, debugger is only involved when necessary, and
+performance of debugging can be improved accordingly. Note that
+interference with program can be reduced but can't be removed completely,
+because the in-process agent will still stop or slow down the program.
+
+The in-process agent can interpret and execute Agent Expressions
+(@pxref{Agent Expressions}) during performing debugging operations. The
+agent expressions can be used for different purposes, such as collecting
+data in tracepoints, and condition evaluation in breakpoints.
+
+@anchor{Control Agent}
+You can control whether the in-process agent is used as an aid for
+debugging with the following commands:
+
+@table @code
+@kindex set agent on
+@item set agent on
+Causes the in-process agent to perform some operations on behalf of the
+debugger. Just which operations requested by the user will be done
+by the in-process agent depends on the its capabilities. For example,
+if you request to evaluate breakpoint conditions in the in-process agent,
+and the in-process agent has such capability as well, then breakpoint
+conditions will be evaluated in the in-process agent.
+
+@kindex set agent off
+@item set agent off
+Disables execution of debugging operations by the in-process agent. All
+of the operations will be performed by @value{GDBN}.
+
+@kindex show agent
+@item show agent
+Display the current setting of execution of debugging operations by
+the in-process agent.
+@end table
+
@node GDB Bugs
@chapter Reporting Bugs in @value{GDBN}
@cindex bugs in @value{GDBN}
@table @samp
+@item QAgent:1
+@item QAgent:0
+Turn on or off the agent as a helper to perform some debugging operations
+delegated from @value{GDBN} (@pxref{Control Agent}).
+
@item QAllow:@var{op}:@var{val}@dots{}
@cindex @samp{QAllow} packet
Specify which operations @value{GDBN} expects to request of the
@tab @samp{-}
@tab No
+@item @samp{QAgent}
+@tab No
+@tab @samp{-}
+@tab No
+
@item @samp{QAllow}
@tab No
@tab @samp{-}
The remote stub understands the @samp{QTDPsrc} packet that supplies
the source form of tracepoint definitions.
+@item QAgent
+The remote stub understands the @samp{QAgent} packet.
+
@item QAllow
The remote stub understands the @samp{QAllow} packet.
+2012-03-03 Yao Qi <yao@codesourcery.com>
+
+ * linux-low.c (linux_supports_agent): New.
+ (linux_target_ops): Initialize field `supports_agent' with
+ linux_supports_agent.
+ * target.h (struct target_ops) <supports_agent>: New.
+ (target_supports_agent): New macro.
+ * server.c (handle_general_set): Handle packet 'QAgent'.
+ (handle_query): Send `QAgent+'.
+ * Makefile.in (server.o): Depends on agent.h.
+
2012-03-03 Yao Qi <yao@codesourcery.com>
* Makefile.in (OBS): Add agent.o.
proc-service.o: proc-service.c $(server_h) $(gdb_proc_service_h)
regcache.o: regcache.c $(server_h) $(regdef_h)
remote-utils.o: remote-utils.c terminal.h $(server_h)
-server.o: server.c $(server_h)
+server.o: server.c $(server_h) $(agent_h)
target.o: target.c $(server_h)
thread-db.o: thread-db.c $(server_h) $(linux_low_h) $(gdb_proc_service_h) \
$(gdb_thread_db_h)
#endif
}
+static int
+linux_supports_agent (void)
+{
+ return 1;
+}
+
/* Enumerate spufs IDs for process PID. */
static int
spu_enumerate_spu_ids (long pid, unsigned char *buf, CORE_ADDR offset, int len)
linux_supports_disable_randomization,
linux_get_min_fast_tracepoint_insn_len,
linux_qxfer_libraries_svr4,
+ linux_supports_agent,
};
static void
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "server.h"
+#include "agent.h"
#if HAVE_UNISTD_H
#include <unistd.h>
&& handle_tracepoint_general_set (own_buf))
return;
+ if (strncmp ("QAgent:", own_buf, strlen ("QAgent:")) == 0)
+ {
+ char *mode = own_buf + strlen ("QAgent:");
+ int req = 0;
+
+ if (strcmp (mode, "0") == 0)
+ req = 0;
+ else if (strcmp (mode, "1") == 0)
+ req = 1;
+ else
+ {
+ /* We don't know what this value is, so complain to GDB. */
+ sprintf (own_buf, "E.Unknown QAgent value");
+ return;
+ }
+
+ /* Update the flag. */
+ use_agent = req;
+ if (remote_debug)
+ fprintf (stderr, "[%s agent]\n", req ? "Enable" : "Disable");
+ write_ok (own_buf);
+ return;
+ }
+
/* Otherwise we didn't know what packet it was. Say we didn't
understand it. */
own_buf[0] = 0;
/* Support target-side breakpoint conditions. */
strcat (own_buf, ";ConditionalBreakpoints+");
+ if (target_supports_agent ())
+ strcat (own_buf, ";QAgent+");
+
return;
}
int (*qxfer_libraries_svr4) (const char *annex, unsigned char *readbuf,
unsigned const char *writebuf,
CORE_ADDR offset, int len);
+
+ /* Return true if target supports debugging agent. */
+ int (*supports_agent) (void);
};
extern struct target_ops *the_target;
(the_target->supports_disable_randomization ? \
(*the_target->supports_disable_randomization) () : 0)
+#define target_supports_agent() \
+ (the_target->supports_agent ? \
+ (*the_target->supports_agent) () : 0)
+
/* Start non-stop mode, returns 0 on success, -1 on failure. */
int start_non_stop (int nonstop);
#include "tracepoint.h"
#include "ax.h"
#include "ax-gdb.h"
+#include "agent.h"
/* Temp hacks for tracepoint encoding migration. */
static char *target_buf;
PACKET_QAllow,
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
+ PACKET_QAgent,
PACKET_MAX
};
PACKET_qXfer_fdpic },
{ "QDisableRandomization", PACKET_DISABLE, remote_supported_packet,
PACKET_QDisableRandomization },
+ { "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent},
{ "tracenz", PACKET_DISABLE,
remote_string_tracing_feature, -1 },
};
return 1;
}
+static int
+remote_use_agent (int use)
+{
+ if (remote_protocol_packets[PACKET_QAgent].support != PACKET_DISABLE)
+ {
+ struct remote_state *rs = get_remote_state ();
+
+ /* If the stub supports QAgent. */
+ sprintf (rs->buf, "QAgent:%d", use);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+
+ if (strcmp (rs->buf, "OK") == 0)
+ {
+ use_agent = use;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+remote_can_use_agent (void)
+{
+ return (remote_protocol_packets[PACKET_QAgent].support != PACKET_DISABLE);
+}
+
static void
init_remote_ops (void)
{
remote_ops.to_static_tracepoint_markers_by_strid
= remote_static_tracepoint_markers_by_strid;
remote_ops.to_traceframe_info = remote_traceframe_info;
+ remote_ops.to_use_agent = remote_use_agent;
+ remote_ops.to_can_use_agent = remote_can_use_agent;
}
/* Set up the extended remote vector by making a copy of the standard
add_packet_config_cmd (&remote_protocol_packets[PACKET_QDisableRandomization],
"QDisableRandomization", "disable-randomization", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
+ "QAgent", "agent", 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
INHERIT (to_static_tracepoint_marker_at, t);
INHERIT (to_static_tracepoint_markers_by_strid, t);
INHERIT (to_traceframe_info, t);
+ INHERIT (to_use_agent, t);
+ INHERIT (to_can_use_agent, t);
INHERIT (to_magic, t);
INHERIT (to_supports_evaluation_of_breakpoint_conditions, t);
/* Do not inherit to_memory_map. */
de_fault (to_supports_evaluation_of_breakpoint_conditions,
(int (*) (void))
return_zero);
+ de_fault (to_use_agent,
+ (int (*) (int))
+ tcomplain);
+ de_fault (to_can_use_agent,
+ (int (*) (void))
+ return_zero);
de_fault (to_execution_direction, default_execution_direction);
#undef de_fault
re-fetching when necessary. */
struct traceframe_info *(*to_traceframe_info) (void);
+ /* Ask the target to use or not to use agent according to USE. Return 1
+ successful, 0 otherwise. */
+ int (*to_use_agent) (int use);
+
+ /* Is the target able to use agent in current state? */
+ int (*to_can_use_agent) (void);
+
int to_magic;
/* Need sub-structure for target machine related rather than comm related?
*/
#define target_traceframe_info() \
(*current_target.to_traceframe_info) ()
+#define target_use_agent(use) \
+ (*current_target.to_use_agent) (use)
+
+#define target_can_use_agent() \
+ (*current_target.to_can_use_agent) ()
+
/* Command logging facility. */
#define target_log_command(p) \
struct ui_out *uiout = current_uiout;
int i;
+ /* We don't have to check target_can_use_agent and agent's capability on
+ static tracepoint here, in order to be compatible with older GDBserver.
+ We don't check USE_AGENT is true or not, because static tracepoints
+ don't work without in-process agent, so we don't bother users to type
+ `set agent on' when to use static tracepoint. */
+
old_chain
= make_cleanup_ui_out_table_begin_end (uiout, 5, -1,
"StaticTracepointMarkersTable");