gdb:
authorYao Qi <yao@codesourcery.com>
Sat, 3 Mar 2012 03:32:46 +0000 (03:32 +0000)
committerYao Qi <yao@codesourcery.com>
Sat, 3 Mar 2012 03:32:46 +0000 (03:32 +0000)
* 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.

16 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/agent.c [new file with mode: 0644]
gdb/common/agent.c
gdb/common/agent.h
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/gdbserver/ChangeLog
gdb/gdbserver/Makefile.in
gdb/gdbserver/linux-low.c
gdb/gdbserver/server.c
gdb/gdbserver/target.h
gdb/remote.c
gdb/target.c
gdb/target.h
gdb/tracepoint.c

index 23ba558..3e6e501 100644 (file)
@@ -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
index 57ef436..dc473da 100644 (file)
@@ -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 (file)
index 0000000..b751cfe
--- /dev/null
@@ -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);
+}
index 7553835..2bd3206 100644 (file)
@@ -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.  */
 
index 31c46d9..2965215 100644 (file)
@@ -35,3 +35,4 @@ int agent_look_up_symbols (void);
 
 extern int debug_agent;
 
+extern int use_agent;
index 89ded13..f3e483f 100644 (file)
@@ -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.
index e187b03..62c92e9 100644 (file)
@@ -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.
 
index 6cb8789..b115b23 100644 (file)
@@ -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.
index 439fd20..0dc5e40 100644 (file)
@@ -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)
index 7638ca3..b4f3d5a 100644 (file)
@@ -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
index e3d1f7c..0de3f52 100644 (file)
@@ -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;
     }
 
index 03dff0f..256cfd9 100644 (file)
@@ -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);
index 09bf18e..8eb975f 100644 (file)
@@ -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
index d29d37a..87ecf79 100644 (file)
@@ -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
index e5679b1..850cb38 100644 (file)
@@ -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)                                          \
index 0442a60..a519ed3 100644 (file)
@@ -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");