* 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.
This commit is contained in:
Yao Qi 2012-03-03 03:32:46 +00:00
parent 2fa291aca4
commit d1feda864e
16 changed files with 300 additions and 3 deletions

View File

@ -1,3 +1,24 @@
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.

View 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
#

73
gdb/agent.c Normal file
View File

@ -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);
}

View 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. */

View File

@ -35,3 +35,4 @@ int agent_look_up_symbols (void);
extern int debug_agent;
extern int use_agent;

View 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.

View 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.

View File

@ -1,3 +1,14 @@
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.

View 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)

View 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

View 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;
}

View 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);

View 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

View 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

View 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) \

View 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");