aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog21
-rw-r--r--gdb/Makefile.in10
-rw-r--r--gdb/agent.c73
-rw-r--r--gdb/common/agent.c3
-rw-r--r--gdb/common/agent.h1
-rw-r--r--gdb/doc/ChangeLog6
-rw-r--r--gdb/doc/gdb.texinfo71
-rw-r--r--gdb/gdbserver/ChangeLog11
-rw-r--r--gdb/gdbserver/Makefile.in2
-rw-r--r--gdb/gdbserver/linux-low.c7
-rw-r--r--gdb/gdbserver/server.c28
-rw-r--r--gdb/gdbserver/target.h7
-rw-r--r--gdb/remote.c36
-rw-r--r--gdb/target.c8
-rw-r--r--gdb/target.h13
-rw-r--r--gdb/tracepoint.c6
16 files changed, 300 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 23ba558..3e6e501 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,26 @@
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.
* common/agent.h: New.
* configure.ac: Add `sys/socket.h' and `sys/un.h' to
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 57ef436..dc473da 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -684,6 +684,7 @@ TARGET_FLAGS_TO_PASS = \
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 \
@@ -740,7 +741,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.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
@@ -854,6 +855,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
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 \
@@ -908,7 +910,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
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
@@ -1927,6 +1929,10 @@ linux-procfs.o: $(srcdir)/common/linux-procfs.c
$(COMPILE) $(srcdir)/common/linux-procfs.c
$(POSTCOMPILE)
+common-agent.o: $(srcdir)/common/agent.c
+ $(COMPILE) $(srcdir)/common/agent.c
+ $(POSTCOMPILE)
+
#
# gdb/tui/ dependencies
#
diff --git a/gdb/agent.c b/gdb/agent.c
new file mode 100644
index 0000000..b751cfe
--- /dev/null
+++ b/gdb/agent.c
@@ -0,0 +1,73 @@
+/* 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);
+}
diff --git a/gdb/common/agent.c b/gdb/common/agent.c
index 7553835..2bd3206 100644
--- a/gdb/common/agent.c
+++ b/gdb/common/agent.c
@@ -41,6 +41,9 @@ int debug_agent = 0;
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. */
diff --git a/gdb/common/agent.h b/gdb/common/agent.h
index 31c46d9..2965215 100644
--- a/gdb/common/agent.h
+++ b/gdb/common/agent.h
@@ -35,3 +35,4 @@ int agent_look_up_symbols (void);
extern int debug_agent;
+extern int use_agent;
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 89ded13..f3e483f 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,9 @@
+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.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index e187b03..62c92e9 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -154,6 +154,7 @@ software in general. We will miss him.
* 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}
@@ -32286,6 +32287,63 @@ frame and to write out the values of the registers in the previous
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}
@@ -34623,6 +34681,11 @@ Here are the currently defined query and set packets:
@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
@@ -35207,6 +35270,11 @@ These are the currently defined stub features and their properties:
@tab @samp{-}
@tab No
+@item @samp{QAgent}
+@tab No
+@tab @samp{-}
+@tab No
+
@item @samp{QAllow}
@tab No
@tab @samp{-}
@@ -35345,6 +35413,9 @@ The remote stub accepts and implements the reverse step packet
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.
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 6cb8789..b115b23 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,16 @@
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.
Add new rule for agent.o.
Track dependence of tracepoint.c on agent.h.
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 439fd20..0dc5e40 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -400,7 +400,7 @@ mem-break.o: mem-break.c $(server_h) $(ax_h)
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)
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 7638ca3..b4f3d5a 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -4854,6 +4854,12 @@ linux_supports_disable_randomization (void)
#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)
@@ -5576,6 +5582,7 @@ static struct target_ops linux_target_ops = {
linux_supports_disable_randomization,
linux_get_min_fast_tracepoint_insn_len,
linux_qxfer_libraries_svr4,
+ linux_supports_agent,
};
static void
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index e3d1f7c..0de3f52 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -18,6 +18,7 @@
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>
@@ -529,6 +530,30 @@ handle_general_set (char *own_buf)
&& 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;
@@ -1624,6 +1649,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
/* Support target-side breakpoint conditions. */
strcat (own_buf, ";ConditionalBreakpoints+");
+ if (target_supports_agent ())
+ strcat (own_buf, ";QAgent+");
+
return;
}
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 03dff0f..256cfd9 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -394,6 +394,9 @@ struct target_ops
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;
@@ -514,6 +517,10 @@ void set_target_ops (struct target_ops *);
(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);
diff --git a/gdb/remote.c b/gdb/remote.c
index 09bf18e..8eb975f 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -65,6 +65,7 @@
#include "tracepoint.h"
#include "ax.h"
#include "ax-gdb.h"
+#include "agent.h"
/* Temp hacks for tracepoint encoding migration. */
static char *target_buf;
@@ -1276,6 +1277,7 @@ enum {
PACKET_QAllow,
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
+ PACKET_QAgent,
PACKET_MAX
};
@@ -3848,6 +3850,7 @@ static struct protocol_feature remote_protocol_features[] = {
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 },
};
@@ -10757,6 +10760,34 @@ remote_set_trace_notes (char *user, char *notes, char *stop_notes)
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)
{
@@ -10869,6 +10900,8 @@ Specify the serial device it is connected to\n\
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
@@ -11382,6 +11415,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
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
diff --git a/gdb/target.c b/gdb/target.c
index d29d37a..87ecf79 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -698,6 +698,8 @@ update_current_target (void)
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. */
@@ -929,6 +931,12 @@ update_current_target (void)
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
diff --git a/gdb/target.h b/gdb/target.h
index e5679b1..850cb38 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -836,6 +836,13 @@ struct target_ops
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?
*/
@@ -1675,6 +1682,12 @@ extern char *target_fileio_read_stralloc (const char *filename);
#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) \
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 0442a60..a519ed3 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -4883,6 +4883,12 @@ info_static_tracepoint_markers_command (char *arg, int from_tty)
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");