* [PATCH 3/9] command set agent on and off.
2012-02-17 2:56 [patch v2] GDB/GDBserver talks with agents Yao Qi
@ 2012-02-17 2:56 ` Yao Qi
2012-02-23 21:51 ` Pedro Alves
2012-02-17 2:56 ` [PATCH 1/9] move agent related code from gdbserver to common/agent.c Yao Qi
` (9 subsequent siblings)
10 siblings, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-17 2:56 UTC (permalink / raw)
To: gdb-patches
This patch adds new command `set agent on|off'.
2012-02-15 Yao Qi <yao@codesourcery.com>
* Makefile.in (SFILES): Add agent.c and common/agent.c.
(COMMON_OBS): Add agent.o and common/agent.o.
(common-agent.o): New rule.
* agent.c: New.
gdb/testsuite:
2012-02-15 Yao Qi <yao@codesourcery.com>
* gdb.trace/strace.exp (strace_info_marker): Set agent on.
(strace_probe_marker, strace_trace_on_same_addr): Likewise.
(strace_trace_on_diff_addr): Likewise.
---
gdb/Makefile.in | 10 ++++-
gdb/agent.c | 70 ++++++++++++++++++++++++++++++++++++
gdb/testsuite/gdb.trace/strace.exp | 4 ++
3 files changed, 82 insertions(+), 2 deletions(-)
create mode 100644 gdb/agent.c
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 38c93c9..edd616f 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -682,6 +682,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 \
@@ -738,7 +739,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
@@ -852,6 +853,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 \
@@ -906,7 +908,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
@@ -1923,6 +1925,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..c10ed89
--- /dev/null
+++ b/gdb/agent.c
@@ -0,0 +1,70 @@
+/* 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;
+}
+
+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/testsuite/gdb.trace/strace.exp b/gdb/testsuite/gdb.trace/strace.exp
index 4d6ea10..8b0c4ef 100644
--- a/gdb/testsuite/gdb.trace/strace.exp
+++ b/gdb/testsuite/gdb.trace/strace.exp
@@ -66,6 +66,7 @@ proc strace_info_marker { } {
set pf_prefix $old_pf_prefix
return -1
}
+ gdb_test_no_output "set agent on"
# List the markers in program. They should be disabled.
gdb_test "info static-tracepoint-markers" \
@@ -91,6 +92,7 @@ proc strace_probe_marker { } {
set pf_prefix $old_pf_prefix
return -1
}
+ gdb_test_no_output "set agent on"
gdb_test "strace -m ust/bar" "Static tracepoint \[0-9\]+ at ${hex}: file.*"
gdb_test "strace -m ust/bar2" "Static tracepoint \[0-9\]+ at ${hex}: file.*"
@@ -127,6 +129,7 @@ proc strace_trace_on_same_addr { type } {
set pf_prefix $old_pf_prefix
return -1
}
+ gdb_test_no_output "set agent on"
set marker_bar_addr ""
set marker_bar2_addr ""
@@ -223,6 +226,7 @@ proc strace_trace_on_diff_addr { } {
set pf_prefix $old_pf_prefix
return -1
}
+ gdb_test_no_output "set agent on"
set marker_bar_addr ""
set marker_bar2_addr ""
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 3/9] command set agent on and off.
2012-02-17 2:56 ` [PATCH 3/9] command set agent on and off Yao Qi
@ 2012-02-23 21:51 ` Pedro Alves
2012-02-24 13:13 ` Yao Qi
0 siblings, 1 reply; 49+ messages in thread
From: Pedro Alves @ 2012-02-23 21:51 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/17/2012 02:54 AM, Yao Qi wrote:
> This patch adds new command `set agent on|off'.
>
> 2012-02-15 Yao Qi <yao@codesourcery.com>
>
> * Makefile.in (SFILES): Add agent.c and common/agent.c.
> (COMMON_OBS): Add agent.o and common/agent.o.
> (common-agent.o): New rule.
> * agent.c: New.
>
> gdb/testsuite:
>
> 2012-02-15 Yao Qi <yao@codesourcery.com>
>
> * gdb.trace/strace.exp (strace_info_marker): Set agent on.
> (strace_probe_marker, strace_trace_on_same_addr): Likewise.
> (strace_trace_on_diff_addr): Likewise.
> ---
> gdb/Makefile.in | 10 ++++-
> gdb/agent.c | 70 ++++++++++++++++++++++++++++++++++++
> gdb/testsuite/gdb.trace/strace.exp | 4 ++
> 3 files changed, 82 insertions(+), 2 deletions(-)
> create mode 100644 gdb/agent.c
>
> diff --git a/gdb/Makefile.in b/gdb/Makefile.in
> index 38c93c9..edd616f 100644
> --- a/gdb/Makefile.in
> +++ b/gdb/Makefile.in
> @@ -682,6 +682,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 \
> @@ -738,7 +739,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
>
> @@ -852,6 +853,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 \
> @@ -906,7 +908,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
>
> @@ -1923,6 +1925,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..c10ed89
> --- /dev/null
> +++ b/gdb/agent.c
> @@ -0,0 +1,70 @@
> +/* 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;
> +}
> +
> +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/testsuite/gdb.trace/strace.exp b/gdb/testsuite/gdb.trace/strace.exp
> index 4d6ea10..8b0c4ef 100644
> --- a/gdb/testsuite/gdb.trace/strace.exp
> +++ b/gdb/testsuite/gdb.trace/strace.exp
> @@ -66,6 +66,7 @@ proc strace_info_marker { } {
> set pf_prefix $old_pf_prefix
> return -1
> }
> + gdb_test_no_output "set agent on"
>
> # List the markers in program. They should be disabled.
> gdb_test "info static-tracepoint-markers" \
> @@ -91,6 +92,7 @@ proc strace_probe_marker { } {
> set pf_prefix $old_pf_prefix
> return -1
> }
> + gdb_test_no_output "set agent on"
>
> gdb_test "strace -m ust/bar" "Static tracepoint \[0-9\]+ at ${hex}: file.*"
> gdb_test "strace -m ust/bar2" "Static tracepoint \[0-9\]+ at ${hex}: file.*"
> @@ -127,6 +129,7 @@ proc strace_trace_on_same_addr { type } {
> set pf_prefix $old_pf_prefix
> return -1
> }
> + gdb_test_no_output "set agent on"
>
> set marker_bar_addr ""
> set marker_bar2_addr ""
> @@ -223,6 +226,7 @@ proc strace_trace_on_diff_addr { } {
> set pf_prefix $old_pf_prefix
> return -1
> }
> + gdb_test_no_output "set agent on"
>
> set marker_bar_addr ""
> set marker_bar2_addr ""
Hmm, is it really the right thing to do to require turning this
on for static tracepoints? We didn't need it before, and there's
not way for doing static tracepoints without the in-process agent,
so it just looks like unnecessary extra trouble for the user.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 3/9] command set agent on and off.
2012-02-23 21:51 ` Pedro Alves
@ 2012-02-24 13:13 ` Yao Qi
2012-02-24 14:15 ` Pedro Alves
0 siblings, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-24 13:13 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 531 bytes --]
On 02/24/2012 05:20 AM, Pedro Alves wrote:
>> > + gdb_test_no_output "set agent on"
>> >
>> > set marker_bar_addr ""
>> > set marker_bar2_addr ""
> Hmm, is it really the right thing to do to require turning this
> on for static tracepoints? We didn't need it before, and there's
> not way for doing static tracepoints without the in-process agent,
> so it just looks like unnecessary extra trouble for the user.
I agree. These changes in test case strace.exp are removed out of
the patch.
--
Yao (é½å°§)
[-- Attachment #2: 0003-command-set-agent-on-and-off.patch --]
[-- Type: text/x-patch, Size: 4531 bytes --]
This patch adds new command `set agent on|off'.
2012-02-17 Yao Qi <yao@codesourcery.com>
* Makefile.in (SFILES): Add agent.c and common/agent.c.
(COMMON_OBS): Add agent.o and common/agent.o.
(common-agent.o): New rule.
* agent.c: New.
---
gdb/Makefile.in | 10 ++++++-
gdb/agent.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+), 2 deletions(-)
create mode 100644 gdb/agent.c
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 38c93c9..edd616f 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -682,6 +682,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 \
@@ -738,7 +739,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
@@ -852,6 +853,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 \
@@ -906,7 +908,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
@@ -1923,6 +1925,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..c10ed89
--- /dev/null
+++ b/gdb/agent.c
@@ -0,0 +1,70 @@
+/* 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;
+}
+
+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);
+}
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 3/9] command set agent on and off.
2012-02-24 13:13 ` Yao Qi
@ 2012-02-24 14:15 ` Pedro Alves
0 siblings, 0 replies; 49+ messages in thread
From: Pedro Alves @ 2012-02-24 14:15 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/24/2012 01:04 PM, Yao Qi wrote:
> On 02/24/2012 05:20 AM, Pedro Alves wrote:
>>>> + gdb_test_no_output "set agent on"
>>>>
>>>> set marker_bar_addr ""
>>>> set marker_bar2_addr ""
>> Hmm, is it really the right thing to do to require turning this
>> on for static tracepoints? We didn't need it before, and there's
>> not way for doing static tracepoints without the in-process agent,
>> so it just looks like unnecessary extra trouble for the user.
>
> I agree. These changes in test case strace.exp are removed out of
> the patch.
Okay.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH 1/9] move agent related code from gdbserver to common/agent.c
2012-02-17 2:56 [patch v2] GDB/GDBserver talks with agents Yao Qi
2012-02-17 2:56 ` [PATCH 3/9] command set agent on and off Yao Qi
@ 2012-02-17 2:56 ` Yao Qi
2012-02-17 9:55 ` Mark Kettenis
2012-02-23 21:05 ` Pedro Alves
2012-02-17 2:57 ` [PATCH 5/9] agent capability Yao Qi
` (8 subsequent siblings)
10 siblings, 2 replies; 49+ messages in thread
From: Yao Qi @ 2012-02-17 2:56 UTC (permalink / raw)
To: gdb-patches
Compared with version 1, there are some changes,
- Check linux/un.h in both GDB and GDBserver's configure script, and wrap unix socket
related code by HAVE_LINUX_UN_H, to make it doesn't break other builds.
- Rename function names containing "ust".
- Define a macro DEBUG_AGENT using different functions on GDB and GDBserver to log.
Note that some global variables are not made per-process in this patch series. So GDB is
able to talk with agent in single-process. For working with agent in multi-process, it
would be a separate patch.
gdb:
2012-02-13 Yao Qi <yao@codesourcery.com>
* common/agent.c: New.
* common/agent.h: New.
* configure.ac: Add `sys/socket.h' and `linux/un.h' to
AC_CHECK_HEADERS.
* configure, configh.in: Regenerated.
gdb/gdbserver:
2012-02-13 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.
* tracepoint.c (run_inferior_command_1):
(run_inferior_command): Call agent_run_command.
(gdb_ust_connect_sync_socket): Deleted. Move it to
common/agent.c.
(resume_thread, stop_thread): Likewise.
(gdb_ust_socket_init): Renamed to ...
(gdb_agent_socket_init): ... New.
(gdb_ust_thread): Renamed to ...
(gdb_agent_helper_thread): ... New.
(gdb_ust_init): Move some code to ...
(gdb_agent_init): ... here. New.
[HAVE_UST]: Call gdb_ust_init.
(initialize_tracepoint_ftlib): Call gdb_agent_init.
* configure.ac: Add `linux/un.h' to AC_CHECK_HEADERS.
* config.in, configure: Regenerated.
---
gdb/common/agent.c | 297 ++++++++++++++++++++++++++++++++++++++++++++
gdb/common/agent.h | 37 ++++++
gdb/config.in | 6 +
gdb/configure | 20 +++-
gdb/configure.ac | 9 ++-
gdb/gdbserver/Makefile.in | 8 +-
gdb/gdbserver/config.in | 3 +
gdb/gdbserver/configure | 19 +++
gdb/gdbserver/configure.ac | 8 ++
gdb/gdbserver/tracepoint.c | 285 +++++++++---------------------------------
10 files changed, 464 insertions(+), 228 deletions(-)
create mode 100644 gdb/common/agent.c
create mode 100644 gdb/common/agent.h
diff --git a/gdb/common/agent.c b/gdb/common/agent.c
new file mode 100644
index 0000000..657bba6
--- /dev/null
+++ b/gdb/common/agent.c
@@ -0,0 +1,297 @@
+/* Shared utility routines for GDB to interact with agent.
+
+ Copyright (C) 2009-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/>. */
+
+#ifdef GDBSERVER
+#include "server.h"
+#else
+#include "defs.h"
+#include "target.h"
+#include "inferior.h" /* for non_stop */
+#endif
+
+#include <string.h>
+#include <unistd.h>
+#include "agent.h"
+
+int debug_agent = 0;
+
+#ifdef GDBSERVER
+#define DEBUG_AGENT(fmt, args...) \
+ if (debug_agent) \
+ fprintf (stderr, fmt, ##args);
+#else
+#define DEBUG_AGENT(fmt, args...) \
+ if (debug_agent) \
+ fprintf_unfiltered (gdb_stdlog, fmt, ##args);
+#endif
+
+/* Addresses of in-process agent's symbols both GDB and GDBserver cares
+ about. */
+
+struct ipa_sym_addresses
+{
+ CORE_ADDR addr_helper_thread_id;
+ CORE_ADDR addr_cmd_buf;
+};
+
+/* Cache of the helper thread id. FIXME: this global should be made
+ per-process. */
+static unsigned int helper_thread_id = 0;
+
+static struct
+{
+ const char *name;
+ int offset;
+ int required;
+} symbol_list[] = {
+ IPA_SYM(helper_thread_id),
+ IPA_SYM(cmd_buf),
+};
+
+static struct ipa_sym_addresses ipa_sym_addrs;
+
+/* Look up all symbols needed by agent. Return 0 if all the symbols are
+ found, return non-zero otherwise. */
+
+int
+agent_look_up_symbols (void)
+{
+ int i;
+
+ for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
+ {
+ CORE_ADDR *addrp =
+ (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset);
+#ifdef GDBSERVER
+
+ if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
+#else
+ struct minimal_symbol *sym = lookup_minimal_symbol (symbol_list[i].name,
+ NULL, NULL);
+
+ if (sym != NULL)
+ *addrp = SYMBOL_VALUE_ADDRESS (sym);
+ else
+#endif
+ {
+ DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static unsigned int
+agent_get_helper_thread_id (void)
+{
+ if (helper_thread_id == 0)
+ {
+#ifdef GDBSERVER
+ if (read_inferior_memory (ipa_sym_addrs.addr_helper_thread_id,
+ (unsigned char *) &helper_thread_id,
+ sizeof helper_thread_id))
+#else
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+ gdb_byte buf[4];
+
+ if (target_read_memory (ipa_sym_addrs.addr_helper_thread_id,
+ buf, sizeof buf) == 0)
+ helper_thread_id = extract_unsigned_integer (buf, sizeof buf,
+ byte_order);
+ else
+#endif
+ {
+ warning ("Error reading helper thread's id in lib");
+ }
+ }
+
+ return helper_thread_id;
+}
+
+#ifdef HAVE_LINUX_UN_H
+#include <sys/socket.h>
+#include <linux/un.h>
+#define SOCK_DIR P_tmpdir
+#endif
+
+/* Connects to synchronization socket. PID is the pid of inferior, which is
+ used to set up connection socket. */
+
+static int
+gdb_connect_sync_socket (int pid)
+{
+#ifdef HAVE_LINUX_UN_H
+ struct sockaddr_un addr;
+ int res, fd;
+ char path[UNIX_PATH_MAX];
+
+ res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid);
+ if (res >= UNIX_PATH_MAX)
+ return -1;
+
+ res = fd = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (res == -1)
+ {
+ warning ("error opening sync socket: %s\n", strerror (errno));
+ return -1;
+ }
+
+ addr.sun_family = AF_UNIX;
+
+ res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
+ if (res >= UNIX_PATH_MAX)
+ {
+ warning ("string overflow allocating socket name\n");
+ close (fd);
+ return -1;
+ }
+
+ res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
+ if (res == -1)
+ {
+ warning ("error connecting sync socket (%s): %s. "
+ "Make sure the directory exists and that it is writable.",
+ path, strerror (errno));
+ close (fd);
+ return -1;
+ }
+
+ return fd;
+#else
+ return -1;
+#endif
+}
+
+/* Execute an agent command in inferior. PID is the value of pid of inferior.
+ CMD is the buffer for command. GDB or GDBserver will store command into
+ it and fetch return result from CMD. The interaction between GDB/GDBserver
+ and agent is synchronized by synchronization socket. Return zeor if success,
+ otherwise return non-zero. */
+
+int
+agent_run_command (int pid, const char *cmd)
+{
+ int fd;
+ int tid = agent_get_helper_thread_id ();
+ ptid_t ptid = ptid_build (pid, tid, 0);
+ int len = strlen (cmd) + 1;
+
+#ifdef GDBSERVER
+ int ret = write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
+ (const unsigned char *) cmd, len);
+#else
+ int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf, cmd, len);
+#endif
+
+ if (ret != 0)
+ {
+ warning ("unable to write");
+ return -1;
+ }
+
+ DEBUG_AGENT ("agent: resumed helper thread\n");
+
+ /* Resume helper thread. */
+#ifdef GDBSERVER
+{
+ struct thread_resume resume_info;
+
+ resume_info.thread = ptid;
+ resume_info.kind = resume_continue;
+ resume_info.sig = TARGET_SIGNAL_0;
+ (*the_target->resume) (&resume_info, 1);
+}
+#else
+ target_resume (ptid, 0, TARGET_SIGNAL_0);
+#endif
+
+ fd = gdb_connect_sync_socket (pid);
+ if (fd >= 0)
+ {
+ char buf[1] = "";
+ int ret;
+
+ DEBUG_AGENT ("agent: signalling helper thread\n");
+
+ do
+ {
+ ret = write (fd, buf, 1);
+ } while (ret == -1 && errno == EINTR);
+
+ DEBUG_AGENT ("agent:waiting for helper thread's response\n");
+
+ do
+ {
+ ret = read (fd, buf, 1);
+ } while (ret == -1 && errno == EINTR);
+
+ close (fd);
+
+ DEBUG_AGENT ("agent:helper thread's response received\n");
+ }
+ else
+ return -1;
+
+ /* Need to read response with the inferior stopped. */
+ if (!ptid_equal (ptid, null_ptid))
+ {
+ struct target_waitstatus status;
+ int was_non_stop = non_stop;
+ /* Stop thread PTID. */
+ DEBUG_AGENT ("agent: stop helper thread\n");
+#ifdef GDBSERVER
+ {
+ struct thread_resume resume_info;
+
+ resume_info.thread = ptid;
+ resume_info.kind = resume_stop;
+ resume_info.sig = TARGET_SIGNAL_0;
+ (*the_target->resume) (&resume_info, 1);
+ }
+
+ non_stop = 1;
+ mywait (ptid, &status, 0, 0);
+#else
+ non_stop = 1;
+ target_stop (ptid);
+
+ memset (&status, 0, sizeof (status));
+ target_wait (ptid, &status, 0);
+#endif
+ non_stop = was_non_stop;
+ }
+
+ if (fd >= 0)
+ {
+#ifdef GDBSERVER
+ if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
+ (unsigned char *) cmd, IPA_CMD_BUF_SIZE))
+#else
+ if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd,
+ IPA_CMD_BUF_SIZE))
+#endif
+ {
+ warning ("Error reading command response");
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/gdb/common/agent.h b/gdb/common/agent.h
new file mode 100644
index 0000000..31c46d9
--- /dev/null
+++ b/gdb/common/agent.h
@@ -0,0 +1,37 @@
+/* Shared utility routines for GDB to interact with agent.
+
+ Copyright (C) 2009-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/>. */
+
+int agent_run_command (int pid, const char *cmd);
+
+int agent_look_up_symbols (void);
+
+#define STRINGIZE_1(STR) #STR
+#define STRINGIZE(STR) STRINGIZE_1(STR)
+#define IPA_SYM(SYM) \
+ { \
+ STRINGIZE (gdb_agent_ ## SYM), \
+ offsetof (struct ipa_sym_addresses, addr_ ## SYM) \
+ }
+
+/* The size in bytes of the buffer used to talk to the IPA helper
+ thread. */
+#define IPA_CMD_BUF_SIZE 1024
+
+extern int debug_agent;
+
diff --git a/gdb/config.in b/gdb/config.in
index bae1763..d9d1a0c 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -254,6 +254,9 @@
/* Define to 1 if you have the <link.h> header file. */
#undef HAVE_LINK_H
+/* Define to 1 if you have the <linux/un.h> header file. */
+#undef HAVE_LINUX_UN_H
+
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
@@ -644,6 +647,9 @@
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
diff --git a/gdb/configure b/gdb/configure
index 11c044c..1b50d1b 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -11678,7 +11678,7 @@ for ac_header in nlist.h machine/reg.h poll.h sys/poll.h proc_service.h \
sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \
sys/types.h sys/wait.h wait.h termios.h termio.h \
sgtty.h unistd.h elf_hp.h ctype.h time.h locale.h \
- dlfcn.h
+ dlfcn.h sys/socket.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -11744,6 +11744,24 @@ fi
done
+for ac_header in linux/un.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "linux/un.h" "ac_cv_header_linux_un_h" "
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+
+"
+if test "x$ac_cv_header_linux_un_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LINUX_UN_H 1
+_ACEOF
+
+fi
+
+done
+
+
# On Solaris 2.[789], we need to define _MSE_INT_H to avoid a clash
# between <widec.h> and <wchar.h> that would cause AC_CHECK_HEADERS to
# think that we don't have <curses.h> if we're using GCC.
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 36da463..8c2f291 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -986,7 +986,7 @@ AC_CHECK_HEADERS([nlist.h machine/reg.h poll.h sys/poll.h proc_service.h \
sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \
sys/types.h sys/wait.h wait.h termios.h termio.h \
sgtty.h unistd.h elf_hp.h ctype.h time.h locale.h \
- dlfcn.h])
+ dlfcn.h sys/socket.h])
AC_CHECK_HEADERS(link.h, [], [],
[#if HAVE_SYS_TYPES_H
# include <sys/types.h>
@@ -1006,6 +1006,13 @@ AC_CHECK_HEADERS(sys/user.h, [], [],
#endif
])
+AC_CHECK_HEADERS(linux/un.h, [], [],
+[
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+])
+
# On Solaris 2.[789], we need to define _MSE_INT_H to avoid a clash
# between <widec.h> and <wchar.h> that would cause AC_CHECK_HEADERS to
# think that we don't have <curses.h> if we're using GCC.
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 6ccf5ae..17fd043 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -135,7 +135,7 @@ SOURCES = $(SFILES)
TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
- utils.o version.o \
+ utils.o version.o agent.o \
mem-break.o hostio.o event-loop.o tracepoint.o \
xml-utils.o common-utils.o ptid.o buffer.o \
$(XML_BUILTIN) \
@@ -335,6 +335,7 @@ regcache_h = $(srcdir)/regcache.h
signals_def = $(srcdir)/../../include/gdb/signals.def
signals_h = $(srcdir)/../../include/gdb/signals.h $(signals_def)
ptid_h = $(srcdir)/../common/ptid.h
+agent_h = $(srcdir)/../common/agent.h
linux_osdata_h = $(srcdir)/../common/linux-osdata.h
server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h \
$(srcdir)/mem-break.h $(srcdir)/../common/gdb_signals.h \
@@ -398,7 +399,7 @@ server.o: server.c $(server_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)
-tracepoint.o: tracepoint.c $(server_h) $(srcdir)/../common/ax.def
+tracepoint.o: tracepoint.c $(server_h) $(srcdir)/../common/ax.def $(agent_h)
utils.o: utils.c $(server_h)
gdbreplay.o: gdbreplay.c config.h
@@ -423,6 +424,9 @@ ptid.o: ../common/ptid.c $(ptid_h)
buffer.o: ../common/buffer.c $(server_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+agent.o: ../common/agent.c $(server_h) $(agent_h)
+ $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+
# We build memmem.c without -Werror because this file is not under
# our control. On LynxOS, the compiler generates some warnings
# because str-two-way.h uses a constant (MAX_SIZE) whose definition
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index a9472ea..f83ecf1 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -73,6 +73,9 @@
/* Define if the target supports register sets. */
#undef HAVE_LINUX_REGSETS
+/* Define to 1 if you have the <linux/un.h> header file. */
+#undef HAVE_LINUX_UN_H
+
/* Define if the target supports PTRACE_PEEKUSR for register access. */
#undef HAVE_LINUX_USRREGS
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index d92a00f..a392377 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -4163,6 +4163,25 @@ fi
done
+
+for ac_header in linux/un.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "linux/un.h" "ac_cv_header_linux_un_h" "
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+
+"
+if test "x$ac_cv_header_linux_un_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LINUX_UN_H 1
+_ACEOF
+
+fi
+
+done
+
+
for ac_func in pread pwrite pread64
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index 30666ec..6730020 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -43,6 +43,14 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
errno.h fcntl.h signal.h sys/file.h malloc.h dnl
sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
netinet/tcp.h arpa/inet.h sys/wait.h)
+
+AC_CHECK_HEADERS(linux/un.h, [], [],
+[
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+])
+
AC_CHECK_FUNCS(pread pwrite pread64)
AC_REPLACE_FUNCS(memmem vasprintf vsnprintf)
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 5c565fe..091af5a 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -17,6 +17,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "server.h"
+#include "agent.h"
+
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
@@ -185,18 +187,8 @@ struct ipa_sym_addresses
CORE_ADDR addr_get_trace_state_variable_value;
CORE_ADDR addr_set_trace_state_variable_value;
CORE_ADDR addr_ust_loaded;
- CORE_ADDR addr_helper_thread_id;
- CORE_ADDR addr_cmd_buf;
};
-#define STRINGIZE_1(STR) #STR
-#define STRINGIZE(STR) STRINGIZE_1(STR)
-#define IPA_SYM(SYM) \
- { \
- STRINGIZE (gdb_agent_ ## SYM), \
- offsetof (struct ipa_sym_addresses, addr_ ## SYM) \
- }
-
static struct
{
const char *name;
@@ -232,11 +224,9 @@ static struct
IPA_SYM(get_trace_state_variable_value),
IPA_SYM(set_trace_state_variable_value),
IPA_SYM(ust_loaded),
- IPA_SYM(helper_thread_id),
- IPA_SYM(cmd_buf),
};
-struct ipa_sym_addresses ipa_sym_addrs;
+static struct ipa_sym_addresses ipa_sym_addrs;
int all_tracepoint_symbols_looked_up;
@@ -355,6 +345,9 @@ tracepoint_look_up_symbols (void)
}
}
+ if (agent_look_up_symbols () != 0)
+ return;
+
all_tracepoint_symbols_looked_up = 1;
}
@@ -1312,10 +1305,6 @@ static LONGEST get_timestamp (void);
#define cmpxchg(mem, oldval, newval) \
__sync_val_compare_and_swap (mem, oldval, newval)
-/* The size in bytes of the buffer used to talk to the IPA helper
- thread. */
-#define CMD_BUF_SIZE 1024
-
/* Record that an error occurred during expression evaluation. */
static void
@@ -2275,7 +2264,7 @@ cmd_qtinit (char *packet)
static void
unprobe_marker_at (CORE_ADDR address)
{
- char cmd[CMD_BUF_SIZE];
+ char cmd[IPA_CMD_BUF_SIZE];
sprintf (cmd, "unprobe_marker_at:%s", paddress (address));
run_inferior_command (cmd);
@@ -2849,7 +2838,7 @@ have_fast_tracepoint_trampoline_buffer (char *buf)
static int
probe_marker_at (CORE_ADDR address, char *errout)
{
- char cmd[CMD_BUF_SIZE];
+ char cmd[IPA_CMD_BUF_SIZE];
int err;
sprintf (cmd, "probe_marker_at:%s", paddress (address));
@@ -7304,7 +7293,7 @@ upload_fast_traceframes (void)
#ifdef IN_PROCESS_AGENT
IP_AGENT_EXPORT int ust_loaded;
-IP_AGENT_EXPORT char cmd_buf[CMD_BUF_SIZE];
+IP_AGENT_EXPORT char cmd_buf[IPA_CMD_BUF_SIZE];
#ifdef HAVE_UST
@@ -7555,94 +7544,8 @@ static struct ltt_available_probe gdb_ust_probe =
#endif /* HAVE_UST */
#endif /* IN_PROCESS_AGENT */
-#ifdef HAVE_UST
-
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#ifndef UNIX_PATH_MAX
-#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
-#endif
-
-/* Where we put the socked used for synchronization. */
-#define SOCK_DIR P_tmpdir
-
-#endif /* HAVE_UST */
-
#ifndef IN_PROCESS_AGENT
-#ifdef HAVE_UST
-
-static int
-gdb_ust_connect_sync_socket (int pid)
-{
- struct sockaddr_un addr;
- int res, fd;
- char path[UNIX_PATH_MAX];
-
- res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", SOCK_DIR, pid);
- if (res >= UNIX_PATH_MAX)
- {
- trace_debug ("string overflow allocating socket name");
- return -1;
- }
-
- res = fd = socket (PF_UNIX, SOCK_STREAM, 0);
- if (res == -1)
- {
- warning ("error opening sync socket: %s\n", strerror (errno));
- return -1;
- }
-
- addr.sun_family = AF_UNIX;
-
- res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
- if (res >= UNIX_PATH_MAX)
- {
- warning ("string overflow allocating socket name\n");
- close (fd);
- return -1;
- }
-
- res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
- if (res == -1)
- {
- warning ("error connecting sync socket (%s): %s. "
- "Make sure the directory exists and that it is writable.",
- path, strerror (errno));
- close (fd);
- return -1;
- }
-
- return fd;
-}
-
-/* Resume thread PTID. */
-
-static void
-resume_thread (ptid_t ptid)
-{
- struct thread_resume resume_info;
-
- resume_info.thread = ptid;
- resume_info.kind = resume_continue;
- resume_info.sig = TARGET_SIGNAL_0;
- (*the_target->resume) (&resume_info, 1);
-}
-
-/* Stop thread PTID. */
-
-static void
-stop_thread (ptid_t ptid)
-{
- struct thread_resume resume_info;
-
- resume_info.thread = ptid;
- resume_info.kind = resume_stop;
- resume_info.sig = TARGET_SIGNAL_0;
- (*the_target->resume) (&resume_info, 1);
-}
-
/* Ask the in-process agent to run a command. Since we don't want to
have to handle the IPA hitting breakpoints while running the
command, we pause all threads, remove all breakpoints, and then set
@@ -7654,91 +7557,14 @@ static int
run_inferior_command (char *cmd)
{
int err = -1;
- int fd = -1;
int pid = ptid_get_pid (current_inferior->entry.id);
- int tid;
- ptid_t ptid = null_ptid;
trace_debug ("run_inferior_command: running: %s", cmd);
pause_all (0);
uninsert_all_breakpoints ();
- if (read_inferior_integer (ipa_sym_addrs.addr_helper_thread_id, &tid))
- {
- warning ("Error reading helper thread's id in lib");
- goto out;
- }
-
- if (tid == 0)
- {
- warning ("helper thread not initialized yet");
- goto out;
- }
-
- if (write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
- (unsigned char *) cmd, strlen (cmd) + 1))
- {
- warning ("Error writing command");
- goto out;
- }
-
- ptid = ptid_build (pid, tid, 0);
-
- resume_thread (ptid);
-
- fd = gdb_ust_connect_sync_socket (pid);
- if (fd >= 0)
- {
- char buf[1] = "";
- int ret;
-
- trace_debug ("signalling helper thread");
-
- do
- {
- ret = write (fd, buf, 1);
- } while (ret == -1 && errno == EINTR);
-
- trace_debug ("waiting for helper thread's response");
-
- do
- {
- ret = read (fd, buf, 1);
- } while (ret == -1 && errno == EINTR);
-
- close (fd);
-
- trace_debug ("helper thread's response received");
- }
-
- out:
-
- /* Need to read response with the inferior stopped. */
- if (!ptid_equal (ptid, null_ptid))
- {
- int was_non_stop = non_stop;
- struct target_waitstatus status;
-
- stop_thread (ptid);
- non_stop = 1;
- mywait (ptid, &status, 0, 0);
- non_stop = was_non_stop;
- }
-
- if (fd >= 0)
- {
- if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
- (unsigned char *) cmd, CMD_BUF_SIZE))
- {
- warning ("Error reading command response");
- }
- else
- {
- err = 0;
- trace_debug ("run_inferior_command: response: %s", cmd);
- }
- }
+ err = agent_run_command (pid, (const char *) cmd);
reinsert_all_breakpoints ();
unpause_all (0);
@@ -7746,24 +7572,22 @@ run_inferior_command (char *cmd)
return err;
}
-#else /* HAVE_UST */
+#else /* !IN_PROCESS_AGENT */
-static int
-run_inferior_command (char *cmd)
-{
- return -1;
-}
+#include <sys/socket.h>
+#include <sys/un.h>
-#endif /* HAVE_UST */
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
+#endif
-#else /* !IN_PROCESS_AGENT */
+/* Where we put the socked used for synchronization. */
+#define SOCK_DIR P_tmpdir
/* Thread ID of the helper thread. GDBserver reads this to know which
is the help thread. This is an LWP id on Linux. */
int helper_thread_id;
-#ifdef HAVE_UST
-
static int
init_named_socket (const char *name)
{
@@ -7816,7 +7640,7 @@ init_named_socket (const char *name)
}
static int
-gdb_ust_socket_init (void)
+gdb_agent_socket_init (void)
{
int result, fd;
char name[UNIX_PATH_MAX];
@@ -7838,17 +7662,7 @@ gdb_ust_socket_init (void)
return fd;
}
-/* Return an hexstr version of the STR C string, fit for sending to
- GDB. */
-
-static char *
-cstr_to_hexstr (const char *str)
-{
- int len = strlen (str);
- char *hexstr = xmalloc (len * 2 + 1);
- convert_int_to_ascii ((gdb_byte *) str, hexstr, len);
- return hexstr;
-}
+#ifdef HAVE_UST
/* The next marker to be returned on a qTsSTM command. */
static const struct marker *next_st;
@@ -7888,6 +7702,18 @@ next_marker (const struct marker *m)
return NULL;
}
+/* Return an hexstr version of the STR C string, fit for sending to
+ GDB. */
+
+static char *
+cstr_to_hexstr (const char *str)
+{
+ int len = strlen (str);
+ char *hexstr = xmalloc (len * 2 + 1);
+ convert_int_to_ascii ((gdb_byte *) str, hexstr, len);
+ return hexstr;
+}
+
/* Compose packet that is the response to the qTsSTM/qTfSTM/qTSTMat
packets. */
@@ -8048,16 +7874,29 @@ cmd_qtstmat (char *packet)
return -1;
}
+static void
+gdb_ust_init (void)
+{
+ if (!dlsym_ust ())
+ return;
+
+ USTF(ltt_probe_register) (&gdb_ust_probe);
+}
+
+#endif /* HAVE_UST */
+
#include <sys/syscall.h>
+/* Helper thread of agent. */
+
static void *
-gdb_ust_thread (void *arg)
+gdb_agent_helper_thread (void *arg)
{
int listen_fd;
while (1)
{
- listen_fd = gdb_ust_socket_init ();
+ listen_fd = gdb_agent_socket_init ();
if (helper_thread_id == 0)
helper_thread_id = syscall (SYS_gettid);
@@ -8107,7 +7946,12 @@ gdb_ust_thread (void *arg)
if (cmd_buf[0])
{
- if (strcmp ("qTfSTM", cmd_buf) == 0)
+ if (strcmp (cmd_buf, "help") == 0)
+ {
+ strcpy (cmd_buf, "for help, press F1\n");
+ }
+#ifdef HAVE_UST
+ else if (strcmp ("qTfSTM", cmd_buf) == 0)
{
cmd_qtfstm (cmd_buf);
}
@@ -8133,10 +7977,7 @@ gdb_ust_thread (void *arg)
{
cmd_qtstmat (cmd_buf);
}
- else if (strcmp (cmd_buf, "help") == 0)
- {
- strcpy (cmd_buf, "for help, press F1\n");
- }
+#endif /* HAVE_UST */
else
strcpy (cmd_buf, "");
}
@@ -8151,18 +7992,16 @@ gdb_ust_thread (void *arg)
}
#include <signal.h>
+#include <pthread.h>
static void
-gdb_ust_init (void)
+gdb_agent_init (void)
{
int res;
pthread_t thread;
sigset_t new_mask;
sigset_t orig_mask;
- if (!dlsym_ust ())
- return;
-
/* We want the helper thread to be as transparent as possible, so
have it inherit an all-signals-blocked mask. */
@@ -8173,7 +8012,7 @@ gdb_ust_init (void)
res = pthread_create (&thread,
NULL,
- gdb_ust_thread,
+ gdb_agent_helper_thread,
NULL);
res = pthread_sigmask (SIG_SETMASK, &orig_mask, NULL);
@@ -8183,11 +8022,11 @@ gdb_ust_init (void)
while (helper_thread_id == 0)
usleep (1);
- USTF(ltt_probe_register) (&gdb_ust_probe);
+#ifdef HAVE_UST
+ gdb_ust_init ();
+#endif
}
-#endif /* HAVE_UST */
-
#include <sys/mman.h>
#include <fcntl.h>
@@ -8218,9 +8057,7 @@ initialize_tracepoint_ftlib (void)
{
initialize_tracepoint ();
-#ifdef HAVE_UST
- gdb_ust_init ();
-#endif
+ gdb_agent_init ();
}
#endif /* IN_PROCESS_AGENT */
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 1/9] move agent related code from gdbserver to common/agent.c
2012-02-17 2:56 ` [PATCH 1/9] move agent related code from gdbserver to common/agent.c Yao Qi
@ 2012-02-17 9:55 ` Mark Kettenis
2012-02-23 21:05 ` Pedro Alves
1 sibling, 0 replies; 49+ messages in thread
From: Mark Kettenis @ 2012-02-17 9:55 UTC (permalink / raw)
To: yao; +Cc: gdb-patches
> From: Yao Qi <yao@codesourcery.com>
> Date: Fri, 17 Feb 2012 10:54:52 +0800
>
> Compared with version 1, there are some changes,
>
> - Check linux/un.h in both GDB and GDBserver's configure script, and wrap unix socket
> related code by HAVE_LINUX_UN_H, to make it doesn't break other builds.
I'm pretty sure you should not be including <linux/un.h> directly, but
use <sys/un.h> instead.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 1/9] move agent related code from gdbserver to common/agent.c
2012-02-17 2:56 ` [PATCH 1/9] move agent related code from gdbserver to common/agent.c Yao Qi
2012-02-17 9:55 ` Mark Kettenis
@ 2012-02-23 21:05 ` Pedro Alves
2012-02-23 21:17 ` Pedro Alves
2012-02-24 7:57 ` Yao Qi
1 sibling, 2 replies; 49+ messages in thread
From: Pedro Alves @ 2012-02-23 21:05 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/17/2012 02:54 AM, Yao Qi wrote:
> 2012-02-13 Yao Qi <yao@codesourcery.com>
>
> * common/agent.c: New.
> * common/agent.h: New.
> * configure.ac: Add `sys/socket.h' and `linux/un.h' to
> AC_CHECK_HEADERS.
> * configure, configh.in: Regenerated.
>
> gdb/gdbserver:
>
> 2012-02-13 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.
> * tracepoint.c (run_inferior_command_1):
> (run_inferior_command): Call agent_run_command.
> (gdb_ust_connect_sync_socket): Deleted. Move it to
> common/agent.c.
> (resume_thread, stop_thread): Likewise.
> (gdb_ust_socket_init): Renamed to ...
> (gdb_agent_socket_init): ... New.
> (gdb_ust_thread): Renamed to ...
> (gdb_agent_helper_thread): ... New.
> (gdb_ust_init): Move some code to ...
> (gdb_agent_init): ... here. New.
> [HAVE_UST]: Call gdb_ust_init.
> (initialize_tracepoint_ftlib): Call gdb_agent_init.
> * configure.ac: Add `linux/un.h' to AC_CHECK_HEADERS.
> * config.in, configure: Regenerated.
Something fishy with the indentation here. Make entries and indented
with one tab.
> ---
> gdb/common/agent.c | 297 ++++++++++++++++++++++++++++++++++++++++++++
> gdb/common/agent.h | 37 ++++++
> gdb/config.in | 6 +
> gdb/configure | 20 +++-
> gdb/configure.ac | 9 ++-
> gdb/gdbserver/Makefile.in | 8 +-
> gdb/gdbserver/config.in | 3 +
> gdb/gdbserver/configure | 19 +++
> gdb/gdbserver/configure.ac | 8 ++
> gdb/gdbserver/tracepoint.c | 285 +++++++++---------------------------------
> 10 files changed, 464 insertions(+), 228 deletions(-)
> create mode 100644 gdb/common/agent.c
> create mode 100644 gdb/common/agent.h
>
> diff --git a/gdb/common/agent.c b/gdb/common/agent.c
> new file mode 100644
> index 0000000..657bba6
> --- /dev/null
> +++ b/gdb/common/agent.c
> @@ -0,0 +1,297 @@
> +/* Shared utility routines for GDB to interact with agent.
> +
> + Copyright (C) 2009-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/>. */
> +
> +#ifdef GDBSERVER
> +#include "server.h"
> +#else
> +#include "defs.h"
> +#include "target.h"
> +#include "inferior.h" /* for non_stop */
> +#endif
> +
> +#include <string.h>
> +#include <unistd.h>
> +#include "agent.h"
> +
> +int debug_agent = 0;
> +
> +#ifdef GDBSERVER
> +#define DEBUG_AGENT(fmt, args...) \
> + if (debug_agent) \
> + fprintf (stderr, fmt, ##args);
> +#else
> +#define DEBUG_AGENT(fmt, args...) \
> + if (debug_agent) \
> + fprintf_unfiltered (gdb_stdlog, fmt, ##args);
> +#endif
> +
> +/* Addresses of in-process agent's symbols both GDB and GDBserver cares
> + about. */
> +
> +struct ipa_sym_addresses
> +{
> + CORE_ADDR addr_helper_thread_id;
> + CORE_ADDR addr_cmd_buf;
> +};
> +
> +/* Cache of the helper thread id. FIXME: this global should be made
> + per-process. */
> +static unsigned int helper_thread_id = 0;
> +
> +static struct
> +{
> + const char *name;
> + int offset;
> + int required;
> +} symbol_list[] = {
> + IPA_SYM(helper_thread_id),
> + IPA_SYM(cmd_buf),
> +};
> +
> +static struct ipa_sym_addresses ipa_sym_addrs;
> +
> +/* Look up all symbols needed by agent. Return 0 if all the symbols are
> + found, return non-zero otherwise. */
> +
> +int
> +agent_look_up_symbols (void)
> +{
> + int i;
> +
> + for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
> + {
> + CORE_ADDR *addrp =
> + (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset);
> +#ifdef GDBSERVER
> +
> + if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
> +#else
> + struct minimal_symbol *sym = lookup_minimal_symbol (symbol_list[i].name,
> + NULL, NULL);
> +
> + if (sym != NULL)
> + *addrp = SYMBOL_VALUE_ADDRESS (sym);
> + else
> +#endif
> + {
> + DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name);
> + return -1;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static unsigned int
> +agent_get_helper_thread_id (void)
> +{
> + if (helper_thread_id == 0)
> + {
> +#ifdef GDBSERVER
> + if (read_inferior_memory (ipa_sym_addrs.addr_helper_thread_id,
> + (unsigned char *) &helper_thread_id,
> + sizeof helper_thread_id))
> +#else
> + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
> + gdb_byte buf[4];
> +
> + if (target_read_memory (ipa_sym_addrs.addr_helper_thread_id,
> + buf, sizeof buf) == 0)
> + helper_thread_id = extract_unsigned_integer (buf, sizeof buf,
> + byte_order);
> + else
> +#endif
> + {
> + warning ("Error reading helper thread's id in lib");
> + }
> + }
> +
> + return helper_thread_id;
> +}
> +
> +#ifdef HAVE_LINUX_UN_H
> +#include <sys/socket.h>
> +#include <linux/un.h>
> +#define SOCK_DIR P_tmpdir
> +#endif
> +
> +/* Connects to synchronization socket. PID is the pid of inferior, which is
> + used to set up connection socket. */
set up the connection socket.
> +
> +static int
> +gdb_connect_sync_socket (int pid)
> +{
> +#ifdef HAVE_LINUX_UN_H
> + struct sockaddr_un addr;
> + int res, fd;
> + char path[UNIX_PATH_MAX];
> +
> + res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid);
> + if (res >= UNIX_PATH_MAX)
> + return -1;
> +
> + res = fd = socket (PF_UNIX, SOCK_STREAM, 0);
> + if (res == -1)
> + {
> + warning ("error opening sync socket: %s\n", strerror (errno));
> + return -1;
> + }
> +
> + addr.sun_family = AF_UNIX;
> +
> + res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
> + if (res >= UNIX_PATH_MAX)
> + {
> + warning ("string overflow allocating socket name\n");
> + close (fd);
> + return -1;
> + }
> +
> + res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
> + if (res == -1)
> + {
> + warning ("error connecting sync socket (%s): %s. "
> + "Make sure the directory exists and that it is writable.",
> + path, strerror (errno));
> + close (fd);
> + return -1;
> + }
> +
> + return fd;
> +#else
> + return -1;
> +#endif
> +}
> +
> +/* Execute an agent command in inferior. PID is the value of pid of inferior.
in the inferior. of the inferior.
> + CMD is the buffer for command. GDB or GDBserver will store command into
store the command.
> + it and fetch return result from CMD. The interaction between GDB/GDBserver
fetch the return result.
> + and agent is synchronized by synchronization socket. Return zeor if success,
and the agent. by a synchronization socket. zero.
> + otherwise return non-zero. */
> +
> +int
> +agent_run_command (int pid, const char *cmd)
> +{
The code at the caller in gdbserver also stops all threads (try with non-stop),
and removes breakpoints , so that the helper thread doesn't trip on any
breakpoint (e.g., a breakpoint at write/read, or a catch system),
so this is easy to break on gdb as is, but okay.
> + int fd;
> + int tid = agent_get_helper_thread_id ();
> + ptid_t ptid = ptid_build (pid, tid, 0);
> + int len = strlen (cmd) + 1;
> +
> +#ifdef GDBSERVER
> + int ret = write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
> + (const unsigned char *) cmd, len);
> +#else
> + int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf, cmd, len);
> +#endif
> +
> + if (ret != 0)
> + {
> + warning ("unable to write");
> + return -1;
> + }
> +
> + DEBUG_AGENT ("agent: resumed helper thread\n");
> +
> + /* Resume helper thread. */
> +#ifdef GDBSERVER
> +{
> + struct thread_resume resume_info;
> +
> + resume_info.thread = ptid;
> + resume_info.kind = resume_continue;
> + resume_info.sig = TARGET_SIGNAL_0;
> + (*the_target->resume) (&resume_info, 1);
> +}
> +#else
> + target_resume (ptid, 0, TARGET_SIGNAL_0);
> +#endif
> +
> + fd = gdb_connect_sync_socket (pid);
> + if (fd >= 0)
> + {
> + char buf[1] = "";
> + int ret;
> +
> + DEBUG_AGENT ("agent: signalling helper thread\n");
> +
> + do
> + {
> + ret = write (fd, buf, 1);
> + } while (ret == -1 && errno == EINTR);
> +
> + DEBUG_AGENT ("agent:waiting for helper thread's response\n");
missing space after colon.
> +
> + do
> + {
> + ret = read (fd, buf, 1);
> + } while (ret == -1 && errno == EINTR);
> +
> + close (fd);
> +
> + DEBUG_AGENT ("agent:helper thread's response received\n");
missing space after colon.
> + }
> + else
> + return -1;
> +
> + /* Need to read response with the inferior stopped. */
> + if (!ptid_equal (ptid, null_ptid))
> + {
> + struct target_waitstatus status;
> + int was_non_stop = non_stop;
> + /* Stop thread PTID. */
> + DEBUG_AGENT ("agent: stop helper thread\n");
> +#ifdef GDBSERVER
> + {
> + struct thread_resume resume_info;
> +
> + resume_info.thread = ptid;
> + resume_info.kind = resume_stop;
> + resume_info.sig = TARGET_SIGNAL_0;
> + (*the_target->resume) (&resume_info, 1);
> + }
> +
> + non_stop = 1;
> + mywait (ptid, &status, 0, 0);
> +#else
> + non_stop = 1;
> + target_stop (ptid);
> +
> + memset (&status, 0, sizeof (status));
> + target_wait (ptid, &status, 0);
> +#endif
> + non_stop = was_non_stop;
> + }
> +
> + if (fd >= 0)
> + {
> +#ifdef GDBSERVER
> + if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
> + (unsigned char *) cmd, IPA_CMD_BUF_SIZE))
> +#else
> + if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd,
> + IPA_CMD_BUF_SIZE))
> +#endif
> + {
> + warning ("Error reading command response");
> + return -1;
> + }
> + }
> +
> + return 0;
> +}
> @@ -7746,24 +7572,22 @@ run_inferior_command (char *cmd)
> return err;
> }
>
> -#else /* HAVE_UST */
> +#else /* !IN_PROCESS_AGENT */
>
> -static int
> -run_inferior_command (char *cmd)
> -{
> - return -1;
> -}
> +#include <sys/socket.h>
> +#include <sys/un.h>
>
Hard to read, but are these now outside of HAVE_UST? That'll break
mingw builds.
> -#endif /* HAVE_UST */
> +#ifndef UNIX_PATH_MAX
> +#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
> +#endif
>
> -#else /* !IN_PROCESS_AGENT */
> +/* Where we put the socked used for synchronization. */
> +#define SOCK_DIR P_tmpdir
> @@ -8107,7 +7946,12 @@ gdb_ust_thread (void *arg)
>
> if (cmd_buf[0])
> {
> - if (strcmp ("qTfSTM", cmd_buf) == 0)
> + if (strcmp (cmd_buf, "help") == 0)
> + {
> + strcpy (cmd_buf, "for help, press F1\n");
> + }
LOL, I remember writing that as a joke, but I didn't remember
that it had ended up in the tree.
> +#ifdef HAVE_UST
> + else if (strcmp ("qTfSTM", cmd_buf) == 0)
> {
> cmd_qtfstm (cmd_buf);
> }
> @@ -8133,10 +7977,7 @@ gdb_ust_thread (void *arg)
> {
> cmd_qtstmat (cmd_buf);
> }
> - else if (strcmp (cmd_buf, "help") == 0)
> - {
> - strcpy (cmd_buf, "for help, press F1\n");
> - }
> +#endif /* HAVE_UST */
> else
> strcpy (cmd_buf, "");
> }
> @@ -8151,18 +7992,16 @@ gdb_ust_thread (void *arg)
> }
Otherwise okay.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 1/9] move agent related code from gdbserver to common/agent.c
2012-02-23 21:05 ` Pedro Alves
@ 2012-02-23 21:17 ` Pedro Alves
2012-02-24 7:57 ` Yao Qi
1 sibling, 0 replies; 49+ messages in thread
From: Pedro Alves @ 2012-02-23 21:17 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/23/2012 09:01 PM, Pedro Alves wrote:
argh, a sign that I probably shouldn't be reviewing at this late hour. I meant,
> Something fishy with the indentation here. Make entries and indented
Make sure entries are indented with one tab.
> breakpoint (e.g., a breakpoint at write/read, or a catch system),
or a catch syscall.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 1/9] move agent related code from gdbserver to common/agent.c
2012-02-23 21:05 ` Pedro Alves
2012-02-23 21:17 ` Pedro Alves
@ 2012-02-24 7:57 ` Yao Qi
2012-02-24 13:40 ` Yao Qi
1 sibling, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-24 7:57 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Mark Kettenis
[-- Attachment #1: Type: text/plain, Size: 1343 bytes --]
On 02/17/2012 05:24 PM, Mark Kettenis wrote:
>>
>> - Check linux/un.h in both GDB and GDBserver's configure script, and
wrap unix socket
>> related code by HAVE_LINUX_UN_H, to make it doesn't break other builds.
>
> I'm pretty sure you should not be including <linux/un.h> directly, but
> use <sys/un.h> instead.
<sys/un.h> is included, and checked in autoconf as well in this new patch.
On 02/24/2012 05:01 AM, Pedro Alves wrote:
>> > +#include <sys/socket.h>
>> > +#include <sys/un.h>
>> >
> Hard to read, but are these now outside of HAVE_UST? That'll break
> mingw builds.
>
They are out of HAVE_UST. They are warpped by #ifdef IN_PROCESS_AGENT.
We don't build IN_PROCESS_AGENT on mingw, so it doesn't break mingw build.
I cross build GDB on linux with "--host=i586-mingw32msvc
--target=i586-mingw32msvc", no errors.
>> > @@ -8107,7 +7946,12 @@ gdb_ust_thread (void *arg)
>> >
>> > if (cmd_buf[0])
>> > {
>> > - if (strcmp ("qTfSTM", cmd_buf) == 0)
>> > + if (strcmp (cmd_buf, "help") == 0)
>> > + {
>> > + strcpy (cmd_buf, "for help, press F1\n");
>> > + }
> LOL, I remember writing that as a joke, but I didn't remember
> that it had ended up in the tree.
>
Removed it for you :)
> Otherwise okay.
This is what I plan to commit once this series are approved totoally.
--
Yao (é½å°§)
[-- Attachment #2: 0001-move-agent-related-code-from-gdbserver-to-common-age.patch --]
[-- Type: text/x-patch, Size: 27050 bytes --]
gdb:
2012-02-24 Yao Qi <yao@codesourcery.com>
* common/agent.c: New.
* common/agent.h: New.
* configure.ac: Add `sys/socket.h' and `sys/un.h' to
AC_CHECK_HEADERS.
* configure, configh.in: Regenerated.
gdb/gdbserver:
2012-02-24 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.
* tracepoint.c (run_inferior_command_1):
(run_inferior_command): Call agent_run_command.
(gdb_ust_connect_sync_socket): Deleted. Move it to
common/agent.c.
(resume_thread, stop_thread): Likewise.
(gdb_ust_socket_init): Renamed to ...
(gdb_agent_socket_init): ... New.
(gdb_ust_thread): Renamed to ...
(gdb_agent_helper_thread): ... New.
(gdb_ust_init): Move some code to ...
(gdb_agent_init): ... here. New.
[HAVE_UST]: Call gdb_ust_init.
(initialize_tracepoint_ftlib): Call gdb_agent_init.
* configure.ac: Add `sys/un.h' to AC_CHECK_HEADERS.
* config.in, configure: Regenerated.
---
gdb/common/agent.c | 302 ++++++++++++++++++++++++++++++++++++++++++++
gdb/common/agent.h | 37 ++++++
gdb/config.in | 6 +
gdb/configure | 2 +-
gdb/configure.ac | 2 +-
gdb/gdbserver/Makefile.in | 8 +-
gdb/gdbserver/config.in | 3 +
gdb/gdbserver/configure | 3 +-
gdb/gdbserver/configure.ac | 3 +-
gdb/gdbserver/tracepoint.c | 281 ++++++++---------------------------------
10 files changed, 416 insertions(+), 231 deletions(-)
create mode 100644 gdb/common/agent.c
create mode 100644 gdb/common/agent.h
diff --git a/gdb/common/agent.c b/gdb/common/agent.c
new file mode 100644
index 0000000..7553835
--- /dev/null
+++ b/gdb/common/agent.c
@@ -0,0 +1,302 @@
+/* Shared utility routines for GDB to interact with agent.
+
+ Copyright (C) 2009-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/>. */
+
+#ifdef GDBSERVER
+#include "server.h"
+#else
+#include "defs.h"
+#include "target.h"
+#include "inferior.h" /* for non_stop */
+#endif
+
+#include <string.h>
+#include <unistd.h>
+#include "agent.h"
+
+int debug_agent = 0;
+
+#ifdef GDBSERVER
+#define DEBUG_AGENT(fmt, args...) \
+ if (debug_agent) \
+ fprintf (stderr, fmt, ##args);
+#else
+#define DEBUG_AGENT(fmt, args...) \
+ if (debug_agent) \
+ fprintf_unfiltered (gdb_stdlog, fmt, ##args);
+#endif
+
+/* Addresses of in-process agent's symbols both GDB and GDBserver cares
+ about. */
+
+struct ipa_sym_addresses
+{
+ CORE_ADDR addr_helper_thread_id;
+ CORE_ADDR addr_cmd_buf;
+};
+
+/* Cache of the helper thread id. FIXME: this global should be made
+ per-process. */
+static unsigned int helper_thread_id = 0;
+
+static struct
+{
+ const char *name;
+ int offset;
+ int required;
+} symbol_list[] = {
+ IPA_SYM(helper_thread_id),
+ IPA_SYM(cmd_buf),
+};
+
+static struct ipa_sym_addresses ipa_sym_addrs;
+
+/* Look up all symbols needed by agent. Return 0 if all the symbols are
+ found, return non-zero otherwise. */
+
+int
+agent_look_up_symbols (void)
+{
+ int i;
+
+ for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
+ {
+ CORE_ADDR *addrp =
+ (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset);
+#ifdef GDBSERVER
+
+ if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
+#else
+ struct minimal_symbol *sym = lookup_minimal_symbol (symbol_list[i].name,
+ NULL, NULL);
+
+ if (sym != NULL)
+ *addrp = SYMBOL_VALUE_ADDRESS (sym);
+ else
+#endif
+ {
+ DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static unsigned int
+agent_get_helper_thread_id (void)
+{
+ if (helper_thread_id == 0)
+ {
+#ifdef GDBSERVER
+ if (read_inferior_memory (ipa_sym_addrs.addr_helper_thread_id,
+ (unsigned char *) &helper_thread_id,
+ sizeof helper_thread_id))
+#else
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+ gdb_byte buf[4];
+
+ if (target_read_memory (ipa_sym_addrs.addr_helper_thread_id,
+ buf, sizeof buf) == 0)
+ helper_thread_id = extract_unsigned_integer (buf, sizeof buf,
+ byte_order);
+ else
+#endif
+ {
+ warning ("Error reading helper thread's id in lib");
+ }
+ }
+
+ return helper_thread_id;
+}
+
+#ifdef HAVE_SYS_UN_H
+#include <sys/socket.h>
+#include <sys/un.h>
+#define SOCK_DIR P_tmpdir
+
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
+#endif
+
+#endif
+
+/* Connects to synchronization socket. PID is the pid of inferior, which is
+ used to set up the connection socket. */
+
+static int
+gdb_connect_sync_socket (int pid)
+{
+#ifdef HAVE_SYS_UN_H
+ struct sockaddr_un addr;
+ int res, fd;
+ char path[UNIX_PATH_MAX];
+
+ res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid);
+ if (res >= UNIX_PATH_MAX)
+ return -1;
+
+ res = fd = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (res == -1)
+ {
+ warning ("error opening sync socket: %s\n", strerror (errno));
+ return -1;
+ }
+
+ addr.sun_family = AF_UNIX;
+
+ res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
+ if (res >= UNIX_PATH_MAX)
+ {
+ warning ("string overflow allocating socket name\n");
+ close (fd);
+ return -1;
+ }
+
+ res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
+ if (res == -1)
+ {
+ warning ("error connecting sync socket (%s): %s. "
+ "Make sure the directory exists and that it is writable.",
+ path, strerror (errno));
+ close (fd);
+ return -1;
+ }
+
+ return fd;
+#else
+ return -1;
+#endif
+}
+
+/* Execute an agent command in the inferior. PID is the value of pid of the
+ inferior. CMD is the buffer for command. GDB or GDBserver will store the
+ command into it and fetch the return result from CMD. The interaction
+ between GDB/GDBserver and the agent is synchronized by a synchronization
+ socket. Return zero if success, otherwise return non-zero. */
+
+int
+agent_run_command (int pid, const char *cmd)
+{
+ int fd;
+ int tid = agent_get_helper_thread_id ();
+ ptid_t ptid = ptid_build (pid, tid, 0);
+ int len = strlen (cmd) + 1;
+
+#ifdef GDBSERVER
+ int ret = write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
+ (const unsigned char *) cmd, len);
+#else
+ int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf, cmd, len);
+#endif
+
+ if (ret != 0)
+ {
+ warning ("unable to write");
+ return -1;
+ }
+
+ DEBUG_AGENT ("agent: resumed helper thread\n");
+
+ /* Resume helper thread. */
+#ifdef GDBSERVER
+{
+ struct thread_resume resume_info;
+
+ resume_info.thread = ptid;
+ resume_info.kind = resume_continue;
+ resume_info.sig = TARGET_SIGNAL_0;
+ (*the_target->resume) (&resume_info, 1);
+}
+#else
+ target_resume (ptid, 0, TARGET_SIGNAL_0);
+#endif
+
+ fd = gdb_connect_sync_socket (pid);
+ if (fd >= 0)
+ {
+ char buf[1] = "";
+ int ret;
+
+ DEBUG_AGENT ("agent: signalling helper thread\n");
+
+ do
+ {
+ ret = write (fd, buf, 1);
+ } while (ret == -1 && errno == EINTR);
+
+ DEBUG_AGENT ("agent: waiting for helper thread's response\n");
+
+ do
+ {
+ ret = read (fd, buf, 1);
+ } while (ret == -1 && errno == EINTR);
+
+ close (fd);
+
+ DEBUG_AGENT ("agent: helper thread's response received\n");
+ }
+ else
+ return -1;
+
+ /* Need to read response with the inferior stopped. */
+ if (!ptid_equal (ptid, null_ptid))
+ {
+ struct target_waitstatus status;
+ int was_non_stop = non_stop;
+ /* Stop thread PTID. */
+ DEBUG_AGENT ("agent: stop helper thread\n");
+#ifdef GDBSERVER
+ {
+ struct thread_resume resume_info;
+
+ resume_info.thread = ptid;
+ resume_info.kind = resume_stop;
+ resume_info.sig = TARGET_SIGNAL_0;
+ (*the_target->resume) (&resume_info, 1);
+ }
+
+ non_stop = 1;
+ mywait (ptid, &status, 0, 0);
+#else
+ non_stop = 1;
+ target_stop (ptid);
+
+ memset (&status, 0, sizeof (status));
+ target_wait (ptid, &status, 0);
+#endif
+ non_stop = was_non_stop;
+ }
+
+ if (fd >= 0)
+ {
+#ifdef GDBSERVER
+ if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
+ (unsigned char *) cmd, IPA_CMD_BUF_SIZE))
+#else
+ if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd,
+ IPA_CMD_BUF_SIZE))
+#endif
+ {
+ warning ("Error reading command response");
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/gdb/common/agent.h b/gdb/common/agent.h
new file mode 100644
index 0000000..31c46d9
--- /dev/null
+++ b/gdb/common/agent.h
@@ -0,0 +1,37 @@
+/* Shared utility routines for GDB to interact with agent.
+
+ Copyright (C) 2009-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/>. */
+
+int agent_run_command (int pid, const char *cmd);
+
+int agent_look_up_symbols (void);
+
+#define STRINGIZE_1(STR) #STR
+#define STRINGIZE(STR) STRINGIZE_1(STR)
+#define IPA_SYM(SYM) \
+ { \
+ STRINGIZE (gdb_agent_ ## SYM), \
+ offsetof (struct ipa_sym_addresses, addr_ ## SYM) \
+ }
+
+/* The size in bytes of the buffer used to talk to the IPA helper
+ thread. */
+#define IPA_CMD_BUF_SIZE 1024
+
+extern int debug_agent;
+
diff --git a/gdb/config.in b/gdb/config.in
index bae1763..cd25b0a 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -644,6 +644,9 @@
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
@@ -653,6 +656,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
/* Define to 1 if you have the <sys/user.h> header file. */
#undef HAVE_SYS_USER_H
diff --git a/gdb/configure b/gdb/configure
index 11c044c..2c306a4 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -11678,7 +11678,7 @@ for ac_header in nlist.h machine/reg.h poll.h sys/poll.h proc_service.h \
sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \
sys/types.h sys/wait.h wait.h termios.h termio.h \
sgtty.h unistd.h elf_hp.h ctype.h time.h locale.h \
- dlfcn.h
+ dlfcn.h sys/socket.h sys/un.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 36da463..ffda45a 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -986,7 +986,7 @@ AC_CHECK_HEADERS([nlist.h machine/reg.h poll.h sys/poll.h proc_service.h \
sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \
sys/types.h sys/wait.h wait.h termios.h termio.h \
sgtty.h unistd.h elf_hp.h ctype.h time.h locale.h \
- dlfcn.h])
+ dlfcn.h sys/socket.h sys/un.h])
AC_CHECK_HEADERS(link.h, [], [],
[#if HAVE_SYS_TYPES_H
# include <sys/types.h>
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 6ccf5ae..17fd043 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -135,7 +135,7 @@ SOURCES = $(SFILES)
TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
- utils.o version.o \
+ utils.o version.o agent.o \
mem-break.o hostio.o event-loop.o tracepoint.o \
xml-utils.o common-utils.o ptid.o buffer.o \
$(XML_BUILTIN) \
@@ -335,6 +335,7 @@ regcache_h = $(srcdir)/regcache.h
signals_def = $(srcdir)/../../include/gdb/signals.def
signals_h = $(srcdir)/../../include/gdb/signals.h $(signals_def)
ptid_h = $(srcdir)/../common/ptid.h
+agent_h = $(srcdir)/../common/agent.h
linux_osdata_h = $(srcdir)/../common/linux-osdata.h
server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h \
$(srcdir)/mem-break.h $(srcdir)/../common/gdb_signals.h \
@@ -398,7 +399,7 @@ server.o: server.c $(server_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)
-tracepoint.o: tracepoint.c $(server_h) $(srcdir)/../common/ax.def
+tracepoint.o: tracepoint.c $(server_h) $(srcdir)/../common/ax.def $(agent_h)
utils.o: utils.c $(server_h)
gdbreplay.o: gdbreplay.c config.h
@@ -423,6 +424,9 @@ ptid.o: ../common/ptid.c $(ptid_h)
buffer.o: ../common/buffer.c $(server_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+agent.o: ../common/agent.c $(server_h) $(agent_h)
+ $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+
# We build memmem.c without -Werror because this file is not under
# our control. On LynxOS, the compiler generates some warnings
# because str-two-way.h uses a constant (MAX_SIZE) whose definition
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index a9472ea..c063642 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -181,6 +181,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index d92a00f..f459844 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -4149,7 +4149,7 @@ _ACEOF
fi
-for ac_header in sgtty.h termio.h termios.h sys/reg.h string.h proc_service.h sys/procfs.h thread_db.h linux/elf.h stdlib.h unistd.h errno.h fcntl.h signal.h sys/file.h malloc.h sys/ioctl.h netinet/in.h sys/socket.h netdb.h netinet/tcp.h arpa/inet.h sys/wait.h
+for ac_header in sgtty.h termio.h termios.h sys/reg.h string.h proc_service.h sys/procfs.h thread_db.h linux/elf.h stdlib.h unistd.h errno.h fcntl.h signal.h sys/file.h malloc.h sys/ioctl.h netinet/in.h sys/socket.h netdb.h netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -4163,6 +4163,7 @@ fi
done
+
for ac_func in pread pwrite pread64
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index 30666ec..f811534 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -42,7 +42,8 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
stdlib.h unistd.h dnl
errno.h fcntl.h signal.h sys/file.h malloc.h dnl
sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
- netinet/tcp.h arpa/inet.h sys/wait.h)
+ netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h)
+
AC_CHECK_FUNCS(pread pwrite pread64)
AC_REPLACE_FUNCS(memmem vasprintf vsnprintf)
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 5c565fe..746e231 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -17,6 +17,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "server.h"
+#include "agent.h"
+
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
@@ -185,18 +187,8 @@ struct ipa_sym_addresses
CORE_ADDR addr_get_trace_state_variable_value;
CORE_ADDR addr_set_trace_state_variable_value;
CORE_ADDR addr_ust_loaded;
- CORE_ADDR addr_helper_thread_id;
- CORE_ADDR addr_cmd_buf;
};
-#define STRINGIZE_1(STR) #STR
-#define STRINGIZE(STR) STRINGIZE_1(STR)
-#define IPA_SYM(SYM) \
- { \
- STRINGIZE (gdb_agent_ ## SYM), \
- offsetof (struct ipa_sym_addresses, addr_ ## SYM) \
- }
-
static struct
{
const char *name;
@@ -232,11 +224,9 @@ static struct
IPA_SYM(get_trace_state_variable_value),
IPA_SYM(set_trace_state_variable_value),
IPA_SYM(ust_loaded),
- IPA_SYM(helper_thread_id),
- IPA_SYM(cmd_buf),
};
-struct ipa_sym_addresses ipa_sym_addrs;
+static struct ipa_sym_addresses ipa_sym_addrs;
int all_tracepoint_symbols_looked_up;
@@ -355,6 +345,9 @@ tracepoint_look_up_symbols (void)
}
}
+ if (agent_look_up_symbols () != 0)
+ return;
+
all_tracepoint_symbols_looked_up = 1;
}
@@ -1312,10 +1305,6 @@ static LONGEST get_timestamp (void);
#define cmpxchg(mem, oldval, newval) \
__sync_val_compare_and_swap (mem, oldval, newval)
-/* The size in bytes of the buffer used to talk to the IPA helper
- thread. */
-#define CMD_BUF_SIZE 1024
-
/* Record that an error occurred during expression evaluation. */
static void
@@ -2275,7 +2264,7 @@ cmd_qtinit (char *packet)
static void
unprobe_marker_at (CORE_ADDR address)
{
- char cmd[CMD_BUF_SIZE];
+ char cmd[IPA_CMD_BUF_SIZE];
sprintf (cmd, "unprobe_marker_at:%s", paddress (address));
run_inferior_command (cmd);
@@ -2849,7 +2838,7 @@ have_fast_tracepoint_trampoline_buffer (char *buf)
static int
probe_marker_at (CORE_ADDR address, char *errout)
{
- char cmd[CMD_BUF_SIZE];
+ char cmd[IPA_CMD_BUF_SIZE];
int err;
sprintf (cmd, "probe_marker_at:%s", paddress (address));
@@ -7304,7 +7293,7 @@ upload_fast_traceframes (void)
#ifdef IN_PROCESS_AGENT
IP_AGENT_EXPORT int ust_loaded;
-IP_AGENT_EXPORT char cmd_buf[CMD_BUF_SIZE];
+IP_AGENT_EXPORT char cmd_buf[IPA_CMD_BUF_SIZE];
#ifdef HAVE_UST
@@ -7555,94 +7544,8 @@ static struct ltt_available_probe gdb_ust_probe =
#endif /* HAVE_UST */
#endif /* IN_PROCESS_AGENT */
-#ifdef HAVE_UST
-
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#ifndef UNIX_PATH_MAX
-#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
-#endif
-
-/* Where we put the socked used for synchronization. */
-#define SOCK_DIR P_tmpdir
-
-#endif /* HAVE_UST */
-
#ifndef IN_PROCESS_AGENT
-#ifdef HAVE_UST
-
-static int
-gdb_ust_connect_sync_socket (int pid)
-{
- struct sockaddr_un addr;
- int res, fd;
- char path[UNIX_PATH_MAX];
-
- res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", SOCK_DIR, pid);
- if (res >= UNIX_PATH_MAX)
- {
- trace_debug ("string overflow allocating socket name");
- return -1;
- }
-
- res = fd = socket (PF_UNIX, SOCK_STREAM, 0);
- if (res == -1)
- {
- warning ("error opening sync socket: %s\n", strerror (errno));
- return -1;
- }
-
- addr.sun_family = AF_UNIX;
-
- res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
- if (res >= UNIX_PATH_MAX)
- {
- warning ("string overflow allocating socket name\n");
- close (fd);
- return -1;
- }
-
- res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
- if (res == -1)
- {
- warning ("error connecting sync socket (%s): %s. "
- "Make sure the directory exists and that it is writable.",
- path, strerror (errno));
- close (fd);
- return -1;
- }
-
- return fd;
-}
-
-/* Resume thread PTID. */
-
-static void
-resume_thread (ptid_t ptid)
-{
- struct thread_resume resume_info;
-
- resume_info.thread = ptid;
- resume_info.kind = resume_continue;
- resume_info.sig = TARGET_SIGNAL_0;
- (*the_target->resume) (&resume_info, 1);
-}
-
-/* Stop thread PTID. */
-
-static void
-stop_thread (ptid_t ptid)
-{
- struct thread_resume resume_info;
-
- resume_info.thread = ptid;
- resume_info.kind = resume_stop;
- resume_info.sig = TARGET_SIGNAL_0;
- (*the_target->resume) (&resume_info, 1);
-}
-
/* Ask the in-process agent to run a command. Since we don't want to
have to handle the IPA hitting breakpoints while running the
command, we pause all threads, remove all breakpoints, and then set
@@ -7654,91 +7557,14 @@ static int
run_inferior_command (char *cmd)
{
int err = -1;
- int fd = -1;
int pid = ptid_get_pid (current_inferior->entry.id);
- int tid;
- ptid_t ptid = null_ptid;
trace_debug ("run_inferior_command: running: %s", cmd);
pause_all (0);
uninsert_all_breakpoints ();
- if (read_inferior_integer (ipa_sym_addrs.addr_helper_thread_id, &tid))
- {
- warning ("Error reading helper thread's id in lib");
- goto out;
- }
-
- if (tid == 0)
- {
- warning ("helper thread not initialized yet");
- goto out;
- }
-
- if (write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
- (unsigned char *) cmd, strlen (cmd) + 1))
- {
- warning ("Error writing command");
- goto out;
- }
-
- ptid = ptid_build (pid, tid, 0);
-
- resume_thread (ptid);
-
- fd = gdb_ust_connect_sync_socket (pid);
- if (fd >= 0)
- {
- char buf[1] = "";
- int ret;
-
- trace_debug ("signalling helper thread");
-
- do
- {
- ret = write (fd, buf, 1);
- } while (ret == -1 && errno == EINTR);
-
- trace_debug ("waiting for helper thread's response");
-
- do
- {
- ret = read (fd, buf, 1);
- } while (ret == -1 && errno == EINTR);
-
- close (fd);
-
- trace_debug ("helper thread's response received");
- }
-
- out:
-
- /* Need to read response with the inferior stopped. */
- if (!ptid_equal (ptid, null_ptid))
- {
- int was_non_stop = non_stop;
- struct target_waitstatus status;
-
- stop_thread (ptid);
- non_stop = 1;
- mywait (ptid, &status, 0, 0);
- non_stop = was_non_stop;
- }
-
- if (fd >= 0)
- {
- if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
- (unsigned char *) cmd, CMD_BUF_SIZE))
- {
- warning ("Error reading command response");
- }
- else
- {
- err = 0;
- trace_debug ("run_inferior_command: response: %s", cmd);
- }
- }
+ err = agent_run_command (pid, (const char *) cmd);
reinsert_all_breakpoints ();
unpause_all (0);
@@ -7746,24 +7572,22 @@ run_inferior_command (char *cmd)
return err;
}
-#else /* HAVE_UST */
+#else /* !IN_PROCESS_AGENT */
-static int
-run_inferior_command (char *cmd)
-{
- return -1;
-}
+#include <sys/socket.h>
+#include <sys/un.h>
-#endif /* HAVE_UST */
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
+#endif
-#else /* !IN_PROCESS_AGENT */
+/* Where we put the socked used for synchronization. */
+#define SOCK_DIR P_tmpdir
/* Thread ID of the helper thread. GDBserver reads this to know which
is the help thread. This is an LWP id on Linux. */
int helper_thread_id;
-#ifdef HAVE_UST
-
static int
init_named_socket (const char *name)
{
@@ -7816,7 +7640,7 @@ init_named_socket (const char *name)
}
static int
-gdb_ust_socket_init (void)
+gdb_agent_socket_init (void)
{
int result, fd;
char name[UNIX_PATH_MAX];
@@ -7838,17 +7662,7 @@ gdb_ust_socket_init (void)
return fd;
}
-/* Return an hexstr version of the STR C string, fit for sending to
- GDB. */
-
-static char *
-cstr_to_hexstr (const char *str)
-{
- int len = strlen (str);
- char *hexstr = xmalloc (len * 2 + 1);
- convert_int_to_ascii ((gdb_byte *) str, hexstr, len);
- return hexstr;
-}
+#ifdef HAVE_UST
/* The next marker to be returned on a qTsSTM command. */
static const struct marker *next_st;
@@ -7888,6 +7702,18 @@ next_marker (const struct marker *m)
return NULL;
}
+/* Return an hexstr version of the STR C string, fit for sending to
+ GDB. */
+
+static char *
+cstr_to_hexstr (const char *str)
+{
+ int len = strlen (str);
+ char *hexstr = xmalloc (len * 2 + 1);
+ convert_int_to_ascii ((gdb_byte *) str, hexstr, len);
+ return hexstr;
+}
+
/* Compose packet that is the response to the qTsSTM/qTfSTM/qTSTMat
packets. */
@@ -8048,16 +7874,29 @@ cmd_qtstmat (char *packet)
return -1;
}
+static void
+gdb_ust_init (void)
+{
+ if (!dlsym_ust ())
+ return;
+
+ USTF(ltt_probe_register) (&gdb_ust_probe);
+}
+
+#endif /* HAVE_UST */
+
#include <sys/syscall.h>
+/* Helper thread of agent. */
+
static void *
-gdb_ust_thread (void *arg)
+gdb_agent_helper_thread (void *arg)
{
int listen_fd;
while (1)
{
- listen_fd = gdb_ust_socket_init ();
+ listen_fd = gdb_agent_socket_init ();
if (helper_thread_id == 0)
helper_thread_id = syscall (SYS_gettid);
@@ -8107,6 +7946,7 @@ gdb_ust_thread (void *arg)
if (cmd_buf[0])
{
+#ifdef HAVE_UST
if (strcmp ("qTfSTM", cmd_buf) == 0)
{
cmd_qtfstm (cmd_buf);
@@ -8133,12 +7973,7 @@ gdb_ust_thread (void *arg)
{
cmd_qtstmat (cmd_buf);
}
- else if (strcmp (cmd_buf, "help") == 0)
- {
- strcpy (cmd_buf, "for help, press F1\n");
- }
- else
- strcpy (cmd_buf, "");
+#endif /* HAVE_UST */
}
/* Fix compiler's warning: ignoring return value of 'write'. */
@@ -8151,18 +7986,16 @@ gdb_ust_thread (void *arg)
}
#include <signal.h>
+#include <pthread.h>
static void
-gdb_ust_init (void)
+gdb_agent_init (void)
{
int res;
pthread_t thread;
sigset_t new_mask;
sigset_t orig_mask;
- if (!dlsym_ust ())
- return;
-
/* We want the helper thread to be as transparent as possible, so
have it inherit an all-signals-blocked mask. */
@@ -8173,7 +8006,7 @@ gdb_ust_init (void)
res = pthread_create (&thread,
NULL,
- gdb_ust_thread,
+ gdb_agent_helper_thread,
NULL);
res = pthread_sigmask (SIG_SETMASK, &orig_mask, NULL);
@@ -8183,11 +8016,11 @@ gdb_ust_init (void)
while (helper_thread_id == 0)
usleep (1);
- USTF(ltt_probe_register) (&gdb_ust_probe);
+#ifdef HAVE_UST
+ gdb_ust_init ();
+#endif
}
-#endif /* HAVE_UST */
-
#include <sys/mman.h>
#include <fcntl.h>
@@ -8218,9 +8051,7 @@ initialize_tracepoint_ftlib (void)
{
initialize_tracepoint ();
-#ifdef HAVE_UST
- gdb_ust_init ();
-#endif
+ gdb_agent_init ();
}
#endif /* IN_PROCESS_AGENT */
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 1/9] move agent related code from gdbserver to common/agent.c
2012-02-24 7:57 ` Yao Qi
@ 2012-02-24 13:40 ` Yao Qi
0 siblings, 0 replies; 49+ messages in thread
From: Yao Qi @ 2012-02-24 13:40 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 427 bytes --]
On 02/24/2012 10:48 AM, Yao Qi wrote:
> +static struct ipa_sym_addresses ipa_sym_addrs;
> +
> +/* Look up all symbols needed by agent. Return 0 if all the symbols are
> + found, return non-zero otherwise. */
> +
> +int
> +agent_look_up_symbols (void)
This version addes a parameter ARG of type `void *', in order to pass
OBJFILE needed in patch 8/9. GDBserver side is not affected by this change.
--
Yao (é½å°§)
[-- Attachment #2: 0001-move-agent-related-code-from-gdbserver-to-common-age.patch --]
[-- Type: text/x-patch, Size: 27082 bytes --]
gdb:
2012-02-17 Yao Qi <yao@codesourcery.com>
* common/agent.c: New.
* common/agent.h: New.
* configure.ac: Add `sys/socket.h' and `sys/un.h' to
AC_CHECK_HEADERS.
* configure, configh.in: Regenerated.
gdb/gdbserver:
2012-02-17 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.
* tracepoint.c (run_inferior_command_1):
(run_inferior_command): Call agent_run_command.
(gdb_ust_connect_sync_socket): Deleted. Move it to
common/agent.c.
(resume_thread, stop_thread): Likewise.
(gdb_ust_socket_init): Renamed to ...
(gdb_agent_socket_init): ... New.
(gdb_ust_thread): Renamed to ...
(gdb_agent_helper_thread): ... New.
(gdb_ust_init): Move some code to ...
(gdb_agent_init): ... here. New.
[HAVE_UST]: Call gdb_ust_init.
(initialize_tracepoint_ftlib): Call gdb_agent_init.
* configure.ac: Add `sys/un.h' to AC_CHECK_HEADERS.
* config.in, configure: Regenerated.
---
gdb/common/agent.c | 303 ++++++++++++++++++++++++++++++++++++++++++++
gdb/common/agent.h | 37 ++++++
gdb/config.in | 6 +
gdb/configure | 2 +-
gdb/configure.ac | 2 +-
gdb/gdbserver/Makefile.in | 8 +-
gdb/gdbserver/config.in | 3 +
gdb/gdbserver/configure | 3 +-
gdb/gdbserver/configure.ac | 3 +-
gdb/gdbserver/tracepoint.c | 281 ++++++++--------------------------------
10 files changed, 417 insertions(+), 231 deletions(-)
create mode 100644 gdb/common/agent.c
create mode 100644 gdb/common/agent.h
diff --git a/gdb/common/agent.c b/gdb/common/agent.c
new file mode 100644
index 0000000..8f7dded
--- /dev/null
+++ b/gdb/common/agent.c
@@ -0,0 +1,303 @@
+/* Shared utility routines for GDB to interact with agent.
+
+ Copyright (C) 2009-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/>. */
+
+#ifdef GDBSERVER
+#include "server.h"
+#else
+#include "defs.h"
+#include "target.h"
+#include "inferior.h" /* for non_stop */
+#endif
+
+#include <string.h>
+#include <unistd.h>
+#include "agent.h"
+
+int debug_agent = 0;
+
+#ifdef GDBSERVER
+#define DEBUG_AGENT(fmt, args...) \
+ if (debug_agent) \
+ fprintf (stderr, fmt, ##args);
+#else
+#define DEBUG_AGENT(fmt, args...) \
+ if (debug_agent) \
+ fprintf_unfiltered (gdb_stdlog, fmt, ##args);
+#endif
+
+/* Addresses of in-process agent's symbols both GDB and GDBserver cares
+ about. */
+
+struct ipa_sym_addresses
+{
+ CORE_ADDR addr_helper_thread_id;
+ CORE_ADDR addr_cmd_buf;
+};
+
+/* Cache of the helper thread id. FIXME: this global should be made
+ per-process. */
+static unsigned int helper_thread_id = 0;
+
+static struct
+{
+ const char *name;
+ int offset;
+ int required;
+} symbol_list[] = {
+ IPA_SYM(helper_thread_id),
+ IPA_SYM(cmd_buf),
+};
+
+static struct ipa_sym_addresses ipa_sym_addrs;
+
+/* Look up all symbols needed by agent. Return 0 if all the symbols are
+ found, return non-zero otherwise. */
+
+int
+agent_look_up_symbols (void *arg)
+{
+ int i;
+
+ for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
+ {
+ CORE_ADDR *addrp =
+ (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset);
+#ifdef GDBSERVER
+
+ if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
+#else
+ struct minimal_symbol *sym =
+ lookup_minimal_symbol (symbol_list[i].name, NULL,
+ (struct objfile *) arg);
+
+ if (sym != NULL)
+ *addrp = SYMBOL_VALUE_ADDRESS (sym);
+ else
+#endif
+ {
+ DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static unsigned int
+agent_get_helper_thread_id (void)
+{
+ if (helper_thread_id == 0)
+ {
+#ifdef GDBSERVER
+ if (read_inferior_memory (ipa_sym_addrs.addr_helper_thread_id,
+ (unsigned char *) &helper_thread_id,
+ sizeof helper_thread_id))
+#else
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+ gdb_byte buf[4];
+
+ if (target_read_memory (ipa_sym_addrs.addr_helper_thread_id,
+ buf, sizeof buf) == 0)
+ helper_thread_id = extract_unsigned_integer (buf, sizeof buf,
+ byte_order);
+ else
+#endif
+ {
+ warning ("Error reading helper thread's id in lib");
+ }
+ }
+
+ return helper_thread_id;
+}
+
+#ifdef HAVE_SYS_UN_H
+#include <sys/socket.h>
+#include <sys/un.h>
+#define SOCK_DIR P_tmpdir
+
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
+#endif
+
+#endif
+
+/* Connects to synchronization socket. PID is the pid of inferior, which is
+ used to set up the connection socket. */
+
+static int
+gdb_connect_sync_socket (int pid)
+{
+#ifdef HAVE_SYS_UN_H
+ struct sockaddr_un addr;
+ int res, fd;
+ char path[UNIX_PATH_MAX];
+
+ res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid);
+ if (res >= UNIX_PATH_MAX)
+ return -1;
+
+ res = fd = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (res == -1)
+ {
+ warning ("error opening sync socket: %s\n", strerror (errno));
+ return -1;
+ }
+
+ addr.sun_family = AF_UNIX;
+
+ res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
+ if (res >= UNIX_PATH_MAX)
+ {
+ warning ("string overflow allocating socket name\n");
+ close (fd);
+ return -1;
+ }
+
+ res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
+ if (res == -1)
+ {
+ warning ("error connecting sync socket (%s): %s. "
+ "Make sure the directory exists and that it is writable.",
+ path, strerror (errno));
+ close (fd);
+ return -1;
+ }
+
+ return fd;
+#else
+ return -1;
+#endif
+}
+
+/* Execute an agent command in the inferior. PID is the value of pid of the
+ inferior. CMD is the buffer for command. GDB or GDBserver will store the
+ command into it and fetch the return result from CMD. The interaction
+ between GDB/GDBserver and the agent is synchronized by a synchronization
+ socket. Return zero if success, otherwise return non-zero. */
+
+int
+agent_run_command (int pid, const char *cmd)
+{
+ int fd;
+ int tid = agent_get_helper_thread_id ();
+ ptid_t ptid = ptid_build (pid, tid, 0);
+ int len = strlen (cmd) + 1;
+
+#ifdef GDBSERVER
+ int ret = write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
+ (const unsigned char *) cmd, len);
+#else
+ int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf, cmd, len);
+#endif
+
+ if (ret != 0)
+ {
+ warning ("unable to write");
+ return -1;
+ }
+
+ DEBUG_AGENT ("agent: resumed helper thread\n");
+
+ /* Resume helper thread. */
+#ifdef GDBSERVER
+{
+ struct thread_resume resume_info;
+
+ resume_info.thread = ptid;
+ resume_info.kind = resume_continue;
+ resume_info.sig = TARGET_SIGNAL_0;
+ (*the_target->resume) (&resume_info, 1);
+}
+#else
+ target_resume (ptid, 0, TARGET_SIGNAL_0);
+#endif
+
+ fd = gdb_connect_sync_socket (pid);
+ if (fd >= 0)
+ {
+ char buf[1] = "";
+ int ret;
+
+ DEBUG_AGENT ("agent: signalling helper thread\n");
+
+ do
+ {
+ ret = write (fd, buf, 1);
+ } while (ret == -1 && errno == EINTR);
+
+ DEBUG_AGENT ("agent: waiting for helper thread's response\n");
+
+ do
+ {
+ ret = read (fd, buf, 1);
+ } while (ret == -1 && errno == EINTR);
+
+ close (fd);
+
+ DEBUG_AGENT ("agent: helper thread's response received\n");
+ }
+ else
+ return -1;
+
+ /* Need to read response with the inferior stopped. */
+ if (!ptid_equal (ptid, null_ptid))
+ {
+ struct target_waitstatus status;
+ int was_non_stop = non_stop;
+ /* Stop thread PTID. */
+ DEBUG_AGENT ("agent: stop helper thread\n");
+#ifdef GDBSERVER
+ {
+ struct thread_resume resume_info;
+
+ resume_info.thread = ptid;
+ resume_info.kind = resume_stop;
+ resume_info.sig = TARGET_SIGNAL_0;
+ (*the_target->resume) (&resume_info, 1);
+ }
+
+ non_stop = 1;
+ mywait (ptid, &status, 0, 0);
+#else
+ non_stop = 1;
+ target_stop (ptid);
+
+ memset (&status, 0, sizeof (status));
+ target_wait (ptid, &status, 0);
+#endif
+ non_stop = was_non_stop;
+ }
+
+ if (fd >= 0)
+ {
+#ifdef GDBSERVER
+ if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
+ (unsigned char *) cmd, IPA_CMD_BUF_SIZE))
+#else
+ if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd,
+ IPA_CMD_BUF_SIZE))
+#endif
+ {
+ warning ("Error reading command response");
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/gdb/common/agent.h b/gdb/common/agent.h
new file mode 100644
index 0000000..43e128c
--- /dev/null
+++ b/gdb/common/agent.h
@@ -0,0 +1,37 @@
+/* Shared utility routines for GDB to interact with agent.
+
+ Copyright (C) 2009-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/>. */
+
+int agent_run_command (int pid, const char *cmd);
+
+int agent_look_up_symbols (void *);
+
+#define STRINGIZE_1(STR) #STR
+#define STRINGIZE(STR) STRINGIZE_1(STR)
+#define IPA_SYM(SYM) \
+ { \
+ STRINGIZE (gdb_agent_ ## SYM), \
+ offsetof (struct ipa_sym_addresses, addr_ ## SYM) \
+ }
+
+/* The size in bytes of the buffer used to talk to the IPA helper
+ thread. */
+#define IPA_CMD_BUF_SIZE 1024
+
+extern int debug_agent;
+
diff --git a/gdb/config.in b/gdb/config.in
index bae1763..cd25b0a 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -644,6 +644,9 @@
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
@@ -653,6 +656,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
/* Define to 1 if you have the <sys/user.h> header file. */
#undef HAVE_SYS_USER_H
diff --git a/gdb/configure b/gdb/configure
index 11c044c..2c306a4 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -11678,7 +11678,7 @@ for ac_header in nlist.h machine/reg.h poll.h sys/poll.h proc_service.h \
sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \
sys/types.h sys/wait.h wait.h termios.h termio.h \
sgtty.h unistd.h elf_hp.h ctype.h time.h locale.h \
- dlfcn.h
+ dlfcn.h sys/socket.h sys/un.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 36da463..ffda45a 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -986,7 +986,7 @@ AC_CHECK_HEADERS([nlist.h machine/reg.h poll.h sys/poll.h proc_service.h \
sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \
sys/types.h sys/wait.h wait.h termios.h termio.h \
sgtty.h unistd.h elf_hp.h ctype.h time.h locale.h \
- dlfcn.h])
+ dlfcn.h sys/socket.h sys/un.h])
AC_CHECK_HEADERS(link.h, [], [],
[#if HAVE_SYS_TYPES_H
# include <sys/types.h>
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 6ccf5ae..17fd043 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -135,7 +135,7 @@ SOURCES = $(SFILES)
TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
- utils.o version.o \
+ utils.o version.o agent.o \
mem-break.o hostio.o event-loop.o tracepoint.o \
xml-utils.o common-utils.o ptid.o buffer.o \
$(XML_BUILTIN) \
@@ -335,6 +335,7 @@ regcache_h = $(srcdir)/regcache.h
signals_def = $(srcdir)/../../include/gdb/signals.def
signals_h = $(srcdir)/../../include/gdb/signals.h $(signals_def)
ptid_h = $(srcdir)/../common/ptid.h
+agent_h = $(srcdir)/../common/agent.h
linux_osdata_h = $(srcdir)/../common/linux-osdata.h
server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h \
$(srcdir)/mem-break.h $(srcdir)/../common/gdb_signals.h \
@@ -398,7 +399,7 @@ server.o: server.c $(server_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)
-tracepoint.o: tracepoint.c $(server_h) $(srcdir)/../common/ax.def
+tracepoint.o: tracepoint.c $(server_h) $(srcdir)/../common/ax.def $(agent_h)
utils.o: utils.c $(server_h)
gdbreplay.o: gdbreplay.c config.h
@@ -423,6 +424,9 @@ ptid.o: ../common/ptid.c $(ptid_h)
buffer.o: ../common/buffer.c $(server_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+agent.o: ../common/agent.c $(server_h) $(agent_h)
+ $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+
# We build memmem.c without -Werror because this file is not under
# our control. On LynxOS, the compiler generates some warnings
# because str-two-way.h uses a constant (MAX_SIZE) whose definition
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index a9472ea..c063642 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -181,6 +181,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index d92a00f..f459844 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -4149,7 +4149,7 @@ _ACEOF
fi
-for ac_header in sgtty.h termio.h termios.h sys/reg.h string.h proc_service.h sys/procfs.h thread_db.h linux/elf.h stdlib.h unistd.h errno.h fcntl.h signal.h sys/file.h malloc.h sys/ioctl.h netinet/in.h sys/socket.h netdb.h netinet/tcp.h arpa/inet.h sys/wait.h
+for ac_header in sgtty.h termio.h termios.h sys/reg.h string.h proc_service.h sys/procfs.h thread_db.h linux/elf.h stdlib.h unistd.h errno.h fcntl.h signal.h sys/file.h malloc.h sys/ioctl.h netinet/in.h sys/socket.h netdb.h netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -4163,6 +4163,7 @@ fi
done
+
for ac_func in pread pwrite pread64
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index 30666ec..f811534 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -42,7 +42,8 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
stdlib.h unistd.h dnl
errno.h fcntl.h signal.h sys/file.h malloc.h dnl
sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
- netinet/tcp.h arpa/inet.h sys/wait.h)
+ netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h)
+
AC_CHECK_FUNCS(pread pwrite pread64)
AC_REPLACE_FUNCS(memmem vasprintf vsnprintf)
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 5c565fe..3b6f2f4 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -17,6 +17,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "server.h"
+#include "agent.h"
+
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
@@ -185,18 +187,8 @@ struct ipa_sym_addresses
CORE_ADDR addr_get_trace_state_variable_value;
CORE_ADDR addr_set_trace_state_variable_value;
CORE_ADDR addr_ust_loaded;
- CORE_ADDR addr_helper_thread_id;
- CORE_ADDR addr_cmd_buf;
};
-#define STRINGIZE_1(STR) #STR
-#define STRINGIZE(STR) STRINGIZE_1(STR)
-#define IPA_SYM(SYM) \
- { \
- STRINGIZE (gdb_agent_ ## SYM), \
- offsetof (struct ipa_sym_addresses, addr_ ## SYM) \
- }
-
static struct
{
const char *name;
@@ -232,11 +224,9 @@ static struct
IPA_SYM(get_trace_state_variable_value),
IPA_SYM(set_trace_state_variable_value),
IPA_SYM(ust_loaded),
- IPA_SYM(helper_thread_id),
- IPA_SYM(cmd_buf),
};
-struct ipa_sym_addresses ipa_sym_addrs;
+static struct ipa_sym_addresses ipa_sym_addrs;
int all_tracepoint_symbols_looked_up;
@@ -355,6 +345,9 @@ tracepoint_look_up_symbols (void)
}
}
+ if (agent_look_up_symbols (NULL) != 0)
+ return;
+
all_tracepoint_symbols_looked_up = 1;
}
@@ -1312,10 +1305,6 @@ static LONGEST get_timestamp (void);
#define cmpxchg(mem, oldval, newval) \
__sync_val_compare_and_swap (mem, oldval, newval)
-/* The size in bytes of the buffer used to talk to the IPA helper
- thread. */
-#define CMD_BUF_SIZE 1024
-
/* Record that an error occurred during expression evaluation. */
static void
@@ -2275,7 +2264,7 @@ cmd_qtinit (char *packet)
static void
unprobe_marker_at (CORE_ADDR address)
{
- char cmd[CMD_BUF_SIZE];
+ char cmd[IPA_CMD_BUF_SIZE];
sprintf (cmd, "unprobe_marker_at:%s", paddress (address));
run_inferior_command (cmd);
@@ -2849,7 +2838,7 @@ have_fast_tracepoint_trampoline_buffer (char *buf)
static int
probe_marker_at (CORE_ADDR address, char *errout)
{
- char cmd[CMD_BUF_SIZE];
+ char cmd[IPA_CMD_BUF_SIZE];
int err;
sprintf (cmd, "probe_marker_at:%s", paddress (address));
@@ -7304,7 +7293,7 @@ upload_fast_traceframes (void)
#ifdef IN_PROCESS_AGENT
IP_AGENT_EXPORT int ust_loaded;
-IP_AGENT_EXPORT char cmd_buf[CMD_BUF_SIZE];
+IP_AGENT_EXPORT char cmd_buf[IPA_CMD_BUF_SIZE];
#ifdef HAVE_UST
@@ -7555,94 +7544,8 @@ static struct ltt_available_probe gdb_ust_probe =
#endif /* HAVE_UST */
#endif /* IN_PROCESS_AGENT */
-#ifdef HAVE_UST
-
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#ifndef UNIX_PATH_MAX
-#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
-#endif
-
-/* Where we put the socked used for synchronization. */
-#define SOCK_DIR P_tmpdir
-
-#endif /* HAVE_UST */
-
#ifndef IN_PROCESS_AGENT
-#ifdef HAVE_UST
-
-static int
-gdb_ust_connect_sync_socket (int pid)
-{
- struct sockaddr_un addr;
- int res, fd;
- char path[UNIX_PATH_MAX];
-
- res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", SOCK_DIR, pid);
- if (res >= UNIX_PATH_MAX)
- {
- trace_debug ("string overflow allocating socket name");
- return -1;
- }
-
- res = fd = socket (PF_UNIX, SOCK_STREAM, 0);
- if (res == -1)
- {
- warning ("error opening sync socket: %s\n", strerror (errno));
- return -1;
- }
-
- addr.sun_family = AF_UNIX;
-
- res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
- if (res >= UNIX_PATH_MAX)
- {
- warning ("string overflow allocating socket name\n");
- close (fd);
- return -1;
- }
-
- res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
- if (res == -1)
- {
- warning ("error connecting sync socket (%s): %s. "
- "Make sure the directory exists and that it is writable.",
- path, strerror (errno));
- close (fd);
- return -1;
- }
-
- return fd;
-}
-
-/* Resume thread PTID. */
-
-static void
-resume_thread (ptid_t ptid)
-{
- struct thread_resume resume_info;
-
- resume_info.thread = ptid;
- resume_info.kind = resume_continue;
- resume_info.sig = TARGET_SIGNAL_0;
- (*the_target->resume) (&resume_info, 1);
-}
-
-/* Stop thread PTID. */
-
-static void
-stop_thread (ptid_t ptid)
-{
- struct thread_resume resume_info;
-
- resume_info.thread = ptid;
- resume_info.kind = resume_stop;
- resume_info.sig = TARGET_SIGNAL_0;
- (*the_target->resume) (&resume_info, 1);
-}
-
/* Ask the in-process agent to run a command. Since we don't want to
have to handle the IPA hitting breakpoints while running the
command, we pause all threads, remove all breakpoints, and then set
@@ -7654,91 +7557,14 @@ static int
run_inferior_command (char *cmd)
{
int err = -1;
- int fd = -1;
int pid = ptid_get_pid (current_inferior->entry.id);
- int tid;
- ptid_t ptid = null_ptid;
trace_debug ("run_inferior_command: running: %s", cmd);
pause_all (0);
uninsert_all_breakpoints ();
- if (read_inferior_integer (ipa_sym_addrs.addr_helper_thread_id, &tid))
- {
- warning ("Error reading helper thread's id in lib");
- goto out;
- }
-
- if (tid == 0)
- {
- warning ("helper thread not initialized yet");
- goto out;
- }
-
- if (write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
- (unsigned char *) cmd, strlen (cmd) + 1))
- {
- warning ("Error writing command");
- goto out;
- }
-
- ptid = ptid_build (pid, tid, 0);
-
- resume_thread (ptid);
-
- fd = gdb_ust_connect_sync_socket (pid);
- if (fd >= 0)
- {
- char buf[1] = "";
- int ret;
-
- trace_debug ("signalling helper thread");
-
- do
- {
- ret = write (fd, buf, 1);
- } while (ret == -1 && errno == EINTR);
-
- trace_debug ("waiting for helper thread's response");
-
- do
- {
- ret = read (fd, buf, 1);
- } while (ret == -1 && errno == EINTR);
-
- close (fd);
-
- trace_debug ("helper thread's response received");
- }
-
- out:
-
- /* Need to read response with the inferior stopped. */
- if (!ptid_equal (ptid, null_ptid))
- {
- int was_non_stop = non_stop;
- struct target_waitstatus status;
-
- stop_thread (ptid);
- non_stop = 1;
- mywait (ptid, &status, 0, 0);
- non_stop = was_non_stop;
- }
-
- if (fd >= 0)
- {
- if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
- (unsigned char *) cmd, CMD_BUF_SIZE))
- {
- warning ("Error reading command response");
- }
- else
- {
- err = 0;
- trace_debug ("run_inferior_command: response: %s", cmd);
- }
- }
+ err = agent_run_command (pid, (const char *) cmd);
reinsert_all_breakpoints ();
unpause_all (0);
@@ -7746,24 +7572,22 @@ run_inferior_command (char *cmd)
return err;
}
-#else /* HAVE_UST */
+#else /* !IN_PROCESS_AGENT */
-static int
-run_inferior_command (char *cmd)
-{
- return -1;
-}
+#include <sys/socket.h>
+#include <sys/un.h>
-#endif /* HAVE_UST */
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
+#endif
-#else /* !IN_PROCESS_AGENT */
+/* Where we put the socked used for synchronization. */
+#define SOCK_DIR P_tmpdir
/* Thread ID of the helper thread. GDBserver reads this to know which
is the help thread. This is an LWP id on Linux. */
int helper_thread_id;
-#ifdef HAVE_UST
-
static int
init_named_socket (const char *name)
{
@@ -7816,7 +7640,7 @@ init_named_socket (const char *name)
}
static int
-gdb_ust_socket_init (void)
+gdb_agent_socket_init (void)
{
int result, fd;
char name[UNIX_PATH_MAX];
@@ -7838,17 +7662,7 @@ gdb_ust_socket_init (void)
return fd;
}
-/* Return an hexstr version of the STR C string, fit for sending to
- GDB. */
-
-static char *
-cstr_to_hexstr (const char *str)
-{
- int len = strlen (str);
- char *hexstr = xmalloc (len * 2 + 1);
- convert_int_to_ascii ((gdb_byte *) str, hexstr, len);
- return hexstr;
-}
+#ifdef HAVE_UST
/* The next marker to be returned on a qTsSTM command. */
static const struct marker *next_st;
@@ -7888,6 +7702,18 @@ next_marker (const struct marker *m)
return NULL;
}
+/* Return an hexstr version of the STR C string, fit for sending to
+ GDB. */
+
+static char *
+cstr_to_hexstr (const char *str)
+{
+ int len = strlen (str);
+ char *hexstr = xmalloc (len * 2 + 1);
+ convert_int_to_ascii ((gdb_byte *) str, hexstr, len);
+ return hexstr;
+}
+
/* Compose packet that is the response to the qTsSTM/qTfSTM/qTSTMat
packets. */
@@ -8048,16 +7874,29 @@ cmd_qtstmat (char *packet)
return -1;
}
+static void
+gdb_ust_init (void)
+{
+ if (!dlsym_ust ())
+ return;
+
+ USTF(ltt_probe_register) (&gdb_ust_probe);
+}
+
+#endif /* HAVE_UST */
+
#include <sys/syscall.h>
+/* Helper thread of agent. */
+
static void *
-gdb_ust_thread (void *arg)
+gdb_agent_helper_thread (void *arg)
{
int listen_fd;
while (1)
{
- listen_fd = gdb_ust_socket_init ();
+ listen_fd = gdb_agent_socket_init ();
if (helper_thread_id == 0)
helper_thread_id = syscall (SYS_gettid);
@@ -8107,6 +7946,7 @@ gdb_ust_thread (void *arg)
if (cmd_buf[0])
{
+#ifdef HAVE_UST
if (strcmp ("qTfSTM", cmd_buf) == 0)
{
cmd_qtfstm (cmd_buf);
@@ -8133,12 +7973,7 @@ gdb_ust_thread (void *arg)
{
cmd_qtstmat (cmd_buf);
}
- else if (strcmp (cmd_buf, "help") == 0)
- {
- strcpy (cmd_buf, "for help, press F1\n");
- }
- else
- strcpy (cmd_buf, "");
+#endif /* HAVE_UST */
}
/* Fix compiler's warning: ignoring return value of 'write'. */
@@ -8151,18 +7986,16 @@ gdb_ust_thread (void *arg)
}
#include <signal.h>
+#include <pthread.h>
static void
-gdb_ust_init (void)
+gdb_agent_init (void)
{
int res;
pthread_t thread;
sigset_t new_mask;
sigset_t orig_mask;
- if (!dlsym_ust ())
- return;
-
/* We want the helper thread to be as transparent as possible, so
have it inherit an all-signals-blocked mask. */
@@ -8173,7 +8006,7 @@ gdb_ust_init (void)
res = pthread_create (&thread,
NULL,
- gdb_ust_thread,
+ gdb_agent_helper_thread,
NULL);
res = pthread_sigmask (SIG_SETMASK, &orig_mask, NULL);
@@ -8183,11 +8016,11 @@ gdb_ust_init (void)
while (helper_thread_id == 0)
usleep (1);
- USTF(ltt_probe_register) (&gdb_ust_probe);
+#ifdef HAVE_UST
+ gdb_ust_init ();
+#endif
}
-#endif /* HAVE_UST */
-
#include <sys/mman.h>
#include <fcntl.h>
@@ -8218,9 +8051,7 @@ initialize_tracepoint_ftlib (void)
{
initialize_tracepoint ();
-#ifdef HAVE_UST
- gdb_ust_init ();
-#endif
+ gdb_agent_init ();
}
#endif /* IN_PROCESS_AGENT */
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH 5/9] agent capability
2012-02-17 2:56 [patch v2] GDB/GDBserver talks with agents Yao Qi
2012-02-17 2:56 ` [PATCH 3/9] command set agent on and off Yao Qi
2012-02-17 2:56 ` [PATCH 1/9] move agent related code from gdbserver to common/agent.c Yao Qi
@ 2012-02-17 2:57 ` Yao Qi
2012-02-17 2:57 ` [PATCH 4/9] agent doc Yao Qi
` (7 subsequent siblings)
10 siblings, 0 replies; 49+ messages in thread
From: Yao Qi @ 2012-02-17 2:57 UTC (permalink / raw)
To: gdb-patches
Different agents may have different capabilities, so this piece of work is to present
what agent can do, and can not do. This version still keeps the implementation of last
version, instead of qSupported-like implementation, because,
- It is independent of "command buffer" and sync socket, so GDB or GDBserver can read
it from agent at any time.
- It is reliable to get capability in this way,
2012-02-13 Yao Qi <yao@codesourcery.com>
* common/agent.c (struct ipa_sym_addresses) <addr_capability>: New.
(agent_capability_check, agent_capability_invalidate): New.
(symbol_list): New array element.
* common/agent.h (enum agent_capa): New.
* target.c (target_pre_inferior): Call agent_capability_invalidate.
---
gdb/common/agent.c | 40 ++++++++++++++++++++++++++++++++++++++++
gdb/common/agent.h | 17 +++++++++++++++++
gdb/target.c | 3 +++
3 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/gdb/common/agent.c b/gdb/common/agent.c
index 5a9ac16..074efea 100644
--- a/gdb/common/agent.c
+++ b/gdb/common/agent.c
@@ -51,6 +51,7 @@ struct ipa_sym_addresses
{
CORE_ADDR addr_helper_thread_id;
CORE_ADDR addr_cmd_buf;
+ CORE_ADDR addr_capability;
};
/* Cache of the helper thread id. FIXME: this global should be made
@@ -65,6 +66,7 @@ static struct
} symbol_list[] = {
IPA_SYM(helper_thread_id),
IPA_SYM(cmd_buf),
+ IPA_SYM(capability),
};
static struct ipa_sym_addresses ipa_sym_addrs;
@@ -298,3 +300,41 @@ agent_run_command (int pid, const char *cmd)
return 0;
}
+
+/* Each bit of it stands for a capability of agent. */
+static unsigned int agent_capability = 0;
+
+/* Return true if agent has capability AGENT_CAP, otherwise return false. */
+
+int
+agent_capability_check (enum agent_capa agent_capa)
+{
+ if (agent_capability == 0)
+ {
+#ifdef GDBSERVER
+ if (read_inferior_memory (ipa_sym_addrs.addr_capability,
+ (unsigned char *) &agent_capability,
+ sizeof agent_capability))
+#else
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+ gdb_byte buf[4];
+
+ if (target_read_memory (ipa_sym_addrs.addr_capability,
+ buf, sizeof buf) == 0)
+ agent_capability = extract_unsigned_integer (buf, sizeof buf,
+ byte_order);
+ else
+#endif
+ warning ("Error reading capability of agent");
+ }
+ return agent_capability & agent_capa;
+}
+
+/* Invalidate the cache of agent capability, so we'll read it from inferior
+ again. Call it when launches a new program or reconnect to remote stub. */
+
+void
+agent_capability_invalidate (void)
+{
+ agent_capability = 0;
+}
diff --git a/gdb/common/agent.h b/gdb/common/agent.h
index 2965215..a1ac9b2 100644
--- a/gdb/common/agent.h
+++ b/gdb/common/agent.h
@@ -36,3 +36,20 @@ int agent_look_up_symbols (void);
extern int debug_agent;
extern int use_agent;
+
+/* Capability of agent. Different agents may have different capabilities,
+ such as installing fast tracepoint or evaluating breakpoint conditions.
+ Capabilities are represented by bit-maps, and each capability occupies one
+ bit. */
+
+enum agent_capa
+{
+ /* Capability to install fast tracepoint. */
+ AGENT_CAPA_FAST_TRACE = 0x1,
+ /* Capability to install static tracepoint. */
+ AGENT_CAPA_STATIC_TRACE = (0x1 << 1),
+};
+
+int agent_capability_check (enum agent_capa);
+
+void agent_capability_invalidate (void);
diff --git a/gdb/target.c b/gdb/target.c
index a7c11c3..776be23 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -43,6 +43,7 @@
#include "inline-frame.h"
#include "tracepoint.h"
#include "gdb/fileio.h"
+#include "agent.h"
static void target_info (char *, int);
@@ -2496,6 +2497,8 @@ target_pre_inferior (int from_tty)
target_clear_description ();
}
+
+ agent_capability_invalidate ();
}
/* Callback for iterate_over_inferiors. Gets rid of the given
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* [PATCH 4/9] agent doc
2012-02-17 2:56 [patch v2] GDB/GDBserver talks with agents Yao Qi
` (2 preceding siblings ...)
2012-02-17 2:57 ` [PATCH 5/9] agent capability Yao Qi
@ 2012-02-17 2:57 ` Yao Qi
2012-02-17 11:38 ` Eli Zaretskii
2012-02-17 2:57 ` [PATCH 7/9] move in_process_agent_loaded to agent_loaded_p Yao Qi
` (6 subsequent siblings)
10 siblings, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-17 2:57 UTC (permalink / raw)
To: gdb-patches
Documentation bits. Leave original contents of node "Agent Expressions" there, with
some minor updates. A new node "Agent" is added.
gdb/doc/
2012-01-21 Yao Qi <yao@codesourcery.com>
* agentexpr.texi (Agent Expressions): Update some parts for agent expression
can not only be used in agent, but also in remote stubs.
Move some contents to ...
* gdb.texinfo (Agent): ... to here. New node.
---
gdb/doc/agentexpr.texi | 35 +++++++++--------------------
gdb/doc/gdb.texinfo | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 67 insertions(+), 24 deletions(-)
diff --git a/gdb/doc/agentexpr.texi b/gdb/doc/agentexpr.texi
index d0f6f15..7075281 100644
--- a/gdb/doc/agentexpr.texi
+++ b/gdb/doc/agentexpr.texi
@@ -13,32 +13,19 @@
@node Agent Expressions
@appendix The GDB Agent Expression Mechanism
-
-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.
-
-Using GDB's @code{trace} and @code{collect} commands, the user can
-specify locations in the program, and arbitrary expressions to evaluate
-when those locations are reached. Later, using the @code{tfind}
-command, she can examine the values those expressions had when the
-program hit the trace points. The expressions may also denote objects
-in memory --- structures or arrays, for example --- whose values GDB
-should record; while visiting a particular tracepoint, the user may
-inspect those objects as if they were in memory at that moment.
-However, because GDB records these values without interacting with the
-user, it can do so quickly and unobtrusively, hopefully not disturbing
-the program's behavior.
-
-When GDB is debugging a remote target, the GDB @dfn{agent} code running
+Agent expression will be used in many cases, such as the expressions used in tracepoints
+for data collection, and expressions used in breakpoint condition evaluation. The
+expressions may also denote registers and objects in memory---structures or arrays, for
+example---whose values @value{GDBN} should record. Originally, agent expressions are used
+in @dfn{agent} (@pxref{Agent}), so they are called @dfn{Agent Expression}. Gradually,
+they are used more widely, such as in remote stub.
+
+When @value{GDBN} is debugging, the @value{GDBN} agent code running
on the target computes the values of the expressions itself. To avoid
-having a full symbolic expression evaluator on the agent, GDB translates
-expressions in the source language into a simpler bytecode language, and
-then sends the bytecode to the agent; the agent then executes the
-bytecode, and records the values for GDB to retrieve later.
+having a full symbolic expression evaluator on the agent or remote stub,
+@value{GDBN} translates expressions in the source language into a simpler bytecode
+language, and then sends the bytecode to the agent; the agent then executes the
+bytecode, and records the values for @value{GDBN} to retrieve later.
The bytecode language is simple; there are forty-odd opcodes, the bulk
of which are the usual vocabulary of C operands (addition, subtraction,
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 34bf77e..a833f34 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.
+* Agent:: Debugging Agent
* GDB Bugs:: Reporting bugs in @value{GDBN}
@@ -32191,6 +32192,61 @@ 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 Agent
+@chapter Debugging 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. @dfn{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 agent will still stop
+or slow down the program.
+
+The agent can interpret and execute @dfn{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.
+
+@menu
+* Control Agent:: Turn agent on and off
+@end menu
+@node Control Agent
+@section Turn Agent On And Off
+
+You can control whether the agent is used as an aid for debugging
+with the following commands:
+
+@table @code
+@item set agent on
+Causes the agent to perform some operations on behalf of the
+debugger. Just which operations requested by the user will be done
+by the agent depends on the agent's capabilities. For example, if
+you request to evaluate breakpoint conditions in the agent, and the
+agent has such capability as well, then breakpoint conditions will be
+evaluated in the agent.
+
+@item set agent off
+Disables execution of debugging operations by the agent. All of the
+operations will be performed by @value{GDBN}.
+@end table
+
@node GDB Bugs
@chapter Reporting Bugs in @value{GDBN}
@cindex bugs in @value{GDBN}
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 4/9] agent doc
2012-02-17 2:57 ` [PATCH 4/9] agent doc Yao Qi
@ 2012-02-17 11:38 ` Eli Zaretskii
2012-02-17 13:34 ` Yao Qi
0 siblings, 1 reply; 49+ messages in thread
From: Eli Zaretskii @ 2012-02-17 11:38 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
> From: Yao Qi <yao@codesourcery.com>
> Date: Fri, 17 Feb 2012 10:54:55 +0800
>
> Documentation bits. Leave original contents of node "Agent Expressions" there, with
> some minor updates. A new node "Agent" is added.
Thanks.
> +Agent expression will be used in many cases, such as the expressions used in tracepoints
> +for data collection, and expressions used in breakpoint condition evaluation. The
Please always format the Texinfo sources with lines that don't exceed
80 characters, preferably even 72.
> +expressions may also denote registers and objects in memory---structures or arrays, for
> +example---whose values @value{GDBN} should record. Originally, agent expressions are used
> +in @dfn{agent} (@pxref{Agent}), so they are called @dfn{Agent Expression}.
I would leave only the latter @dfn, there seems to be no need for the
former one, as you don't describe the agent in this section.
> Gradually,
> +they are used more widely, such as in remote stub.
I don't understand what you wanted to say in this sentence. Does it
really add anything important?
> +The agent can interpret and execute @dfn{Agent Expressions}
> +(@pxref{Agent Expressions}) during performing debugging operations. The
Again, this @dfn is not appropriate here, because this section does
not explain this term.
> +@menu
> +* Control Agent:: Turn agent on and off
> +@end menu
> +@node Control Agent
> +@section Turn Agent On And Off
> +
> +You can control whether the agent is used as an aid for debugging
> +with the following commands:
> +
> +@table @code
> +@item set agent on
@kindex is missing here. All commands should be indexed.
> +Causes the agent to perform some operations on behalf of the
> +debugger. Just which operations requested by the user will be done
> +by the agent depends on the agent's capabilities. For example, if
> +you request to evaluate breakpoint conditions in the agent, and the
> +agent has such capability as well, then breakpoint conditions will be
> +evaluated in the agent.
> +
> +@item set agent off
> +Disables execution of debugging operations by the agent. All of the
> +operations will be performed by @value{GDBN}.
> +@end table
Don't we also have "show agent"?
Anyway, full section for just 2 commands seems like a waste of a
section. Why not make it part of its parent chapter.
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 4/9] agent doc
2012-02-17 11:38 ` Eli Zaretskii
@ 2012-02-17 13:34 ` Yao Qi
2012-02-17 16:10 ` Pedro Alves
2012-02-18 17:11 ` Eli Zaretskii
0 siblings, 2 replies; 49+ messages in thread
From: Yao Qi @ 2012-02-17 13:34 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
On 02/17/2012 07:37 PM, Eli Zaretskii wrote:
>> > Gradually,
>> > +they are used more widely, such as in remote stub.
> I don't understand what you wanted to say in this sentence. Does it
> really add anything important?
>
What I want to describe here is that "Agent Expression" is not only used
in agent, but also used somewhere else, such as target-side breakpoint
conditions in GDBserver. Just want to avoid the confusion that Agent
Expression is used in agent only.
Eli, thanks for your review. I'll fix other stuff you pointed out.
--
Yao (é½å°§)
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 4/9] agent doc
2012-02-17 13:34 ` Yao Qi
@ 2012-02-17 16:10 ` Pedro Alves
2012-02-18 17:11 ` Eli Zaretskii
1 sibling, 0 replies; 49+ messages in thread
From: Pedro Alves @ 2012-02-17 16:10 UTC (permalink / raw)
To: Yao Qi; +Cc: Eli Zaretskii, gdb-patches
On 02/17/2012 01:12 PM, Yao Qi wrote:
> On 02/17/2012 07:37 PM, Eli Zaretskii wrote:
>>>> Gradually,
>>>> +they are used more widely, such as in remote stub.
>> I don't understand what you wanted to say in this sentence. Does it
>> really add anything important?
>>
>
> What I want to describe here is that "Agent Expression" is not only used
> in agent, but also used somewhere else, such as target-side breakpoint
> conditions in GDBserver. Just want to avoid the confusion that Agent
> Expression is used in agent only.
IMO, the main confusion is that you're calling the new thing "agent", which
is a very generic term. We had been using in-process (debugging)
agent (IPA) so far for the thing that is loaded in the inferior,
which is I think is a bit more to the point. And I think users may well
get confused by reading the bits in the docs that already talk about
the in-process agent, and then this new section, which talks about
an agent, but without connecting the dots.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 4/9] agent doc
2012-02-17 13:34 ` Yao Qi
2012-02-17 16:10 ` Pedro Alves
@ 2012-02-18 17:11 ` Eli Zaretskii
2012-02-20 3:56 ` Yao Qi
1 sibling, 1 reply; 49+ messages in thread
From: Eli Zaretskii @ 2012-02-18 17:11 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
> Date: Fri, 17 Feb 2012 21:12:49 +0800
> From: Yao Qi <yao@codesourcery.com>
> CC: <gdb-patches@sourceware.org>
>
> On 02/17/2012 07:37 PM, Eli Zaretskii wrote:
> >> > Gradually,
> >> > +they are used more widely, such as in remote stub.
> > I don't understand what you wanted to say in this sentence. Does it
> > really add anything important?
> >
>
> What I want to describe here is that "Agent Expression" is not only used
> in agent, but also used somewhere else, such as target-side breakpoint
> conditions in GDBserver. Just want to avoid the confusion that Agent
> Expression is used in agent only.
Then I suggest the following modified wording of that paragraph:
Although called @dfn{agent expression}, because they originally
referred to the target-side debugging agent (@pxref{Agent}), these
expressions can be used in conjunction with many unrelated
@value{GDBN} features, such as expressions used in tracepoints for
data collection, expressions used in breakpoint condition evaluation,
etc. Note that the expressions may also denote registers and objects
in memory---structures or arrays, for example---whose values
@value{GDBN} should record.
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 4/9] agent doc
2012-02-18 17:11 ` Eli Zaretskii
@ 2012-02-20 3:56 ` Yao Qi
2012-02-20 6:22 ` Eli Zaretskii
2012-02-21 18:18 ` Pedro Alves
0 siblings, 2 replies; 49+ messages in thread
From: Yao Qi @ 2012-02-20 3:56 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches, Pedro Alves
[-- Attachment #1: Type: text/plain, Size: 870 bytes --]
On 02/18/2012 08:40 PM, Eli Zaretskii wrote:
> Then I suggest the following modified wording of that paragraph:
>
> Although called @dfn{agent expression}, because they originally
> referred to the target-side debugging agent (@pxref{Agent}), these
> expressions can be used in conjunction with many unrelated
> @value{GDBN} features, such as expressions used in tracepoints for
> data collection, expressions used in breakpoint condition evaluation,
> etc. Note that the expressions may also denote registers and objects
> in memory---structures or arrays, for example---whose values
> @value{GDBN} should record.
I replaced 'target-side debugging agent (@pxref{Agent})' with
'in-process agent (@pxref{In-Process Agent})', to explictly name `agent'
as `In-Process Agent', to avoid of confusion. Here is the new patch on doc.
--
Yao (é½å°§)
[-- Attachment #2: 0004-agent-doc.patch --]
[-- Type: text/x-patch, Size: 6866 bytes --]
gdb/doc/
2012-02-20 Yao Qi <yao@codesourcery.com>
* agentexpr.texi (Agent Expressions): Update some parts for agent expression
can not only be used in agent, but also in remote stubs.
Move some contents to ...
* gdb.texinfo (In-Process Agent): ... to here. New node.
Document new commands.
---
gdb/doc/agentexpr.texi | 37 ++++++++++-------------------
gdb/doc/gdb.texinfo | 58 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+), 24 deletions(-)
diff --git a/gdb/doc/agentexpr.texi b/gdb/doc/agentexpr.texi
index d0f6f15..65e4423 100644
--- a/gdb/doc/agentexpr.texi
+++ b/gdb/doc/agentexpr.texi
@@ -13,32 +13,21 @@
@node Agent Expressions
@appendix The GDB Agent Expression Mechanism
-
-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.
-
-Using GDB's @code{trace} and @code{collect} commands, the user can
-specify locations in the program, and arbitrary expressions to evaluate
-when those locations are reached. Later, using the @code{tfind}
-command, she can examine the values those expressions had when the
-program hit the trace points. The expressions may also denote objects
-in memory --- structures or arrays, for example --- whose values GDB
-should record; while visiting a particular tracepoint, the user may
-inspect those objects as if they were in memory at that moment.
-However, because GDB records these values without interacting with the
-user, it can do so quickly and unobtrusively, hopefully not disturbing
-the program's behavior.
-
-When GDB is debugging a remote target, the GDB @dfn{agent} code running
+Although called @dfn{agent expression}, because they originally
+referred to the in-process agent (@pxref{In-Process Agent}), these
+expressions can be used in conjunction with many unrelated @value{GDBN}
+features, such as expressions used in tracepoints for data collection,
+expressions used in breakpoint condition evaluation, etc. Note that the
+expressions may also denote registers and objects in memory---structures
+or arrays, for example---whose values @value{GDBN} should record.
+
+When @value{GDBN} is debugging, the @value{GDBN} agent code running
on the target computes the values of the expressions itself. To avoid
-having a full symbolic expression evaluator on the agent, GDB translates
-expressions in the source language into a simpler bytecode language, and
-then sends the bytecode to the agent; the agent then executes the
-bytecode, and records the values for GDB to retrieve later.
+having a full symbolic expression evaluator on the agent or remote stub,
+@value{GDBN} translates expressions in the source language into a simpler
+bytecode language, and then sends the bytecode to the agent; the agent
+then executes the bytecode, and records the values for @value{GDBN} to
+retrieve later.
The bytecode language is simple; there are forty-odd opcodes, the bulk
of which are the usual vocabulary of C operands (addition, subtraction,
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 34bf77e..cd2482f 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}
@@ -32191,6 +32192,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. @dfn{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 agent will still stop
+or slow down the program.
+
+The 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 agent is used as an aid for debugging
+with the following commands:
+
+@table @code
+@kindex set agent on
+@item set agent on
+Causes the agent to perform some operations on behalf of the
+debugger. Just which operations requested by the user will be done
+by the agent depends on the agent's capabilities. For example, if
+you request to evaluate breakpoint conditions in the agent, and the
+agent has such capability as well, then breakpoint conditions will be
+evaluated in the agent.
+
+@kindex set agent off
+@item set agent off
+Disables execution of debugging operations by the 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 agent.
+@end table
+
@node GDB Bugs
@chapter Reporting Bugs in @value{GDBN}
@cindex bugs in @value{GDBN}
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 4/9] agent doc
2012-02-20 3:56 ` Yao Qi
@ 2012-02-20 6:22 ` Eli Zaretskii
2012-02-21 18:18 ` Pedro Alves
1 sibling, 0 replies; 49+ messages in thread
From: Eli Zaretskii @ 2012-02-20 6:22 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches, palves
> Date: Mon, 20 Feb 2012 10:40:49 +0800
> From: Yao Qi <yao@codesourcery.com>
> CC: <gdb-patches@sourceware.org>, Pedro Alves <palves@redhat.com>
>
> On 02/18/2012 08:40 PM, Eli Zaretskii wrote:
> > Then I suggest the following modified wording of that paragraph:
> >
> > Although called @dfn{agent expression}, because they originally
> > referred to the target-side debugging agent (@pxref{Agent}), these
> > expressions can be used in conjunction with many unrelated
> > @value{GDBN} features, such as expressions used in tracepoints for
> > data collection, expressions used in breakpoint condition evaluation,
> > etc. Note that the expressions may also denote registers and objects
> > in memory---structures or arrays, for example---whose values
> > @value{GDBN} should record.
>
> I replaced 'target-side debugging agent (@pxref{Agent})' with
> 'in-process agent (@pxref{In-Process Agent})', to explictly name `agent'
> as `In-Process Agent', to avoid of confusion. Here is the new patch on doc.
OK.
Thanks.
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 4/9] agent doc
2012-02-20 3:56 ` Yao Qi
2012-02-20 6:22 ` Eli Zaretskii
@ 2012-02-21 18:18 ` Pedro Alves
2012-02-22 1:56 ` Yao Qi
1 sibling, 1 reply; 49+ messages in thread
From: Pedro Alves @ 2012-02-21 18:18 UTC (permalink / raw)
To: Yao Qi; +Cc: Eli Zaretskii, gdb-patches
On 02/20/2012 02:40 AM, Yao Qi wrote:
> -When GDB is debugging a remote target, the GDB @dfn{agent} code running
> +Although called @dfn{agent expression}, because they originally
> +referred to the in-process agent (@pxref{In-Process Agent}), these
That's incorrect. Agent expressions existed long before the in-process
agent was invented. See the confusion about calling the new IPA thing
just "agent"?
From agentexpr.texi:
When GDB is debugging a remote target, the GDB @dfn{agent} code running
on the target computes the values of the expressions itself. To avoid
having a full symbolic expression evaluator on the agent, GDB translates
expressions in the source language into a simpler bytecode language, and
then sends the bytecode to the agent; the agent then executes the
bytecode, and records the values for GDB to retrieve later.
(...) The interpreter is
small, and strict limits on the memory and time required to evaluate an
expression are easy to determine, making it suitable for use by the
debugging agent in real-time applications.
So nothing mentioned here about in-process or not. This applies all the
same to the agent expression mechinary in GDBserver (tracepoints, etc.).
That's an agent as well. "agent" is a very loose term for roughly something
that runs on the remote target on GDB's behalf. Can we just drop that
explanation? If we name things clearly then that's unnecessary.
So I'd suggest also:
On 02/20/2012 02:40 AM, Yao Qi wrote:
> +reduce the number of operations performed by debugger. @dfn{Agent},
the 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 agent will still stop
> +or slow down the program.
> +
> +The agent can interpret and execute Agent Expressions
the in-process agent
> +@anchor{Control Agent}
And review things under this item even.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 4/9] agent doc
2012-02-21 18:18 ` Pedro Alves
@ 2012-02-22 1:56 ` Yao Qi
2012-02-22 20:41 ` Pedro Alves
0 siblings, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-22 1:56 UTC (permalink / raw)
To: Pedro Alves; +Cc: Eli Zaretskii, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1985 bytes --]
On 02/22/2012 01:26 AM, Pedro Alves wrote:
> On 02/20/2012 02:40 AM, Yao Qi wrote:
>
>> -When GDB is debugging a remote target, the GDB @dfn{agent} code running
>> +Although called @dfn{agent expression}, because they originally
>> +referred to the in-process agent (@pxref{In-Process Agent}), these
>
> That's incorrect. Agent expressions existed long before the in-process
> agent was invented. See the confusion about calling the new IPA thing
> just "agent"?
>
I didn't realize "agent" was introduced back in 1999, long before IPA
was created.
> From agentexpr.texi:
>
> When GDB is debugging a remote target, the GDB @dfn{agent} code running
> on the target computes the values of the expressions itself. To avoid
> having a full symbolic expression evaluator on the agent, GDB translates
> expressions in the source language into a simpler bytecode language, and
> then sends the bytecode to the agent; the agent then executes the
> bytecode, and records the values for GDB to retrieve later.
> (...) The interpreter is
> small, and strict limits on the memory and time required to evaluate an
> expression are easy to determine, making it suitable for use by the
> debugging agent in real-time applications.
>
> So nothing mentioned here about in-process or not. This applies all the
> same to the agent expression mechinary in GDBserver (tracepoints, etc.).
> That's an agent as well. "agent" is a very loose term for roughly something
> that runs on the remote target on GDB's behalf. Can we just drop that
> explanation? If we name things clearly then that's unnecessary.
>
I am inclined to leave this explanation there, as it is still useful to
generic term "agent".
> So I'd suggest also:
>
> On 02/20/2012 02:40 AM, Yao Qi wrote:
>> +reduce the number of operations performed by debugger. @dfn{Agent},
>
> the in-process agent
>
s/agent/in-process agent/ in my patch.
--
Yao (é½å°§)
[-- Attachment #2: 0004-agent-doc.patch --]
[-- Type: text/x-patch, Size: 6998 bytes --]
gdb/doc/
2012-02-22 Yao Qi <yao@codesourcery.com>
* agentexpr.texi (Agent Expressions): Update some parts for agent expression
can not only be used in in-process agent, but also in remote stubs.
Move some contents to ...
* gdb.texinfo (In-Process Agent): ... to here. New node.
Document new commands.
---
gdb/doc/agentexpr.texi | 37 ++++++++++-------------------
gdb/doc/gdb.texinfo | 58 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+), 24 deletions(-)
diff --git a/gdb/doc/agentexpr.texi b/gdb/doc/agentexpr.texi
index d0f6f15..65e4423 100644
--- a/gdb/doc/agentexpr.texi
+++ b/gdb/doc/agentexpr.texi
@@ -13,32 +13,21 @@
@node Agent Expressions
@appendix The GDB Agent Expression Mechanism
-
-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.
-
-Using GDB's @code{trace} and @code{collect} commands, the user can
-specify locations in the program, and arbitrary expressions to evaluate
-when those locations are reached. Later, using the @code{tfind}
-command, she can examine the values those expressions had when the
-program hit the trace points. The expressions may also denote objects
-in memory --- structures or arrays, for example --- whose values GDB
-should record; while visiting a particular tracepoint, the user may
-inspect those objects as if they were in memory at that moment.
-However, because GDB records these values without interacting with the
-user, it can do so quickly and unobtrusively, hopefully not disturbing
-the program's behavior.
-
-When GDB is debugging a remote target, the GDB @dfn{agent} code running
+Although called @dfn{agent expression}, because they originally
+referred to the in-process agent (@pxref{In-Process Agent}), these
+expressions can be used in conjunction with many unrelated @value{GDBN}
+features, such as expressions used in tracepoints for data collection,
+expressions used in breakpoint condition evaluation, etc. Note that the
+expressions may also denote registers and objects in memory---structures
+or arrays, for example---whose values @value{GDBN} should record.
+
+When @value{GDBN} is debugging, the @value{GDBN} agent code running
on the target computes the values of the expressions itself. To avoid
-having a full symbolic expression evaluator on the agent, GDB translates
-expressions in the source language into a simpler bytecode language, and
-then sends the bytecode to the agent; the agent then executes the
-bytecode, and records the values for GDB to retrieve later.
+having a full symbolic expression evaluator on the agent or remote stub,
+@value{GDBN} translates expressions in the source language into a simpler
+bytecode language, and then sends the bytecode to the agent; the agent
+then executes the bytecode, and records the values for @value{GDBN} to
+retrieve later.
The bytecode language is simple; there are forty-odd opcodes, the bulk
of which are the usual vocabulary of C operands (addition, subtraction,
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 34bf77e..0eb3811 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}
@@ -32191,6 +32192,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}
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 4/9] agent doc
2012-02-22 1:56 ` Yao Qi
@ 2012-02-22 20:41 ` Pedro Alves
2012-02-22 23:43 ` Eli Zaretskii
2012-02-27 13:23 ` Yao Qi
0 siblings, 2 replies; 49+ messages in thread
From: Pedro Alves @ 2012-02-22 20:41 UTC (permalink / raw)
To: Yao Qi; +Cc: Eli Zaretskii, gdb-patches
On 02/22/2012 01:28 AM, Yao Qi wrote:
> On 02/22/2012 01:26 AM, Pedro Alves wrote:
>> > From agentexpr.texi:
>> >
>> > When GDB is debugging a remote target, the GDB @dfn{agent} code running
>> > on the target computes the values of the expressions itself. To avoid
>> > having a full symbolic expression evaluator on the agent, GDB translates
>> > expressions in the source language into a simpler bytecode language, and
>> > then sends the bytecode to the agent; the agent then executes the
>> > bytecode, and records the values for GDB to retrieve later.
>> > (...) The interpreter is
>> > small, and strict limits on the memory and time required to evaluate an
>> > expression are easy to determine, making it suitable for use by the
>> > debugging agent in real-time applications.
>> >
>> > So nothing mentioned here about in-process or not. This applies all the
>> > same to the agent expression mechinary in GDBserver (tracepoints, etc.).
>> > That's an agent as well. "agent" is a very loose term for roughly something
>> > that runs on the remote target on GDB's behalf. Can we just drop that
>> > explanation? If we name things clearly then that's unnecessary.
>> >
> I am inclined to leave this explanation there, as it is still useful to
> generic term "agent".
Hmm, it still seems incorrect in the exact same way.
> -When GDB is debugging a remote target, the GDB @dfn{agent} code running
> +Although called @dfn{agent expression}, because they originally
> +referred to the in-process agent (@pxref{In-Process Agent}), these
Still false. Looks unchanged compared to the previous version?
> +When @value{GDBN} is debugging, the @value{GDBN} agent code running
> on the target computes the values of the expressions itself. To avoid
> -having a full symbolic expression evaluator on the agent, GDB translates
> -expressions in the source language into a simpler bytecode language, and
> -then sends the bytecode to the agent; the agent then executes the
> -bytecode, and records the values for GDB to retrieve later.
> +having a full symbolic expression evaluator on the agent or remote stub,
This is still confused on agent vs in-process agent. The remote stub is
an agent as well; it does things for gdb (e.g., GDBserver supports tracepoints).
Note the several references to "agent" on this whole paragraph. I suggest
really just leave this paragraph as it was.
> +@value{GDBN} translates expressions in the source language into a simpler
> +bytecode language, and then sends the bytecode to the agent; the agent
> +then executes the bytecode, and records the values for @value{GDBN} to
> +retrieve later.
We lost the intro about tracepoints, so this mention of recording values
for gdb to retrieve later is now awkward.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 4/9] agent doc
2012-02-22 20:41 ` Pedro Alves
@ 2012-02-22 23:43 ` Eli Zaretskii
2012-02-27 13:23 ` Yao Qi
1 sibling, 0 replies; 49+ messages in thread
From: Eli Zaretskii @ 2012-02-22 23:43 UTC (permalink / raw)
To: Pedro Alves; +Cc: yao, gdb-patches
> Date: Wed, 22 Feb 2012 20:25:06 +0000
> From: Pedro Alves <palves@redhat.com>
> CC: Eli Zaretskii <eliz@gnu.org>, gdb-patches@sourceware.org
>
> Hmm, it still seems incorrect in the exact same way.
>
> > -When GDB is debugging a remote target, the GDB @dfn{agent} code running
> > +Although called @dfn{agent expression}, because they originally
> > +referred to the in-process agent (@pxref{In-Process Agent}), these
>
> Still false. Looks unchanged compared to the previous version?
>
> > +When @value{GDBN} is debugging, the @value{GDBN} agent code running
> > on the target computes the values of the expressions itself. To avoid
> > -having a full symbolic expression evaluator on the agent, GDB translates
> > -expressions in the source language into a simpler bytecode language, and
> > -then sends the bytecode to the agent; the agent then executes the
> > -bytecode, and records the values for GDB to retrieve later.
> > +having a full symbolic expression evaluator on the agent or remote stub,
>
> This is still confused on agent vs in-process agent. The remote stub is
> an agent as well; it does things for gdb (e.g., GDBserver supports tracepoints).
> Note the several references to "agent" on this whole paragraph. I suggest
> really just leave this paragraph as it was.
>
> > +@value{GDBN} translates expressions in the source language into a simpler
> > +bytecode language, and then sends the bytecode to the agent; the agent
> > +then executes the bytecode, and records the values for @value{GDBN} to
> > +retrieve later.
>
> We lost the intro about tracepoints, so this mention of recording values
> for gdb to retrieve later is now awkward.
Pedro, how about if you write whatever you think we should say there,
in whatever shape it is easy for you, and I will then polish it if
necessary? (The "polish" suggestion is to avoid wasting too much of
your time on stylistic issues.)
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 4/9] agent doc
2012-02-22 20:41 ` Pedro Alves
2012-02-22 23:43 ` Eli Zaretskii
@ 2012-02-27 13:23 ` Yao Qi
1 sibling, 0 replies; 49+ messages in thread
From: Yao Qi @ 2012-02-27 13:23 UTC (permalink / raw)
To: Pedro Alves; +Cc: Eli Zaretskii, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2295 bytes --]
On 02/23/2012 04:25 AM, Pedro Alves wrote:
>> > I am inclined to leave this explanation there, as it is still useful to
>> > generic term "agent".
> Hmm, it still seems incorrect in the exact same way.
>
>> > -When GDB is debugging a remote target, the GDB @dfn{agent} code running
>> > +Although called @dfn{agent expression}, because they originally
>> > +referred to the in-process agent (@pxref{In-Process Agent}), these
> Still false. Looks unchanged compared to the previous version?
>
>> > +When @value{GDBN} is debugging, the @value{GDBN} agent code running
>> > on the target computes the values of the expressions itself. To avoid
>> > -having a full symbolic expression evaluator on the agent, GDB translates
>> > -expressions in the source language into a simpler bytecode language, and
>> > -then sends the bytecode to the agent; the agent then executes the
>> > -bytecode, and records the values for GDB to retrieve later.
>> > +having a full symbolic expression evaluator on the agent or remote stub,
> This is still confused on agent vs in-process agent. The remote stub is
> an agent as well; it does things for gdb (e.g., GDBserver supports tracepoints).
> Note the several references to "agent" on this whole paragraph. I suggest
> really just leave this paragraph as it was.
>
>> > +@value{GDBN} translates expressions in the source language into a simpler
>> > +bytecode language, and then sends the bytecode to the agent; the agent
>> > +then executes the bytecode, and records the values for @value{GDBN} to
>> > +retrieve later.
> We lost the intro about tracepoints, so this mention of recording values
> for gdb to retrieve later is now awkward.
Pedro,
It gets my hand dirty to try to distinguish "agent" vs. "in-process
agent" in appendix "Agent Expression", so I removed all the changes in
doc/agentexpr.texi, to leave it as it was.
Same as previous version, a node "In-Process Agent" is added, to
describe what is it, and how to control it. Mention that "in-process
agent can interpret and execute Agent Expressions" only to avoid the
confusion on "agent" vs. "in-process agent", hopefully.
If this version is still not what you want, or confusing to you, please
give me an outline of this part, I've ran out of my brainpower. :)
--
Yao (é½å°§)
[-- Attachment #2: 0004-agent-doc.patch --]
[-- Type: text/x-patch, Size: 3875 bytes --]
gdb/doc/
* gdb.texinfo (In-Process Agent): New node.
Document new commands.
---
gdb/doc/gdb.texinfo | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 34bf77e..0eb3811 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}
@@ -32191,6 +32192,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 in-process 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}
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH 7/9] move in_process_agent_loaded to agent_loaded_p.
2012-02-17 2:56 [patch v2] GDB/GDBserver talks with agents Yao Qi
` (3 preceding siblings ...)
2012-02-17 2:57 ` [PATCH 4/9] agent doc Yao Qi
@ 2012-02-17 2:57 ` Yao Qi
2012-02-23 22:11 ` Pedro Alves
2012-02-17 2:57 ` [PATCH 2/9] add target_ops fields use_agent and can_use_agent Yao Qi
` (5 subsequent siblings)
10 siblings, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-17 2:57 UTC (permalink / raw)
To: gdb-patches
This patch moves in_process_agent_loaded from gdbserver to gdb/common,
and renmame it to agent_loaded_p, then gdb can use it as well. This
is a refacotr patch, no function is changed.
gdb:
2012-02-14 Yao Qi <yao@codesourcery.com>
* common/agent.c (agent_loaded_p): New.
(agent_look_up_symbols): New global.
* common/agent.h: Declare agent_loaded_p.
gdb/gdbserver:
2012-02-14 Yao Qi <yao@codesourcery.com>
* Makefile.in (linux-low.o): Keep dependence on agent.h.
(linux-x86-low.o): Likewise.
* server.h: Remove in_process_agent_loaded.
* tracepoint.c (in_process_agent_loaded): Removed. Moved it
common/agent.c.
Update callers.
---
gdb/common/agent.c | 11 +++++++++++
gdb/common/agent.h | 2 ++
gdb/gdbserver/Makefile.in | 4 ++--
gdb/gdbserver/linux-low.c | 7 ++++---
gdb/gdbserver/linux-x86-low.c | 3 ++-
gdb/gdbserver/server.h | 2 --
gdb/gdbserver/tracepoint.c | 37 +++++++++++++------------------------
7 files changed, 34 insertions(+), 32 deletions(-)
diff --git a/gdb/common/agent.c b/gdb/common/agent.c
index 074efea..d2f59db 100644
--- a/gdb/common/agent.c
+++ b/gdb/common/agent.c
@@ -71,6 +71,14 @@ static struct
static struct ipa_sym_addresses ipa_sym_addrs;
+static int all_agent_symbols_looked_up = 0;
+
+int
+agent_loaded_p (void)
+{
+ return all_agent_symbols_looked_up;
+}
+
/* Look up all symbols needed by agent. Return 0 if all the symbols are
found, return non-zero otherwise. */
@@ -79,6 +87,8 @@ agent_look_up_symbols (void)
{
int i;
+ all_agent_symbols_looked_up = 0;
+
for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
{
CORE_ADDR *addrp =
@@ -100,6 +110,7 @@ agent_look_up_symbols (void)
}
}
+ all_agent_symbols_looked_up = 1;
return 0;
}
diff --git a/gdb/common/agent.h b/gdb/common/agent.h
index a1ac9b2..b89d111 100644
--- a/gdb/common/agent.h
+++ b/gdb/common/agent.h
@@ -33,6 +33,8 @@ int agent_look_up_symbols (void);
thread. */
#define IPA_CMD_BUF_SIZE 1024
+int agent_loaded_p (void);
+
extern int debug_agent;
extern int use_agent;
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index e840db2..b7f1454 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -451,7 +451,7 @@ i386-low.o: i386-low.c $(i386_low_h) $(server_h) $(target_h)
i387-fp.o: i387-fp.c $(server_h)
linux-low.o: linux-low.c $(linux_low_h) $(linux_ptrace_h) $(linux_procfs_h) \
- $(server_h) $(linux_osdata_h)
+ $(server_h) $(linux_osdata_h) $(agent_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< @USE_THREAD_DB@
linux-arm-low.o: linux-arm-low.c $(linux_low_h) $(server_h) \
@@ -468,7 +468,7 @@ linux-s390-low.o: linux-s390-low.c $(linux_low_h) $(server_h)
linux-sh-low.o: linux-sh-low.c $(linux_low_h) $(server_h)
linux-tic6x-low.o: linux-tic6x-low.c $(linux_low_h) $(server_h)
linux-x86-low.o: linux-x86-low.c $(linux_low_h) $(server_h) \
- $(gdb_proc_service_h) $(i386_low_h)
+ $(gdb_proc_service_h) $(i386_low_h) $(agent_h)
linux-xtensa-low.o: linux-xtensa-low.c xtensa-xtregs.c $(linux_low_h) $(server_h)
lynx-low.o: lynx-low.c $(server_h) $(target_h) $(lynx_low_h)
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index c9b8a3b..d9f4b12 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -19,6 +19,7 @@
#include "server.h"
#include "linux-low.h"
#include "linux-osdata.h"
+#include "agent.h"
#include <sys/wait.h>
#include <stdio.h>
@@ -1320,7 +1321,7 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
if ((wstat == NULL
|| (WIFSTOPPED (*wstat) && WSTOPSIG (*wstat) != SIGTRAP))
&& supports_fast_tracepoints ()
- && in_process_agent_loaded ())
+ && agent_loaded_p ())
{
struct fast_tpoint_collect_status status;
int r;
@@ -2251,7 +2252,7 @@ retry:
if (WIFSTOPPED (w)
&& WSTOPSIG (w) != SIGTRAP
&& supports_fast_tracepoints ()
- && in_process_agent_loaded ())
+ && agent_loaded_p ())
{
if (debug_threads)
fprintf (stderr,
@@ -2795,7 +2796,7 @@ stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data)
/* Allow debugging the jump pad, gdb_collect, etc.. */
return (supports_fast_tracepoints ()
- && in_process_agent_loaded ()
+ && agent_loaded_p ()
&& (gdb_breakpoint_here (lwp->stop_pc)
|| lwp->stopped_by_watchpoint
|| thread->last_resume_kind == resume_step)
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 365cd52..a662780 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -28,6 +28,7 @@
#include "elf/common.h"
#include "gdb_proc_service.h"
+#include "agent.h"
/* Defined in auto-generated file i386-linux.c. */
void init_registers_i386_linux (void);
@@ -1586,7 +1587,7 @@ x86_get_min_fast_tracepoint_insn_len (void)
return 5;
#endif
- if (in_process_agent_loaded ())
+ if (agent_loaded_p ())
{
char errbuf[IPA_BUFSIZ];
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 5c798c8..390f629 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -436,8 +436,6 @@ char *pfildes (gdb_fildes_t fd);
agent back to GDBserver. */
#define IPA_BUFSIZ 100
-int in_process_agent_loaded (void);
-
void initialize_tracepoint (void);
extern int tracing;
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 0e1f9ed..0004ff2 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -228,14 +228,6 @@ static struct
static struct ipa_sym_addresses ipa_sym_addrs;
-int all_tracepoint_symbols_looked_up;
-
-int
-in_process_agent_loaded (void)
-{
- return all_tracepoint_symbols_looked_up;
-}
-
static int read_inferior_integer (CORE_ADDR symaddr, int *val);
/* Returns true if both the in-process agent library and the static
@@ -247,7 +239,7 @@ in_process_agent_supports_ust (void)
{
int loaded = 0;
- if (!in_process_agent_loaded ())
+ if (!agent_loaded_p ())
{
warning ("In-process agent not loaded");
return 0;
@@ -294,7 +286,7 @@ write_e_ust_not_loaded (char *buffer)
static int
maybe_write_ipa_not_loaded (char *buffer)
{
- if (!in_process_agent_loaded ())
+ if (!agent_loaded_p ())
{
write_e_ipa_not_loaded (buffer);
return 1;
@@ -309,7 +301,7 @@ maybe_write_ipa_not_loaded (char *buffer)
static int
maybe_write_ipa_ust_not_loaded (char *buffer)
{
- if (!in_process_agent_loaded ())
+ if (!agent_loaded_p ())
{
write_e_ipa_not_loaded (buffer);
return 1;
@@ -333,7 +325,7 @@ tracepoint_look_up_symbols (void)
{
int i;
- if (all_tracepoint_symbols_looked_up)
+ if (agent_loaded_p ())
return;
for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
@@ -349,10 +341,7 @@ tracepoint_look_up_symbols (void)
}
}
- if (agent_look_up_symbols () != 0)
- return;
-
- all_tracepoint_symbols_looked_up = 1;
+ agent_look_up_symbols ();
}
#endif
@@ -2965,7 +2954,7 @@ install_tracepoint (struct tracepoint *tpoint, char *own_buf)
{
struct tracepoint *tp;
- if (!in_process_agent_loaded ())
+ if (!agent_loaded_p ())
{
trace_debug ("Requested a %s tracepoint, but fast "
"tracepoints aren't supported.",
@@ -3041,7 +3030,7 @@ cmd_qtstart (char *packet)
pause_all (1);
/* Sync the fast tracepoints list in the inferior ftlib. */
- if (in_process_agent_loaded ())
+ if (agent_loaded_p ())
{
download_tracepoints ();
download_trace_state_variables ();
@@ -3142,7 +3131,7 @@ cmd_qtstart (char *packet)
/* Tracing is now active, hits will now start being logged. */
tracing = 1;
- if (in_process_agent_loaded ())
+ if (agent_loaded_p ())
{
if (write_inferior_integer (ipa_sym_addrs.addr_tracing, 1))
fatal ("Error setting tracing variable in lib");
@@ -3201,7 +3190,7 @@ stop_tracing (void)
/* Stop logging. Tracepoints can still be hit, but they will not be
recorded. */
tracing = 0;
- if (in_process_agent_loaded ())
+ if (agent_loaded_p ())
{
if (write_inferior_integer (ipa_sym_addrs.addr_tracing, 0))
fatal ("Error clearing tracing variable in lib");
@@ -3249,7 +3238,7 @@ stop_tracing (void)
/* Clear out the tracepoints. */
clear_installed_tracepoints ();
- if (in_process_agent_loaded ())
+ if (agent_loaded_p ())
{
/* Pull in fast tracepoint trace frames from the inferior lib
buffer into our buffer, even if our buffer is already full,
@@ -3412,7 +3401,7 @@ cmd_qtstatus (char *packet)
trace_debug ("Returning trace status as %d, stop reason %s",
tracing, tracing_stop_reason);
- if (in_process_agent_loaded ())
+ if (agent_loaded_p ())
{
pause_all (1);
@@ -4086,7 +4075,7 @@ tracepoint_finished_step (struct thread_info *tinfo, CORE_ADDR stop_pc)
/* Pull in fast tracepoint trace frames from the inferior lib buffer into
our buffer. */
- if (in_process_agent_loaded ())
+ if (agent_loaded_p ())
upload_fast_traceframes ();
/* Check if we were indeed collecting data for one of more
@@ -4187,7 +4176,7 @@ handle_tracepoint_bkpts (struct thread_info *tinfo, CORE_ADDR stop_pc)
/* Pull in fast tracepoint trace frames from the inferior in-process
agent's buffer into our buffer. */
- if (!in_process_agent_loaded ())
+ if (!agent_loaded_p ())
return 0;
upload_fast_traceframes ();
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 7/9] move in_process_agent_loaded to agent_loaded_p.
2012-02-17 2:57 ` [PATCH 7/9] move in_process_agent_loaded to agent_loaded_p Yao Qi
@ 2012-02-23 22:11 ` Pedro Alves
2012-02-23 22:27 ` Pedro Alves
0 siblings, 1 reply; 49+ messages in thread
From: Pedro Alves @ 2012-02-23 22:11 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/17/2012 02:54 AM, Yao Qi wrote:
> This patch moves in_process_agent_loaded from gdbserver to gdb/common,
> and renmame it to agent_loaded_p, then gdb can use it as well. This
> is a refacotr patch, no function is changed.
>
> gdb:
>
> 2012-02-14 Yao Qi <yao@codesourcery.com>
>
> * common/agent.c (agent_loaded_p): New.
> (agent_look_up_symbols): New global.
> * common/agent.h: Declare agent_loaded_p.
>
> gdb/gdbserver:
>
> 2012-02-14 Yao Qi <yao@codesourcery.com>
>
> * Makefile.in (linux-low.o): Keep dependence on agent.h.
> (linux-x86-low.o): Likewise.
> * server.h: Remove in_process_agent_loaded.
> * tracepoint.c (in_process_agent_loaded): Removed. Moved it
> common/agent.c.
> Update callers.
> ---
> gdb/common/agent.c | 11 +++++++++++
> gdb/common/agent.h | 2 ++
> gdb/gdbserver/Makefile.in | 4 ++--
> gdb/gdbserver/linux-low.c | 7 ++++---
> gdb/gdbserver/linux-x86-low.c | 3 ++-
> gdb/gdbserver/server.h | 2 --
> gdb/gdbserver/tracepoint.c | 37 +++++++++++++------------------------
> 7 files changed, 34 insertions(+), 32 deletions(-)
>
> diff --git a/gdb/common/agent.c b/gdb/common/agent.c
> index 074efea..d2f59db 100644
> --- a/gdb/common/agent.c
> +++ b/gdb/common/agent.c
> @@ -71,6 +71,14 @@ static struct
>
> static struct ipa_sym_addresses ipa_sym_addrs;
>
> +static int all_agent_symbols_looked_up = 0;
> +
> +int
> +agent_loaded_p (void)
> +{
> + return all_agent_symbols_looked_up;
> +}
> +
> /* Look up all symbols needed by agent. Return 0 if all the symbols are
> found, return non-zero otherwise. */
>
> @@ -79,6 +87,8 @@ agent_look_up_symbols (void)
> {
> int i;
>
> + all_agent_symbols_looked_up = 0;
> +
> for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
> {
> CORE_ADDR *addrp =
> @@ -100,6 +110,7 @@ agent_look_up_symbols (void)
> }
> }
>
> + all_agent_symbols_looked_up = 1;
> return 0;
> }
>
> diff --git a/gdb/common/agent.h b/gdb/common/agent.h
> index a1ac9b2..b89d111 100644
> --- a/gdb/common/agent.h
> +++ b/gdb/common/agent.h
> @@ -33,6 +33,8 @@ int agent_look_up_symbols (void);
> thread. */
> #define IPA_CMD_BUF_SIZE 1024
>
> +int agent_loaded_p (void);
> +
> extern int debug_agent;
>
> extern int use_agent;
> diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
> index e840db2..b7f1454 100644
> --- a/gdb/gdbserver/Makefile.in
> +++ b/gdb/gdbserver/Makefile.in
> @@ -451,7 +451,7 @@ i386-low.o: i386-low.c $(i386_low_h) $(server_h) $(target_h)
> i387-fp.o: i387-fp.c $(server_h)
>
> linux-low.o: linux-low.c $(linux_low_h) $(linux_ptrace_h) $(linux_procfs_h) \
> - $(server_h) $(linux_osdata_h)
> + $(server_h) $(linux_osdata_h) $(agent_h)
> $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< @USE_THREAD_DB@
>
> linux-arm-low.o: linux-arm-low.c $(linux_low_h) $(server_h) \
> @@ -468,7 +468,7 @@ linux-s390-low.o: linux-s390-low.c $(linux_low_h) $(server_h)
> linux-sh-low.o: linux-sh-low.c $(linux_low_h) $(server_h)
> linux-tic6x-low.o: linux-tic6x-low.c $(linux_low_h) $(server_h)
> linux-x86-low.o: linux-x86-low.c $(linux_low_h) $(server_h) \
> - $(gdb_proc_service_h) $(i386_low_h)
> + $(gdb_proc_service_h) $(i386_low_h) $(agent_h)
> linux-xtensa-low.o: linux-xtensa-low.c xtensa-xtregs.c $(linux_low_h) $(server_h)
>
> lynx-low.o: lynx-low.c $(server_h) $(target_h) $(lynx_low_h)
> diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
> index c9b8a3b..d9f4b12 100644
> --- a/gdb/gdbserver/linux-low.c
> +++ b/gdb/gdbserver/linux-low.c
> @@ -19,6 +19,7 @@
> #include "server.h"
> #include "linux-low.h"
> #include "linux-osdata.h"
> +#include "agent.h"
>
> #include <sys/wait.h>
> #include <stdio.h>
> @@ -1320,7 +1321,7 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
> if ((wstat == NULL
> || (WIFSTOPPED (*wstat) && WSTOPSIG (*wstat) != SIGTRAP))
> && supports_fast_tracepoints ()
> - && in_process_agent_loaded ())
> + && agent_loaded_p ())
But the checks aren't equivalent. in_process_agent_loaded
checks for a bunch of libinproctrace.so symbols, agent_loaded_p
only checks for a few symbols in common/agent.c.
> {
> struct fast_tpoint_collect_status status;
> int r;
> @@ -2251,7 +2252,7 @@ retry:
> if (WIFSTOPPED (w)
> && WSTOPSIG (w) != SIGTRAP
> && supports_fast_tracepoints ()
> - && in_process_agent_loaded ())
> + && agent_loaded_p ())
> {
> if (debug_threads)
> fprintf (stderr,
> @@ -2795,7 +2796,7 @@ stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data)
>
> /* Allow debugging the jump pad, gdb_collect, etc.. */
> return (supports_fast_tracepoints ()
> - && in_process_agent_loaded ()
> + && agent_loaded_p ()
> && (gdb_breakpoint_here (lwp->stop_pc)
> || lwp->stopped_by_watchpoint
> || thread->last_resume_kind == resume_step)
> diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
> index 365cd52..a662780 100644
> --- a/gdb/gdbserver/linux-x86-low.c
> +++ b/gdb/gdbserver/linux-x86-low.c
> @@ -28,6 +28,7 @@
> #include "elf/common.h"
>
> #include "gdb_proc_service.h"
> +#include "agent.h"
>
> /* Defined in auto-generated file i386-linux.c. */
> void init_registers_i386_linux (void);
> @@ -1586,7 +1587,7 @@ x86_get_min_fast_tracepoint_insn_len (void)
> return 5;
> #endif
>
> - if (in_process_agent_loaded ())
> + if (agent_loaded_p ())
> {
> char errbuf[IPA_BUFSIZ];
>
> diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
> index 5c798c8..390f629 100644
> --- a/gdb/gdbserver/server.h
> +++ b/gdb/gdbserver/server.h
> @@ -436,8 +436,6 @@ char *pfildes (gdb_fildes_t fd);
> agent back to GDBserver. */
> #define IPA_BUFSIZ 100
>
> -int in_process_agent_loaded (void);
> -
> void initialize_tracepoint (void);
>
> extern int tracing;
> diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
> index 0e1f9ed..0004ff2 100644
> --- a/gdb/gdbserver/tracepoint.c
> +++ b/gdb/gdbserver/tracepoint.c
> @@ -228,14 +228,6 @@ static struct
>
> static struct ipa_sym_addresses ipa_sym_addrs;
>
> -int all_tracepoint_symbols_looked_up;
> -
> -int
> -in_process_agent_loaded (void)
> -{
> - return all_tracepoint_symbols_looked_up;
> -}
> -
> static int read_inferior_integer (CORE_ADDR symaddr, int *val);
>
> /* Returns true if both the in-process agent library and the static
> @@ -247,7 +239,7 @@ in_process_agent_supports_ust (void)
> {
> int loaded = 0;
>
> - if (!in_process_agent_loaded ())
> + if (!agent_loaded_p ())
> {
> warning ("In-process agent not loaded");
> return 0;
> @@ -294,7 +286,7 @@ write_e_ust_not_loaded (char *buffer)
> static int
> maybe_write_ipa_not_loaded (char *buffer)
> {
> - if (!in_process_agent_loaded ())
> + if (!agent_loaded_p ())
> {
> write_e_ipa_not_loaded (buffer);
> return 1;
> @@ -309,7 +301,7 @@ maybe_write_ipa_not_loaded (char *buffer)
> static int
> maybe_write_ipa_ust_not_loaded (char *buffer)
> {
> - if (!in_process_agent_loaded ())
> + if (!agent_loaded_p ())
> {
> write_e_ipa_not_loaded (buffer);
> return 1;
> @@ -333,7 +325,7 @@ tracepoint_look_up_symbols (void)
> {
> int i;
>
> - if (all_tracepoint_symbols_looked_up)
> + if (agent_loaded_p ())
> return;
>
> for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
> @@ -349,10 +341,7 @@ tracepoint_look_up_symbols (void)
> }
> }
>
> - if (agent_look_up_symbols () != 0)
> - return;
> -
> - all_tracepoint_symbols_looked_up = 1;
> + agent_look_up_symbols ();
> }
>
> #endif
> @@ -2965,7 +2954,7 @@ install_tracepoint (struct tracepoint *tpoint, char *own_buf)
> {
> struct tracepoint *tp;
>
> - if (!in_process_agent_loaded ())
> + if (!agent_loaded_p ())
> {
> trace_debug ("Requested a %s tracepoint, but fast "
> "tracepoints aren't supported.",
> @@ -3041,7 +3030,7 @@ cmd_qtstart (char *packet)
> pause_all (1);
>
> /* Sync the fast tracepoints list in the inferior ftlib. */
> - if (in_process_agent_loaded ())
> + if (agent_loaded_p ())
> {
> download_tracepoints ();
> download_trace_state_variables ();
> @@ -3142,7 +3131,7 @@ cmd_qtstart (char *packet)
> /* Tracing is now active, hits will now start being logged. */
> tracing = 1;
>
> - if (in_process_agent_loaded ())
> + if (agent_loaded_p ())
> {
> if (write_inferior_integer (ipa_sym_addrs.addr_tracing, 1))
> fatal ("Error setting tracing variable in lib");
> @@ -3201,7 +3190,7 @@ stop_tracing (void)
> /* Stop logging. Tracepoints can still be hit, but they will not be
> recorded. */
> tracing = 0;
> - if (in_process_agent_loaded ())
> + if (agent_loaded_p ())
> {
> if (write_inferior_integer (ipa_sym_addrs.addr_tracing, 0))
> fatal ("Error clearing tracing variable in lib");
> @@ -3249,7 +3238,7 @@ stop_tracing (void)
> /* Clear out the tracepoints. */
> clear_installed_tracepoints ();
>
> - if (in_process_agent_loaded ())
> + if (agent_loaded_p ())
> {
> /* Pull in fast tracepoint trace frames from the inferior lib
> buffer into our buffer, even if our buffer is already full,
> @@ -3412,7 +3401,7 @@ cmd_qtstatus (char *packet)
> trace_debug ("Returning trace status as %d, stop reason %s",
> tracing, tracing_stop_reason);
>
> - if (in_process_agent_loaded ())
> + if (agent_loaded_p ())
> {
> pause_all (1);
>
> @@ -4086,7 +4075,7 @@ tracepoint_finished_step (struct thread_info *tinfo, CORE_ADDR stop_pc)
>
> /* Pull in fast tracepoint trace frames from the inferior lib buffer into
> our buffer. */
> - if (in_process_agent_loaded ())
> + if (agent_loaded_p ())
> upload_fast_traceframes ();
>
> /* Check if we were indeed collecting data for one of more
> @@ -4187,7 +4176,7 @@ handle_tracepoint_bkpts (struct thread_info *tinfo, CORE_ADDR stop_pc)
> /* Pull in fast tracepoint trace frames from the inferior in-process
> agent's buffer into our buffer. */
>
> - if (!in_process_agent_loaded ())
> + if (!agent_loaded_p ())
> return 0;
>
> upload_fast_traceframes ();
Okay, though I'd've preferred if we weren't dropping the in-process qualifier
everywhere... Also, "_p" as suffix means "predicate". It's not really
necessary if the symbol's name is already clearly a predicate.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 7/9] move in_process_agent_loaded to agent_loaded_p.
2012-02-23 22:11 ` Pedro Alves
@ 2012-02-23 22:27 ` Pedro Alves
0 siblings, 0 replies; 49+ messages in thread
From: Pedro Alves @ 2012-02-23 22:27 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/23/2012 10:06 PM, Pedro Alves wrote:
> But the checks aren't equivalent. in_process_agent_loaded
> checks for a bunch of libinproctrace.so symbols, agent_loaded_p
> only checks for a few symbols in common/agent.c.
Sorry, stratch this paragraph. I figured it out eventually, and forgot
to come back and remove this.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH 2/9] add target_ops fields use_agent and can_use_agent
2012-02-17 2:56 [patch v2] GDB/GDBserver talks with agents Yao Qi
` (4 preceding siblings ...)
2012-02-17 2:57 ` [PATCH 7/9] move in_process_agent_loaded to agent_loaded_p Yao Qi
@ 2012-02-17 2:57 ` Yao Qi
2012-02-17 11:40 ` Eli Zaretskii
2012-02-23 21:21 ` Pedro Alves
2012-02-17 2:57 ` [PATCH 8/9] impl of use_agent and can_use_agent in linux-nat Yao Qi
` (4 subsequent siblings)
10 siblings, 2 replies; 49+ messages in thread
From: Yao Qi @ 2012-02-17 2:57 UTC (permalink / raw)
To: gdb-patches
This patch allows GDB to talk with GDBserver with agent running along
with inferior.
2012-02-15 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): Call
target_can_use_agent.
gdb/gdbserver:
2012-02-15 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
gdb/doc:
2012-02-15 Yao Qi <yao@codesourcery.com>
* gdb.texinfo (General Query Packets): Add packet `QAgent'.
---
gdb/common/agent.c | 3 +++
gdb/common/agent.h | 1 +
gdb/doc/gdb.texinfo | 13 +++++++++++++
gdb/gdbserver/Makefile.in | 2 +-
gdb/gdbserver/linux-low.c | 7 +++++++
gdb/gdbserver/server.c | 28 ++++++++++++++++++++++++++++
gdb/gdbserver/target.h | 7 +++++++
gdb/remote.c | 36 ++++++++++++++++++++++++++++++++++++
gdb/target.c | 8 ++++++++
gdb/target.h | 13 +++++++++++++
gdb/tracepoint.c | 12 ++++++++++++
11 files changed, 129 insertions(+), 1 deletions(-)
diff --git a/gdb/common/agent.c b/gdb/common/agent.c
index 657bba6..5a9ac16 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/gdb.texinfo b/gdb/doc/gdb.texinfo
index 02beed7..34bf77e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -34512,6 +34512,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
@@ -35091,6 +35096,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{-}
@@ -35224,6 +35234,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/Makefile.in b/gdb/gdbserver/Makefile.in
index 17fd043..e840db2 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -395,7 +395,7 @@ mem-break.o: mem-break.c $(server_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 ab34d84..c9b8a3b 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -4716,6 +4716,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)
@@ -5438,6 +5444,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 c1788a9..28aef72 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;
@@ -1621,6 +1646,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
strcat (own_buf, ";tracenz+");
}
+ 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 3187ac0..2977e31 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;
@@ -1272,6 +1273,7 @@ enum {
PACKET_QAllow,
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
+ PACKET_QAgent,
PACKET_MAX
};
@@ -3832,6 +3834,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 },
};
@@ -10669,6 +10672,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)
{
@@ -10778,6 +10809,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
@@ -11286,6 +11319,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 ad304bc..a7c11c3 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);
/* Do not inherit to_memory_map. */
/* Do not inherit to_flash_erase. */
@@ -925,6 +927,12 @@ update_current_target (void)
de_fault (to_traceframe_info,
(struct traceframe_info * (*) (void))
tcomplain);
+ 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 d4605ae..3bc9428 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -832,6 +832,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?
*/
@@ -1663,6 +1670,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 37e1f52..c56a02c 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -52,6 +52,7 @@
#include "memrange.h"
#include "exceptions.h"
#include "cli/cli-utils.h"
+#include "agent.h"
/* readline include files */
#include "readline/readline.h"
@@ -4882,6 +4883,17 @@ info_static_tracepoint_markers_command (char *arg, int from_tty)
struct ui_out *uiout = current_uiout;
int i;
+ if (target_can_use_agent () == 0)
+ {
+ warning (_("Can't list markers when agent doesn't work"));
+ return;
+ }
+ if (use_agent == 0)
+ {
+ warning (_("Agent is off. Run `set agent on'."));
+ return;
+ }
+
old_chain
= make_cleanup_ui_out_table_begin_end (uiout, 5, -1,
"StaticTracepointMarkersTable");
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 2/9] add target_ops fields use_agent and can_use_agent
2012-02-17 2:57 ` [PATCH 2/9] add target_ops fields use_agent and can_use_agent Yao Qi
@ 2012-02-17 11:40 ` Eli Zaretskii
2012-02-23 21:21 ` Pedro Alves
1 sibling, 0 replies; 49+ messages in thread
From: Eli Zaretskii @ 2012-02-17 11:40 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
> From: Yao Qi <yao@codesourcery.com>
> Date: Fri, 17 Feb 2012 10:54:53 +0800
>
> 2012-02-15 Yao Qi <yao@codesourcery.com>
>
> * gdb.texinfo (General Query Packets): Add packet `QAgent'.
OK for this part, thanks.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 2/9] add target_ops fields use_agent and can_use_agent
2012-02-17 2:57 ` [PATCH 2/9] add target_ops fields use_agent and can_use_agent Yao Qi
2012-02-17 11:40 ` Eli Zaretskii
@ 2012-02-23 21:21 ` Pedro Alves
2012-02-24 13:01 ` Yao Qi
1 sibling, 1 reply; 49+ messages in thread
From: Pedro Alves @ 2012-02-23 21:21 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/17/2012 02:54 AM, Yao Qi wrote:
> This patch allows GDB to talk with GDBserver with agent running along
> with inferior.
>
> 2012-02-15 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): Call
> target_can_use_agent.
>
> gdb/gdbserver:
>
> 2012-02-15 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
>
> gdb/doc:
>
> 2012-02-15 Yao Qi <yao@codesourcery.com>
>
> * gdb.texinfo (General Query Packets): Add packet `QAgent'.
> ---
> gdb/common/agent.c | 3 +++
> gdb/common/agent.h | 1 +
> gdb/doc/gdb.texinfo | 13 +++++++++++++
> gdb/gdbserver/Makefile.in | 2 +-
> gdb/gdbserver/linux-low.c | 7 +++++++
> gdb/gdbserver/server.c | 28 ++++++++++++++++++++++++++++
> gdb/gdbserver/target.h | 7 +++++++
> gdb/remote.c | 36 ++++++++++++++++++++++++++++++++++++
> gdb/target.c | 8 ++++++++
> gdb/target.h | 13 +++++++++++++
> gdb/tracepoint.c | 12 ++++++++++++
> 11 files changed, 129 insertions(+), 1 deletions(-)
>
> diff --git a/gdb/common/agent.c b/gdb/common/agent.c
> index 657bba6..5a9ac16 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/gdb.texinfo b/gdb/doc/gdb.texinfo
> index 02beed7..34bf77e 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -34512,6 +34512,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
> @@ -35091,6 +35096,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{-}
> @@ -35224,6 +35234,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/Makefile.in b/gdb/gdbserver/Makefile.in
> index 17fd043..e840db2 100644
> --- a/gdb/gdbserver/Makefile.in
> +++ b/gdb/gdbserver/Makefile.in
> @@ -395,7 +395,7 @@ mem-break.o: mem-break.c $(server_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 ab34d84..c9b8a3b 100644
> --- a/gdb/gdbserver/linux-low.c
> +++ b/gdb/gdbserver/linux-low.c
> @@ -4716,6 +4716,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)
> @@ -5438,6 +5444,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 c1788a9..28aef72 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;
> @@ -1621,6 +1646,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
> strcat (own_buf, ";tracenz+");
> }
>
> + 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 3187ac0..2977e31 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;
> @@ -1272,6 +1273,7 @@ enum {
> PACKET_QAllow,
> PACKET_qXfer_fdpic,
> PACKET_QDisableRandomization,
> + PACKET_QAgent,
> PACKET_MAX
> };
>
> @@ -3832,6 +3834,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 },
> };
> @@ -10669,6 +10672,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)
> {
> @@ -10778,6 +10809,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
> @@ -11286,6 +11319,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 ad304bc..a7c11c3 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);
> /* Do not inherit to_memory_map. */
> /* Do not inherit to_flash_erase. */
> @@ -925,6 +927,12 @@ update_current_target (void)
> de_fault (to_traceframe_info,
> (struct traceframe_info * (*) (void))
> tcomplain);
> + 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 d4605ae..3bc9428 100644
> --- a/gdb/target.h
> +++ b/gdb/target.h
> @@ -832,6 +832,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?
> */
> @@ -1663,6 +1670,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 37e1f52..c56a02c 100644
> --- a/gdb/tracepoint.c
> +++ b/gdb/tracepoint.c
> @@ -52,6 +52,7 @@
> #include "memrange.h"
> #include "exceptions.h"
> #include "cli/cli-utils.h"
> +#include "agent.h"
>
> /* readline include files */
> #include "readline/readline.h"
> @@ -4882,6 +4883,17 @@ info_static_tracepoint_markers_command (char *arg, int from_tty)
> struct ui_out *uiout = current_uiout;
> int i;
>
> + if (target_can_use_agent () == 0)
Hmm, I don't think doing this change now is right. If you connect GDB to a GDBserver
that hasn't been patched, this will fail because that GDBserver doesn't report
the QAgent feature, so it is an incompatible change of the protocol to require QAgent
for static tracepoint listing.
The right thing to do seems to be to just go ahead and try the target method call,
as before. We could at a minimum check whether the "statictracepoints" qSupported
feature Was reported by the target, though that doesn't tell you whether the current
inferior has the IPA or UST loaded at all, only that the frontend stub understands
static tracepoints. What was the motivation for these checks here?
> + {
> + warning (_("Can't list markers when agent doesn't work"));
> + return;
> + }
> + if (use_agent == 0)
> + {
> + warning (_("Agent is off. Run `set agent on'."));
> + return;
> + }
> +
> old_chain
> = make_cleanup_ui_out_table_begin_end (uiout, 5, -1,
> "StaticTracepointMarkersTable");
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 2/9] add target_ops fields use_agent and can_use_agent
2012-02-23 21:21 ` Pedro Alves
@ 2012-02-24 13:01 ` Yao Qi
2012-02-24 13:05 ` Pedro Alves
0 siblings, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-24 13:01 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1259 bytes --]
On 02/24/2012 05:17 AM, Pedro Alves wrote:
>> > @@ -4882,6 +4883,17 @@ info_static_tracepoint_markers_command (char *arg, int from_tty)
>> > struct ui_out *uiout = current_uiout;
>> > int i;
>> >
>> > + if (target_can_use_agent () == 0)
> Hmm, I don't think doing this change now is right. If you connect GDB to a GDBserver
> that hasn't been patched, this will fail because that GDBserver doesn't report
> the QAgent feature, so it is an incompatible change of the protocol to require QAgent
> for static tracepoint listing.
> The right thing to do seems to be to just go ahead and try the target method call,
> as before. We could at a minimum check whether the "statictracepoints" qSupported
> feature Was reported by the target, though that doesn't tell you whether the current
> inferior has the IPA or UST loaded at all, only that the frontend stub understands
> static tracepoints. What was the motivation for these checks here?
>
The motivation is quite simple, `since we have some conditions, it is
better to check them first'. However, it breaks compatibility, as you
pointed out. In this version, I get rid of these checks, and only leave
a paragraph of comment on why we don't check these conditions there.
--
Yao (é½å°§)
[-- Attachment #2: 0002-add-target_ops-fields-use_agent-and-can_use_agent.patch --]
[-- Type: text/x-patch, Size: 12129 bytes --]
2012-02-17 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.
gdb/gdbserver:
2012-02-17 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
gdb/doc:
2012-02-17 Yao Qi <yao@codesourcery.com>
* gdb.texinfo (General Query Packets): Add packet `QAgent'.
---
gdb/common/agent.c | 3 +++
gdb/common/agent.h | 1 +
gdb/doc/gdb.texinfo | 13 +++++++++++++
gdb/gdbserver/Makefile.in | 2 +-
gdb/gdbserver/linux-low.c | 7 +++++++
gdb/gdbserver/server.c | 28 ++++++++++++++++++++++++++++
gdb/gdbserver/target.h | 7 +++++++
gdb/remote.c | 36 ++++++++++++++++++++++++++++++++++++
gdb/target.c | 8 ++++++++
gdb/target.h | 13 +++++++++++++
gdb/tracepoint.c | 6 ++++++
11 files changed, 123 insertions(+), 1 deletions(-)
diff --git a/gdb/common/agent.c b/gdb/common/agent.c
index 8f7dded..044024f 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 43e128c..53c6862 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/gdb.texinfo b/gdb/doc/gdb.texinfo
index 02beed7..34bf77e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -34512,6 +34512,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
@@ -35091,6 +35096,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{-}
@@ -35224,6 +35234,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/Makefile.in b/gdb/gdbserver/Makefile.in
index 17fd043..e840db2 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -395,7 +395,7 @@ mem-break.o: mem-break.c $(server_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 ab34d84..c9b8a3b 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -4716,6 +4716,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)
@@ -5438,6 +5444,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 c1788a9..28aef72 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;
@@ -1621,6 +1646,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
strcat (own_buf, ";tracenz+");
}
+ 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 3187ac0..2977e31 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;
@@ -1272,6 +1273,7 @@ enum {
PACKET_QAllow,
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
+ PACKET_QAgent,
PACKET_MAX
};
@@ -3832,6 +3834,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 },
};
@@ -10669,6 +10672,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)
{
@@ -10778,6 +10809,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
@@ -11286,6 +11319,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 ad304bc..a7c11c3 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);
/* Do not inherit to_memory_map. */
/* Do not inherit to_flash_erase. */
@@ -925,6 +927,12 @@ update_current_target (void)
de_fault (to_traceframe_info,
(struct traceframe_info * (*) (void))
tcomplain);
+ 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 d4605ae..3bc9428 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -832,6 +832,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?
*/
@@ -1663,6 +1670,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 37e1f52..194977b 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -4882,6 +4882,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");
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 2/9] add target_ops fields use_agent and can_use_agent
2012-02-24 13:01 ` Yao Qi
@ 2012-02-24 13:05 ` Pedro Alves
0 siblings, 0 replies; 49+ messages in thread
From: Pedro Alves @ 2012-02-24 13:05 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/24/2012 01:00 PM, Yao Qi wrote:
> 2012-02-17 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.
>
> gdb/gdbserver:
>
> 2012-02-17 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
This version is okay.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH 8/9] impl of use_agent and can_use_agent in linux-nat.
2012-02-17 2:56 [patch v2] GDB/GDBserver talks with agents Yao Qi
` (5 preceding siblings ...)
2012-02-17 2:57 ` [PATCH 2/9] add target_ops fields use_agent and can_use_agent Yao Qi
@ 2012-02-17 2:57 ` Yao Qi
2012-02-23 22:15 ` Pedro Alves
2012-02-17 2:57 ` [PATCH 6/9] agent capability of static tracepoint Yao Qi
` (3 subsequent siblings)
10 siblings, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-17 2:57 UTC (permalink / raw)
To: gdb-patches
This patch is to implement two target_ops hooks on linux-nat, and look up symbols
when a solib is added.
2012-01-13 Yao Qi <yao@codesourcery.com>
* linux-nat.c (linux_child_use_agent): New.
(linux_child_can_use_agent): New.
(linux_target_install_ops): Initialize fields `to_use_agent'
and `to_can_use_agent'.
* solib.c (solib_add): Call agent_look_up_symbol.
---
gdb/linux-nat.c | 22 ++++++++++++++++++++++
gdb/solib.c | 6 +++++-
2 files changed, 27 insertions(+), 1 deletions(-)
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 6aab087..3e81fd0 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -59,6 +59,7 @@
#include "solib.h"
#include "linux-osdata.h"
#include "linux-tdep.h"
+#include "agent.h"
#ifndef SPUFS_MAGIC
#define SPUFS_MAGIC 0x23c9b64e
@@ -4800,6 +4801,24 @@ linux_xfer_partial (struct target_ops *ops, enum target_object object,
offset, len);
}
+static int
+linux_child_use_agent (int use)
+{
+ if (agent_loaded_p ())
+ {
+ use_agent = use;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+static int
+linux_child_can_use_agent (void)
+{
+ return agent_loaded_p ();
+}
+
/* Create a prototype generic GNU/Linux target. The client can override
it with local methods. */
@@ -4821,6 +4840,9 @@ linux_target_install_ops (struct target_ops *t)
super_xfer_partial = t->to_xfer_partial;
t->to_xfer_partial = linux_xfer_partial;
+
+ t->to_use_agent = linux_child_use_agent;
+ t->to_can_use_agent = linux_child_can_use_agent;
}
struct target_ops *
diff --git a/gdb/solib.c b/gdb/solib.c
index 84b9019..4f04f39 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -46,6 +46,7 @@
#include "solib.h"
#include "interps.h"
#include "filesystem.h"
+#include "agent.h"
/* Architecture-specific operations. */
@@ -925,7 +926,10 @@ solib_add (char *pattern, int from_tty,
}
if (loaded_any_symbols)
- breakpoint_re_set ();
+ {
+ breakpoint_re_set ();
+ agent_look_up_symbols ();
+ }
if (from_tty && pattern && ! any_matches)
printf_unfiltered
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 8/9] impl of use_agent and can_use_agent in linux-nat.
2012-02-17 2:57 ` [PATCH 8/9] impl of use_agent and can_use_agent in linux-nat Yao Qi
@ 2012-02-23 22:15 ` Pedro Alves
2012-02-24 8:34 ` Yao Qi
2012-02-24 13:31 ` Yao Qi
0 siblings, 2 replies; 49+ messages in thread
From: Pedro Alves @ 2012-02-23 22:15 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/17/2012 02:54 AM, Yao Qi wrote:
> This patch is to implement two target_ops hooks on linux-nat, and look up symbols
> when a solib is added.
>
> 2012-01-13 Yao Qi <yao@codesourcery.com>
>
> * linux-nat.c (linux_child_use_agent): New.
> (linux_child_can_use_agent): New.
> (linux_target_install_ops): Initialize fields `to_use_agent'
> and `to_can_use_agent'.
> * solib.c (solib_add): Call agent_look_up_symbol.
> ---
> gdb/linux-nat.c | 22 ++++++++++++++++++++++
> gdb/solib.c | 6 +++++-
> 2 files changed, 27 insertions(+), 1 deletions(-)
>
> diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
> index 6aab087..3e81fd0 100644
> --- a/gdb/linux-nat.c
> +++ b/gdb/linux-nat.c
> @@ -59,6 +59,7 @@
> #include "solib.h"
> #include "linux-osdata.h"
> #include "linux-tdep.h"
> +#include "agent.h"
>
> #ifndef SPUFS_MAGIC
> #define SPUFS_MAGIC 0x23c9b64e
> @@ -4800,6 +4801,24 @@ linux_xfer_partial (struct target_ops *ops, enum target_object object,
> offset, len);
> }
>
> +static int
> +linux_child_use_agent (int use)
> +{
> + if (agent_loaded_p ())
> + {
> + use_agent = use;
> + return 1;
> + }
> + else
> + return 0;
> +}
> +
> +static int
> +linux_child_can_use_agent (void)
> +{
> + return agent_loaded_p ();
> +}
> +
> /* Create a prototype generic GNU/Linux target. The client can override
> it with local methods. */
>
> @@ -4821,6 +4840,9 @@ linux_target_install_ops (struct target_ops *t)
>
> super_xfer_partial = t->to_xfer_partial;
> t->to_xfer_partial = linux_xfer_partial;
> +
> + t->to_use_agent = linux_child_use_agent;
> + t->to_can_use_agent = linux_child_can_use_agent;
> }
Are these ever going to be different on other native targets? We could
put them in inf-child.c instead, to get them all covered at once.
>
> struct target_ops *
> diff --git a/gdb/solib.c b/gdb/solib.c
> index 84b9019..4f04f39 100644
> --- a/gdb/solib.c
> +++ b/gdb/solib.c
> @@ -46,6 +46,7 @@
> #include "solib.h"
> #include "interps.h"
> #include "filesystem.h"
> +#include "agent.h"
>
> /* Architecture-specific operations. */
>
> @@ -925,7 +926,10 @@ solib_add (char *pattern, int from_tty,
> }
>
> if (loaded_any_symbols)
> - breakpoint_re_set ();
> + {
> + breakpoint_re_set ();
> + agent_look_up_symbols ();
The right place to do this is in a new new_objfile observer.
> + }
>
> if (from_tty && pattern && ! any_matches)
> printf_unfiltered
> -- 1.7.0.4
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 8/9] impl of use_agent and can_use_agent in linux-nat.
2012-02-23 22:15 ` Pedro Alves
@ 2012-02-24 8:34 ` Yao Qi
2012-02-24 10:47 ` Pedro Alves
2012-02-24 13:31 ` Yao Qi
1 sibling, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-24 8:34 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
On 02/24/2012 06:11 AM, Pedro Alves wrote:
>> > @@ -925,7 +926,10 @@ solib_add (char *pattern, int from_tty,
>> > }
>> >
>> > if (loaded_any_symbols)
>> > - breakpoint_re_set ();
>> > + {
>> > + breakpoint_re_set ();
>> > + agent_look_up_symbols ();
> The right place to do this is in a new new_objfile observer.
>
Why not a new solib_loaded observer, which is more accurate, IMO.
--
Yao (é½å°§)
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 8/9] impl of use_agent and can_use_agent in linux-nat.
2012-02-24 8:34 ` Yao Qi
@ 2012-02-24 10:47 ` Pedro Alves
0 siblings, 0 replies; 49+ messages in thread
From: Pedro Alves @ 2012-02-24 10:47 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/24/2012 07:56 AM, Yao Qi wrote:
> On 02/24/2012 06:11 AM, Pedro Alves wrote:
>>>> @@ -925,7 +926,10 @@ solib_add (char *pattern, int from_tty,
>>>> }
>>>>
>>>> if (loaded_any_symbols)
>>>> - breakpoint_re_set ();
>>>> + {
>>>> + breakpoint_re_set ();
>>>> + agent_look_up_symbols ();
>> The right place to do this is in a new new_objfile observer.
>>
>
> Why not a new solib_loaded observer, which is more accurate, IMO.
Because what we care about is whether new symbols have been loaded. Even if
the IPA was already loaded. E.g., do you "set debug-file-directory" to
point at the IPAs symbols. Also, that handles the case of an agent built
statically into the executable, instead of as a separate DSO.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 8/9] impl of use_agent and can_use_agent in linux-nat.
2012-02-23 22:15 ` Pedro Alves
2012-02-24 8:34 ` Yao Qi
@ 2012-02-24 13:31 ` Yao Qi
2012-02-24 14:10 ` Pedro Alves
1 sibling, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-24 13:31 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 864 bytes --]
On 02/24/2012 06:11 AM, Pedro Alves wrote:
>> > +
>> > + t->to_use_agent = linux_child_use_agent;
>> > + t->to_can_use_agent = linux_child_can_use_agent;
>> > }
> Are these ever going to be different on other native targets? We could
> put them in inf-child.c instead, to get them all covered at once.
>
No, they are the same on other native targets. New target_ops hooks
functions are moved to inf-child.c.
>> > @@ -925,7 +926,10 @@ solib_add (char *pattern, int from_tty,
>> > }
>> >
>> > if (loaded_any_symbols)
>> > - breakpoint_re_set ();
>> > + {
>> > + breakpoint_re_set ();
>> > + agent_look_up_symbols ();
> The right place to do this is in a new new_objfile observer.
>
Done. Note that, in new_objfile observer, I pass OBJFILE to
agent_look_up_symbols as one parameter, so patch 1/9 will be updated.
--
Yao (é½å°§)
[-- Attachment #2: 0008-impl-of-use_agent-and-can_use_agent-in-inf-child.patch --]
[-- Type: text/x-patch, Size: 2074 bytes --]
2012-02-23 Yao Qi <yao@codesourcery.com>
* inf-child.c (inf_child_use_agent): New.
(inf_child_can_use_agent): New.
(inf_child_target): Initialize fields `to_use_agent'
and `to_can_use_agent'.
* agent.c (agent_new_objfile): New.
(_initialize_agent): Add agent_new_objfile to new_objfile
observer.
---
gdb/agent.c | 14 ++++++++++++++
gdb/inf-child.c | 20 ++++++++++++++++++++
2 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/gdb/agent.c b/gdb/agent.c
index c10ed89..bd537ea 100644
--- a/gdb/agent.c
+++ b/gdb/agent.c
@@ -51,9 +51,23 @@ set_can_use_agent (char *args, int from_tty, struct cmd_list_element *c)
can_use_agent = can_use_agent_off;
}
+#include "observer.h"
+#include "objfiles.h"
+
+static void
+agent_new_objfile (struct objfile *objfile)
+{
+ if (objfile == NULL || agent_loaded_p ())
+ return;
+
+ agent_look_up_symbols (objfile);
+}
+
void
_initialize_agent (void)
{
+ observer_attach_new_objfile (agent_new_objfile);
+
add_setshow_enum_cmd ("agent", class_run,
can_use_agent_enum,
&can_use_agent, _("\
diff --git a/gdb/inf-child.c b/gdb/inf-child.c
index 96c1157..5531102 100644
--- a/gdb/inf-child.c
+++ b/gdb/inf-child.c
@@ -29,6 +29,7 @@
#include "gdb_stat.h"
#include "inf-child.h"
#include "gdb/fileio.h"
+#include "agent.h"
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> /* for MAXPATHLEN */
@@ -332,6 +333,23 @@ inf_child_fileio_readlink (const char *filename, int *target_errno)
#endif
}
+static int
+inf_child_use_agent (int use)
+{
+ if (agent_loaded_p ())
+ {
+ use_agent = use;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+static int
+inf_child_can_use_agent (void)
+{
+ return agent_loaded_p ();
+}
struct target_ops *
inf_child_target (void)
@@ -371,5 +389,7 @@ inf_child_target (void)
t->to_fileio_unlink = inf_child_fileio_unlink;
t->to_fileio_readlink = inf_child_fileio_readlink;
t->to_magic = OPS_MAGIC;
+ t->to_use_agent = inf_child_use_agent;
+ t->to_can_use_agent = inf_child_can_use_agent;
return t;
}
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 8/9] impl of use_agent and can_use_agent in linux-nat.
2012-02-24 13:31 ` Yao Qi
@ 2012-02-24 14:10 ` Pedro Alves
2012-02-24 14:34 ` Yao Qi
0 siblings, 1 reply; 49+ messages in thread
From: Pedro Alves @ 2012-02-24 14:10 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/24/2012 01:18 PM, Yao Qi wrote:
> On 02/24/2012 06:11 AM, Pedro Alves wrote:
>>>> +
>>>> + t->to_use_agent = linux_child_use_agent;
>>>> + t->to_can_use_agent = linux_child_can_use_agent;
>>>> }
>> Are these ever going to be different on other native targets? We could
>> put them in inf-child.c instead, to get them all covered at once.
>>
>
> No, they are the same on other native targets. New target_ops hooks
> functions are moved to inf-child.c.
>
>>>> @@ -925,7 +926,10 @@ solib_add (char *pattern, int from_tty,
>>>> }
>>>>
>>>> if (loaded_any_symbols)
>>>> - breakpoint_re_set ();
>>>> + {
>>>> + breakpoint_re_set ();
>>>> + agent_look_up_symbols ();
>> The right place to do this is in a new new_objfile observer.
>>
>
> Done. Note that, in new_objfile observer, I pass OBJFILE to
> agent_look_up_symbols as one parameter, so patch 1/9 will be updated.
If the parameter didn't make sense in patch 1, but it makes sense in
patch 8, then do the necessary adjustments to the code in patch 8,
as if patch 1 was already applied. IOW, earlier patches
on a series should stand on their own as much as possible. Yet IOW,
if nothing uses the parameter in patch 1, then adding the parameter
to the function should be done patch 8, where uses are added.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 8/9] impl of use_agent and can_use_agent in linux-nat.
2012-02-24 14:10 ` Pedro Alves
@ 2012-02-24 14:34 ` Yao Qi
0 siblings, 0 replies; 49+ messages in thread
From: Yao Qi @ 2012-02-24 14:34 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
On 02/24/2012 09:56 PM, Pedro Alves wrote:
> If the parameter didn't make sense in patch 1, but it makes sense in
> patch 8, then do the necessary adjustments to the code in patch 8,
> as if patch 1 was already applied. IOW, earlier patches
> on a series should stand on their own as much as possible. Yet IOW,
> if nothing uses the parameter in patch 1, then adding the parameter
> to the function should be done patch 8, where uses are added.
Right. They are very good principles on working on a set patches!
Pedro, thank you.
--
Yao (é½å°§)
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH 6/9] agent capability of static tracepoint
2012-02-17 2:56 [patch v2] GDB/GDBserver talks with agents Yao Qi
` (6 preceding siblings ...)
2012-02-17 2:57 ` [PATCH 8/9] impl of use_agent and can_use_agent in linux-nat Yao Qi
@ 2012-02-17 2:57 ` Yao Qi
2012-02-23 22:06 ` Pedro Alves
2012-02-17 3:02 ` [PATCH 9/9] info static tracepoint in linux-nat Yao Qi
` (2 subsequent siblings)
10 siblings, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-17 2:57 UTC (permalink / raw)
To: gdb-patches
This patch is to teach both GDB and GDBserver to check agent's capability on
static tracepoint, before performing any operations.
gdb:
2012-02-15 Yao Qi <yao@codesourcery.com>
* tracepoint.c (info_static_tracepoint_markers_command): Call
agent_capability_check.
gdb/gdbserver:
2012-02-15 Yao Qi <yao@codesourcery.com>
* tracepoint.c (gdb_agent_capability): New global.
(in_process_agent_loaded_ust): Renamed to
`in_process_agent_supports_ust'.
Update callers.
(in_process_agent_supports_ust): Call agent_capability_check.
(clear_installed_tracepoints): Assert that agent supports
agent.
(install_tracepoint): Call in_process_agent_supports_ust.
---
gdb/gdbserver/tracepoint.c | 25 ++++++++++++++++++-------
gdb/tracepoint.c | 5 +++++
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 091af5a..0e1f9ed 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -239,10 +239,11 @@ in_process_agent_loaded (void)
static int read_inferior_integer (CORE_ADDR symaddr, int *val);
/* Returns true if both the in-process agent library and the static
- tracepoints libraries are loaded in the inferior. */
+ tracepoints libraries are loaded in the inferior, and agent has
+ capability on static tracepoints. */
static int
-in_process_agent_loaded_ust (void)
+in_process_agent_supports_ust (void)
{
int loaded = 0;
@@ -258,7 +259,10 @@ in_process_agent_loaded_ust (void)
return 0;
}
- return loaded;
+ if (loaded)
+ return agent_capability_check (AGENT_CAPA_STATIC_TRACE);
+ else
+ return 0;
}
static void
@@ -310,7 +314,7 @@ maybe_write_ipa_ust_not_loaded (char *buffer)
write_e_ipa_not_loaded (buffer);
return 1;
}
- else if (!in_process_agent_loaded_ust ())
+ else if (!in_process_agent_supports_ust ())
{
write_e_ust_not_loaded (buffer);
return 1;
@@ -2315,6 +2319,10 @@ clear_installed_tracepoints (void)
;
else
{
+ /* Static tracepoints have been inserted, so agent should have
+ been loaded and working. */
+ gdb_assert (in_process_agent_supports_ust ());
+
unprobe_marker_at (tpoint->address);
prev_stpoint = tpoint;
}
@@ -2965,7 +2973,8 @@ install_tracepoint (struct tracepoint *tpoint, char *own_buf)
write_e_ipa_not_loaded (own_buf);
return;
}
- if (tpoint->type == static_tracepoint && !in_process_agent_loaded_ust ())
+ if (tpoint->type == static_tracepoint
+ && !in_process_agent_supports_ust ())
{
trace_debug ("Requested a static tracepoint, but static "
"tracepoints are not supported.");
@@ -2990,8 +2999,8 @@ install_tracepoint (struct tracepoint *tpoint, char *own_buf)
}
else
{
- if (tp)
- tpoint->handle = (void *) -1;
+ if (!in_process_agent_supports_ust ())
+ warning ("Agent does not have capability for static tracepoint.");
else
{
if (probe_marker_at (tpoint->address, own_buf) == 0)
@@ -7994,6 +8003,8 @@ gdb_agent_helper_thread (void *arg)
#include <signal.h>
#include <pthread.h>
+IP_AGENT_EXPORT int gdb_agent_capability = AGENT_CAPA_STATIC_TRACE;
+
static void
gdb_agent_init (void)
{
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index c56a02c..c2801f9 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -4893,6 +4893,11 @@ info_static_tracepoint_markers_command (char *arg, int from_tty)
warning (_("Agent is off. Run `set agent on'."));
return;
}
+ if (!agent_capability_check (AGENT_CAPA_STATIC_TRACE))
+ {
+ warning (_("Agent is not capable of operating static tracepoints"));
+ return;
+ }
old_chain
= make_cleanup_ui_out_table_begin_end (uiout, 5, -1,
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 6/9] agent capability of static tracepoint
2012-02-17 2:57 ` [PATCH 6/9] agent capability of static tracepoint Yao Qi
@ 2012-02-23 22:06 ` Pedro Alves
2012-02-24 13:19 ` Yao Qi
0 siblings, 1 reply; 49+ messages in thread
From: Pedro Alves @ 2012-02-23 22:06 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/17/2012 02:54 AM, Yao Qi wrote:
> This patch is to teach both GDB and GDBserver to check agent's capability on
> static tracepoint, before performing any operations.
>
> gdb:
> 2012-02-15 Yao Qi <yao@codesourcery.com>
>
> * tracepoint.c (info_static_tracepoint_markers_command): Call
> agent_capability_check.
>
> gdb/gdbserver:
> 2012-02-15 Yao Qi <yao@codesourcery.com>
>
> * tracepoint.c (gdb_agent_capability): New global.
> (in_process_agent_loaded_ust): Renamed to
> `in_process_agent_supports_ust'.
> Update callers.
> (in_process_agent_supports_ust): Call agent_capability_check.
> (clear_installed_tracepoints): Assert that agent supports
> agent.
> (install_tracepoint): Call in_process_agent_supports_ust.
> ---
> gdb/gdbserver/tracepoint.c | 25 ++++++++++++++++++-------
> gdb/tracepoint.c | 5 +++++
> 2 files changed, 23 insertions(+), 7 deletions(-)
>
> diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
> index 091af5a..0e1f9ed 100644
> --- a/gdb/gdbserver/tracepoint.c
> +++ b/gdb/gdbserver/tracepoint.c
> @@ -239,10 +239,11 @@ in_process_agent_loaded (void)
> static int read_inferior_integer (CORE_ADDR symaddr, int *val);
>
> /* Returns true if both the in-process agent library and the static
> - tracepoints libraries are loaded in the inferior. */
> + tracepoints libraries are loaded in the inferior, and agent has
> + capability on static tracepoints. */
>
> static int
> -in_process_agent_loaded_ust (void)
> +in_process_agent_supports_ust (void)
> {
> int loaded = 0;
>
> @@ -258,7 +259,10 @@ in_process_agent_loaded_ust (void)
> return 0;
> }
>
> - return loaded;
> + if (loaded)
> + return agent_capability_check (AGENT_CAPA_STATIC_TRACE);
Hmm, this looks backwards. We're reading the existence of a global in
the agent called "ust_loaded", indicating whether it has loaded
ust, and after, we check for the static trace capability. If
"ust_loaded" exists in the agent, then it sure understands static
tracepoints. The right check is:
1. does the agent understand static tracepoints?
2. yes? good. and, is ust loaded perchance?
If the agent doesn't understand AGENT_CAPA_STATIC_TRACE,
then you'd fail right on the ust_loaded read, or some other
mechanism to check whether ust is in fact loaded in the inferior.
> + else
> + return 0;
> }
>
> static void
> @@ -310,7 +314,7 @@ maybe_write_ipa_ust_not_loaded (char *buffer)
> write_e_ipa_not_loaded (buffer);
> return 1;
> }
> - else if (!in_process_agent_loaded_ust ())
> + else if (!in_process_agent_supports_ust ())
> {
> write_e_ust_not_loaded (buffer);
> return 1;
> @@ -2315,6 +2319,10 @@ clear_installed_tracepoints (void)
> ;
> else
> {
> + /* Static tracepoints have been inserted, so agent should have
> + been loaded and working. */
> + gdb_assert (in_process_agent_supports_ust ());
This triggers an extra read off the inferior at each installed tracepoints. Is
it worth it?
> +
> unprobe_marker_at (tpoint->address);
> prev_stpoint = tpoint;
> }
> @@ -2965,7 +2973,8 @@ install_tracepoint (struct tracepoint *tpoint, char *own_buf)
> write_e_ipa_not_loaded (own_buf);
> return;
> }
> - if (tpoint->type == static_tracepoint && !in_process_agent_loaded_ust ())
> + if (tpoint->type == static_tracepoint
> + && !in_process_agent_supports_ust ())
> {
> trace_debug ("Requested a static tracepoint, but static "
> "tracepoints are not supported.");
> @@ -2990,8 +2999,8 @@ install_tracepoint (struct tracepoint *tpoint, char *own_buf)
> }
> else
> {
> - if (tp)
> - tpoint->handle = (void *) -1;
Why do we lose this? This was just cloning another static tracepoint, but
in the static tracepoint case, an installed static tracepoint has a handle == -1
(vs NULL).
> + if (!in_process_agent_supports_ust ())
> + warning ("Agent does not have capability for static tracepoint.");
How did we get so far then? There's that "Requested a static tracepoint, but static..."
check quoted above, above.
> else
This if/else connection appears confused.
> {
> if (probe_marker_at (tpoint->address, own_buf) == 0)
> @@ -7994,6 +8003,8 @@ gdb_agent_helper_thread (void *arg)
> #include <signal.h>
> #include <pthread.h>
>
> +IP_AGENT_EXPORT int gdb_agent_capability = AGENT_CAPA_STATIC_TRACE;
> +
> static void
> gdb_agent_init (void)
> {
> diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
> index c56a02c..c2801f9 100644
> --- a/gdb/tracepoint.c
> +++ b/gdb/tracepoint.c
> @@ -4893,6 +4893,11 @@ info_static_tracepoint_markers_command (char *arg, int from_tty)
> warning (_("Agent is off. Run `set agent on'."));
> return;
> }
> + if (!agent_capability_check (AGENT_CAPA_STATIC_TRACE))
> + {
> + warning (_("Agent is not capable of operating static tracepoints"));
> + return;
> + }
Same comment as in the other patch. I don't think this is right. Also, does
this work for remote debugging? Who is calling agent_look_up_symbols? gdb
knowing about IPA's internals when remote debugging feels a bit dirty.
>
> old_chain
> = make_cleanup_ui_out_table_begin_end (uiout, 5, -1,
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 6/9] agent capability of static tracepoint
2012-02-23 22:06 ` Pedro Alves
@ 2012-02-24 13:19 ` Yao Qi
2012-02-24 14:25 ` Pedro Alves
0 siblings, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-24 13:19 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 3120 bytes --]
On 02/24/2012 05:51 AM, Pedro Alves wrote:
> Hmm, this looks backwards. We're reading the existence of a global in
> the agent called "ust_loaded", indicating whether it has loaded
> ust, and after, we check for the static trace capability. If
> "ust_loaded" exists in the agent, then it sure understands static
> tracepoints. The right check is:
>
> 1. does the agent understand static tracepoints?
> 2. yes? good. and, is ust loaded perchance?
>
> If the agent doesn't understand AGENT_CAPA_STATIC_TRACE,
> then you'd fail right on the ust_loaded read, or some other
> mechanism to check whether ust is in fact loaded in the inferior.
>
This logic makes sense to me.
>> > @@ -2315,6 +2319,10 @@ clear_installed_tracepoints (void)
>> > ;
>> > else
>> > {
>> > + /* Static tracepoints have been inserted, so agent should have
>> > + been loaded and working. */
>> > + gdb_assert (in_process_agent_supports_ust ());
> This triggers an extra read off the inferior at each installed tracepoints. Is
> it worth it?
>
Hmm, I am OK to remove it, to avoid reading from inferior.
>> > @@ -2990,8 +2999,8 @@ install_tracepoint (struct tracepoint *tpoint, char *own_buf)
>> > }
>> > else
>> > {
>> > - if (tp)
>> > - tpoint->handle = (void *) -1;
> Why do we lose this? This was just cloning another static tracepoint, but
> in the static tracepoint case, an installed static tracepoint has a handle == -1
> (vs NULL).
>
>
Sorry, it is a mistake when I split patches. It should be in my
next patch set, which refactor code here a little.
>> > + if (!in_process_agent_supports_ust ())
>> > + warning ("Agent does not have capability for static tracepoint.");
> How did we get so far then? There's that "Requested a static tracepoint, but static..."
> check quoted above, above.
>
This part is redundant. Removed.
>> > else
> This if/else connection appears confused.
>
>> > {
>> > if (probe_marker_at (tpoint->address, own_buf) == 0)
>> > @@ -7994,6 +8003,8 @@ gdb_agent_helper_thread (void *arg)
>> > #include <signal.h>
>> > #include <pthread.h>
>> >
>> > +IP_AGENT_EXPORT int gdb_agent_capability = AGENT_CAPA_STATIC_TRACE;
>> > +
>> > static void
>> > gdb_agent_init (void)
>> > {
>> > diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
>> > index c56a02c..c2801f9 100644
>> > --- a/gdb/tracepoint.c
>> > +++ b/gdb/tracepoint.c
>> > @@ -4893,6 +4893,11 @@ info_static_tracepoint_markers_command (char *arg, int from_tty)
>> > warning (_("Agent is off. Run `set agent on'."));
>> > return;
>> > }
>> > + if (!agent_capability_check (AGENT_CAPA_STATIC_TRACE))
>> > + {
>> > + warning (_("Agent is not capable of operating static tracepoints"));
>> > + return;
>> > + }
> Same comment as in the other patch. I don't think this is right. Also, does
> this work for remote debugging? Who is calling agent_look_up_symbols? gdb
> knowing about IPA's internals when remote debugging feels a bit dirty.
>
This chunk is removed, explained in my reply to patch 2/9.
--
Yao (é½å°§)
[-- Attachment #2: 0006-agent-capability-of-static-tracepoint.patch --]
[-- Type: text/x-patch, Size: 2662 bytes --]
gdb/gdbserver:
2012-02-24 Yao Qi <yao@codesourcery.com>
* tracepoint.c (gdb_agent_capability): New global.
(in_process_agent_loaded_ust): Renamed to
`in_process_agent_supports_ust'.
Update callers.
(in_process_agent_supports_ust): Call agent_capability_check.
(clear_installed_tracepoints): Assert that agent supports
agent.
---
gdb/gdbserver/tracepoint.c | 29 ++++++++++++++++++++---------
1 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 3b6f2f4..a48edaa 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -239,10 +239,11 @@ in_process_agent_loaded (void)
static int read_inferior_integer (CORE_ADDR symaddr, int *val);
/* Returns true if both the in-process agent library and the static
- tracepoints libraries are loaded in the inferior. */
+ tracepoints libraries are loaded in the inferior, and agent has
+ capability on static tracepoints. */
static int
-in_process_agent_loaded_ust (void)
+in_process_agent_supports_ust (void)
{
int loaded = 0;
@@ -252,13 +253,20 @@ in_process_agent_loaded_ust (void)
return 0;
}
- if (read_inferior_integer (ipa_sym_addrs.addr_ust_loaded, &loaded))
+ if (agent_capability_check (AGENT_CAPA_STATIC_TRACE))
{
- warning ("Error reading ust_loaded in lib");
- return 0;
- }
+ /* Agent understands static tracepoint, then check whether UST is in
+ fact loaded in the inferior. */
+ if (read_inferior_integer (ipa_sym_addrs.addr_ust_loaded, &loaded))
+ {
+ warning ("Error reading ust_loaded in lib");
+ return 0;
+ }
- return loaded;
+ return loaded;
+ }
+ else
+ return 0;
}
static void
@@ -310,7 +318,7 @@ maybe_write_ipa_ust_not_loaded (char *buffer)
write_e_ipa_not_loaded (buffer);
return 1;
}
- else if (!in_process_agent_loaded_ust ())
+ else if (!in_process_agent_supports_ust ())
{
write_e_ust_not_loaded (buffer);
return 1;
@@ -2965,7 +2973,8 @@ install_tracepoint (struct tracepoint *tpoint, char *own_buf)
write_e_ipa_not_loaded (own_buf);
return;
}
- if (tpoint->type == static_tracepoint && !in_process_agent_loaded_ust ())
+ if (tpoint->type == static_tracepoint
+ && !in_process_agent_supports_ust ())
{
trace_debug ("Requested a static tracepoint, but static "
"tracepoints are not supported.");
@@ -7988,6 +7997,8 @@ gdb_agent_helper_thread (void *arg)
#include <signal.h>
#include <pthread.h>
+IP_AGENT_EXPORT int gdb_agent_capability = AGENT_CAPA_STATIC_TRACE;
+
static void
gdb_agent_init (void)
{
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 6/9] agent capability of static tracepoint
2012-02-24 13:19 ` Yao Qi
@ 2012-02-24 14:25 ` Pedro Alves
0 siblings, 0 replies; 49+ messages in thread
From: Pedro Alves @ 2012-02-24 14:25 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/24/2012 01:12 PM, Yao Qi wrote:
> On 02/24/2012 05:51 AM, Pedro Alves wrote:
>> > Hmm, this looks backwards. We're reading the existence of a global in
>> > the agent called "ust_loaded", indicating whether it has loaded
>> > ust, and after, we check for the static trace capability. If
>> > "ust_loaded" exists in the agent, then it sure understands static
>> > tracepoints. The right check is:
>> >
>> > 1. does the agent understand static tracepoints?
>> > 2. yes? good. and, is ust loaded perchance?
>> >
>> > If the agent doesn't understand AGENT_CAPA_STATIC_TRACE,
>> > then you'd fail right on the ust_loaded read, or some other
>> > mechanism to check whether ust is in fact loaded in the inferior.
>> >
> This logic makes sense to me.
Then can you revert the rename please (and the reindent it caused)?
Reading the callers, "loaded" is stronger than "supports", which would
be true even if ust is not loaded. Let's leave a rename out until the
semantics of the function changes.
> /* Returns true if both the in-process agent library and the static
> - tracepoints libraries are loaded in the inferior. */
> + tracepoints libraries are loaded in the inferior, and agent has
> + capability on static tracepoints. */
s/on/for
Okay with those changes.
--
Pedro Alves
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH 9/9] info static tracepoint in linux-nat.
2012-02-17 2:56 [patch v2] GDB/GDBserver talks with agents Yao Qi
` (7 preceding siblings ...)
2012-02-17 2:57 ` [PATCH 6/9] agent capability of static tracepoint Yao Qi
@ 2012-02-17 3:02 ` Yao Qi
2012-02-24 13:37 ` Yao Qi
2012-02-17 4:02 ` [patch v2] GDB/GDBserver talks with agents Yao Qi
2012-02-17 12:03 ` Eli Zaretskii
10 siblings, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-17 3:02 UTC (permalink / raw)
To: gdb-patches
This patch is to exercise agent in linux native gdb by command `info
static-tracepoint-marker'. The implementation of `linux_child_static_tracepoint_markers_by_strid'
is quite similar to its counterpart in remote target, except bits to pause and unpause
all threads in current process.
gdb.trace/strace.exp is updated as well to test this point.
2012-02-14 Yao Qi <yao@codesourcery.com>
* linux-nat.c (linux_child_static_tracepoint_markers_by_strid):
New.
(linux_target_install_ops): Initialize field
`to_static_tracepoint_markers_by_strid'.
* remote.c (free_current_marker): Move it to ...
* tracepoint.c (free_current_marker): ... here. New.
(cleanup_target_stop): New.
* tracepoint.h: Declare free_current_marker.
gdb/testsuite/
2012-02-15 Yao Qi <yao@codesourcery.com>
* gdb.trace/strace.exp: run strace_info_marker in native gdb.
---
gdb/linux-nat.c | 71 ++++++++++++++++++++++++++++++++++++
gdb/remote.c | 14 -------
gdb/testsuite/gdb.trace/strace.exp | 35 +++++++++++-------
gdb/tracepoint.c | 14 +++++++
gdb/tracepoint.h | 1 +
5 files changed, 107 insertions(+), 28 deletions(-)
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 3e81fd0..f77ec6e 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -60,6 +60,7 @@
#include "linux-osdata.h"
#include "linux-tdep.h"
#include "agent.h"
+#include "tracepoint.h"
#ifndef SPUFS_MAGIC
#define SPUFS_MAGIC 0x23c9b64e
@@ -4819,6 +4820,73 @@ linux_child_can_use_agent (void)
return agent_loaded_p ();
}
+static void
+cleanup_target_stop (void *arg)
+{
+ ptid_t *ptid = (ptid_t *) arg;
+
+ gdb_assert (arg != NULL);
+
+ /* Unpause all */
+ target_resume (*ptid, 0, TARGET_SIGNAL_0);
+}
+
+static VEC(static_tracepoint_marker_p) *
+linux_child_static_tracepoint_markers_by_strid (const char *strid)
+{
+ char s[IPA_CMD_BUF_SIZE];
+ struct cleanup *old_chain;
+ int pid = ptid_get_pid (inferior_ptid);
+ VEC(static_tracepoint_marker_p) *markers = NULL;
+ struct static_tracepoint_marker *marker = NULL;
+ char *p = s;
+ ptid_t ptid = ptid_build (pid, 0, 0);
+
+ /* Pause all */
+ target_stop (ptid);
+
+ memcpy (s, "qTfSTM", sizeof ("qTfSTM"));
+ s[sizeof ("qTfSTM")] = 0;
+
+ agent_run_command (pid, s);
+
+ old_chain = make_cleanup (free_current_marker, &marker);
+ make_cleanup (cleanup_target_stop, &ptid);
+
+ while (*p++ == 'm')
+ {
+ if (marker == NULL)
+ marker = XCNEW (struct static_tracepoint_marker);
+
+ do
+ {
+ parse_static_tracepoint_marker_definition (p, &p, marker);
+
+ if (strid == NULL || strcmp (strid, marker->str_id) == 0)
+ {
+ VEC_safe_push (static_tracepoint_marker_p,
+ markers, marker);
+ marker = NULL;
+ }
+ else
+ {
+ release_static_tracepoint_marker (marker);
+ memset (marker, 0, sizeof (*marker));
+ }
+ }
+ while (*p++ == ','); /* comma-separated list */
+
+ memcpy (s, "qTsSTM", sizeof ("qTsSTM"));
+ s[sizeof ("qTsSTM")] = 0;
+ agent_run_command (pid, s);
+ p = s;
+ }
+
+ do_cleanups (old_chain);
+
+ return markers;
+}
+
/* Create a prototype generic GNU/Linux target. The client can override
it with local methods. */
@@ -4843,6 +4911,9 @@ linux_target_install_ops (struct target_ops *t)
t->to_use_agent = linux_child_use_agent;
t->to_can_use_agent = linux_child_can_use_agent;
+
+ t->to_static_tracepoint_markers_by_strid
+ = linux_child_static_tracepoint_markers_by_strid;
}
struct target_ops *
diff --git a/gdb/remote.c b/gdb/remote.c
index 2977e31..422c7d4 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -2846,20 +2846,6 @@ remote_static_tracepoint_marker_at (CORE_ADDR addr,
return 0;
}
-static void
-free_current_marker (void *arg)
-{
- struct static_tracepoint_marker **marker_p = arg;
-
- if (*marker_p != NULL)
- {
- release_static_tracepoint_marker (*marker_p);
- xfree (*marker_p);
- }
- else
- *marker_p = NULL;
-}
-
static VEC(static_tracepoint_marker_p) *
remote_static_tracepoint_markers_by_strid (const char *strid)
{
diff --git a/gdb/testsuite/gdb.trace/strace.exp b/gdb/testsuite/gdb.trace/strace.exp
index 8b0c4ef..f30eb79 100644
--- a/gdb/testsuite/gdb.trace/strace.exp
+++ b/gdb/testsuite/gdb.trace/strace.exp
@@ -38,20 +38,6 @@ if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $additional_flags
return -1
}
-clean_restart $executable
-
-if ![runto_main] {
- fail "Can't run to main to check for trace support"
- return -1
-}
-
-if { ![gdb_target_supports_trace] } then {
- unsupported "Current target does not support trace"
- return -1;
-}
-
-gdb_load_shlibs $libipa
-
proc strace_info_marker { } {
global executable
global pf_prefix
@@ -269,6 +255,27 @@ proc strace_trace_on_diff_addr { } {
set pf_prefix $old_pf_prefix
}
+clean_restart $executable
+
+if ![runto_main] {
+ fail "Can't run to main to check for trace support"
+ return -1
+}
+
+# Run it on native x86/x86_64 linux.
+if { ![is_remote target]
+ && ([istarget "x86_64-*-linux*"] || [istarget "i\[34567\]86-*-linux*"]) } {
+ strace_info_marker
+ return
+}
+
+if { ![gdb_target_supports_trace] } then {
+ unsupported "Current target does not support trace"
+ return -1;
+}
+
+gdb_load_shlibs $libipa
+
strace_info_marker
strace_probe_marker
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index c2801f9..c4bfbd5 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -4701,6 +4701,20 @@ init_tfile_ops (void)
tfile_ops.to_magic = OPS_MAGIC;
}
+void
+free_current_marker (void *arg)
+{
+ struct static_tracepoint_marker **marker_p = arg;
+
+ if (*marker_p != NULL)
+ {
+ release_static_tracepoint_marker (*marker_p);
+ xfree (*marker_p);
+ }
+ else
+ *marker_p = NULL;
+}
+
/* Given a line of text defining a static tracepoint marker, parse it
into a "static tracepoint marker" object. Throws an error is
parsing fails. If PP is non-null, it points to one past the end of
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
index 00c4d7c..30a810a 100644
--- a/gdb/tracepoint.h
+++ b/gdb/tracepoint.h
@@ -209,6 +209,7 @@ extern void parse_static_tracepoint_marker_definition
(char *line, char **pp,
struct static_tracepoint_marker *marker);
extern void release_static_tracepoint_marker (struct static_tracepoint_marker *);
+extern void free_current_marker (void *arg);
/* A hook used to notify the UI of tracepoint operations. */
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 9/9] info static tracepoint in linux-nat.
2012-02-17 3:02 ` [PATCH 9/9] info static tracepoint in linux-nat Yao Qi
@ 2012-02-24 13:37 ` Yao Qi
0 siblings, 0 replies; 49+ messages in thread
From: Yao Qi @ 2012-02-24 13:37 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 943 bytes --]
On 02/17/2012 10:55 AM, Yao Qi wrote:
> This patch is to exercise agent in linux native gdb by command `info
> static-tracepoint-marker'. The implementation of `linux_child_static_tracepoint_markers_by_strid'
> is quite similar to its counterpart in remote target, except bits to pause and unpause
> all threads in current process.
Even target_ops hook `can_use_agent' and `use_agent' are implemented in
inf-child.c by patch
[PATCH 8/9] impl of use_agent and can_use_agent in linux-nat
http://sourceware.org/ml/gdb-patches/2012-02/msg00553.html
I am still inclined to implement static_tracepoint_markers_by_strid in
linux-nat, because there is no agent at all for non-linux system.
Although agent itself is quite generic to all unix system, it still
needs de-couple from tracepoint. On the other hand, UST is
Linux-specific, so it is better to keep
static_tracepoint_markers_by_strid implemented in linux-nat.
--
Yao (é½å°§)
[-- Attachment #2: 0009-info-static-tracepoint-in-linux-nat.patch --]
[-- Type: text/x-patch, Size: 6254 bytes --]
2012-02-17 Yao Qi <yao@codesourcery.com>
* linux-nat.c (linux_child_static_tracepoint_markers_by_strid):
New.
(linux_target_install_ops): Initialize field
`to_static_tracepoint_markers_by_strid'.
* remote.c (free_current_marker): Move it to ...
* tracepoint.c (free_current_marker): ... here. New.
(cleanup_target_stop): New.
* tracepoint.h: Declare free_current_marker.
gdb/testsuite/
2012-02-17 Yao Qi <yao@codesourcery.com>
* gdb.trace/strace.exp: run strace_info_marker in linux native gdb.
---
gdb/linux-nat.c | 72 ++++++++++++++++++++++++++++++++++++
gdb/remote.c | 14 -------
gdb/testsuite/gdb.trace/strace.exp | 35 ++++++++++-------
gdb/tracepoint.c | 14 +++++++
gdb/tracepoint.h | 1 +
5 files changed, 108 insertions(+), 28 deletions(-)
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 6aab087..82b7b57 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -59,6 +59,8 @@
#include "solib.h"
#include "linux-osdata.h"
#include "linux-tdep.h"
+#include "agent.h"
+#include "tracepoint.h"
#ifndef SPUFS_MAGIC
#define SPUFS_MAGIC 0x23c9b64e
@@ -4800,6 +4802,73 @@ linux_xfer_partial (struct target_ops *ops, enum target_object object,
offset, len);
}
+static void
+cleanup_target_stop (void *arg)
+{
+ ptid_t *ptid = (ptid_t *) arg;
+
+ gdb_assert (arg != NULL);
+
+ /* Unpause all */
+ target_resume (*ptid, 0, TARGET_SIGNAL_0);
+}
+
+static VEC(static_tracepoint_marker_p) *
+linux_child_static_tracepoint_markers_by_strid (const char *strid)
+{
+ char s[IPA_CMD_BUF_SIZE];
+ struct cleanup *old_chain;
+ int pid = ptid_get_pid (inferior_ptid);
+ VEC(static_tracepoint_marker_p) *markers = NULL;
+ struct static_tracepoint_marker *marker = NULL;
+ char *p = s;
+ ptid_t ptid = ptid_build (pid, 0, 0);
+
+ /* Pause all */
+ target_stop (ptid);
+
+ memcpy (s, "qTfSTM", sizeof ("qTfSTM"));
+ s[sizeof ("qTfSTM")] = 0;
+
+ agent_run_command (pid, s);
+
+ old_chain = make_cleanup (free_current_marker, &marker);
+ make_cleanup (cleanup_target_stop, &ptid);
+
+ while (*p++ == 'm')
+ {
+ if (marker == NULL)
+ marker = XCNEW (struct static_tracepoint_marker);
+
+ do
+ {
+ parse_static_tracepoint_marker_definition (p, &p, marker);
+
+ if (strid == NULL || strcmp (strid, marker->str_id) == 0)
+ {
+ VEC_safe_push (static_tracepoint_marker_p,
+ markers, marker);
+ marker = NULL;
+ }
+ else
+ {
+ release_static_tracepoint_marker (marker);
+ memset (marker, 0, sizeof (*marker));
+ }
+ }
+ while (*p++ == ','); /* comma-separated list */
+
+ memcpy (s, "qTsSTM", sizeof ("qTsSTM"));
+ s[sizeof ("qTsSTM")] = 0;
+ agent_run_command (pid, s);
+ p = s;
+ }
+
+ do_cleanups (old_chain);
+
+ return markers;
+}
+
/* Create a prototype generic GNU/Linux target. The client can override
it with local methods. */
@@ -4821,6 +4890,9 @@ linux_target_install_ops (struct target_ops *t)
super_xfer_partial = t->to_xfer_partial;
t->to_xfer_partial = linux_xfer_partial;
+
+ t->to_static_tracepoint_markers_by_strid
+ = linux_child_static_tracepoint_markers_by_strid;
}
struct target_ops *
diff --git a/gdb/remote.c b/gdb/remote.c
index 2977e31..422c7d4 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -2846,20 +2846,6 @@ remote_static_tracepoint_marker_at (CORE_ADDR addr,
return 0;
}
-static void
-free_current_marker (void *arg)
-{
- struct static_tracepoint_marker **marker_p = arg;
-
- if (*marker_p != NULL)
- {
- release_static_tracepoint_marker (*marker_p);
- xfree (*marker_p);
- }
- else
- *marker_p = NULL;
-}
-
static VEC(static_tracepoint_marker_p) *
remote_static_tracepoint_markers_by_strid (const char *strid)
{
diff --git a/gdb/testsuite/gdb.trace/strace.exp b/gdb/testsuite/gdb.trace/strace.exp
index 4d6ea10..d4a9a9e 100644
--- a/gdb/testsuite/gdb.trace/strace.exp
+++ b/gdb/testsuite/gdb.trace/strace.exp
@@ -38,20 +38,6 @@ if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $additional_flags
return -1
}
-clean_restart $executable
-
-if ![runto_main] {
- fail "Can't run to main to check for trace support"
- return -1
-}
-
-if { ![gdb_target_supports_trace] } then {
- unsupported "Current target does not support trace"
- return -1;
-}
-
-gdb_load_shlibs $libipa
-
proc strace_info_marker { } {
global executable
global pf_prefix
@@ -265,6 +251,27 @@ proc strace_trace_on_diff_addr { } {
set pf_prefix $old_pf_prefix
}
+clean_restart $executable
+
+if ![runto_main] {
+ fail "Can't run to main to check for trace support"
+ return -1
+}
+
+# Run it on native x86/x86_64 linux.
+if { ![is_remote target]
+ && ([istarget "x86_64-*-linux*"] || [istarget "i\[34567\]86-*-linux*"]) } {
+ strace_info_marker
+ return
+}
+
+if { ![gdb_target_supports_trace] } then {
+ unsupported "Current target does not support trace"
+ return -1;
+}
+
+gdb_load_shlibs $libipa
+
strace_info_marker
strace_probe_marker
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 194977b..243ec4d 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -4700,6 +4700,20 @@ init_tfile_ops (void)
tfile_ops.to_magic = OPS_MAGIC;
}
+void
+free_current_marker (void *arg)
+{
+ struct static_tracepoint_marker **marker_p = arg;
+
+ if (*marker_p != NULL)
+ {
+ release_static_tracepoint_marker (*marker_p);
+ xfree (*marker_p);
+ }
+ else
+ *marker_p = NULL;
+}
+
/* Given a line of text defining a static tracepoint marker, parse it
into a "static tracepoint marker" object. Throws an error is
parsing fails. If PP is non-null, it points to one past the end of
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
index 00c4d7c..30a810a 100644
--- a/gdb/tracepoint.h
+++ b/gdb/tracepoint.h
@@ -209,6 +209,7 @@ extern void parse_static_tracepoint_marker_definition
(char *line, char **pp,
struct static_tracepoint_marker *marker);
extern void release_static_tracepoint_marker (struct static_tracepoint_marker *);
+extern void free_current_marker (void *arg);
/* A hook used to notify the UI of tracepoint operations. */
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [patch v2] GDB/GDBserver talks with agents
2012-02-17 2:56 [patch v2] GDB/GDBserver talks with agents Yao Qi
` (8 preceding siblings ...)
2012-02-17 3:02 ` [PATCH 9/9] info static tracepoint in linux-nat Yao Qi
@ 2012-02-17 4:02 ` Yao Qi
2012-02-17 12:03 ` Eli Zaretskii
10 siblings, 0 replies; 49+ messages in thread
From: Yao Qi @ 2012-02-17 4:02 UTC (permalink / raw)
To: gdb-patches
On 02/17/2012 10:54 AM, Yao Qi wrote:
> [patch 0/8] GDB/GDBserver talks with agents
> http://sourceware.org/ml/gdb-patches/2012-01/msg00762.html
Don't know why `git send-email' "eats" my first paragraph. Here is the
original one.
This is the V2 of patches to enable both GDB and GDBserver talk with
agent. All the comments to V1 are addressed.
[patch 0/8] GDB/GDBserver talks with agents
http://sourceware.org/ml/gdb-patches/2012-01/msg00762.html
......
--
Yao (é½å°§)
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [patch v2] GDB/GDBserver talks with agents
2012-02-17 2:56 [patch v2] GDB/GDBserver talks with agents Yao Qi
` (9 preceding siblings ...)
2012-02-17 4:02 ` [patch v2] GDB/GDBserver talks with agents Yao Qi
@ 2012-02-17 12:03 ` Eli Zaretskii
2012-02-27 9:43 ` Yao Qi
10 siblings, 1 reply; 49+ messages in thread
From: Eli Zaretskii @ 2012-02-17 12:03 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
> From: Yao Qi <yao@codesourcery.com>
> Date: Fri, 17 Feb 2012 10:54:51 +0800
>
>
> [patch 0/8] GDB/GDBserver talks with agents
> http://sourceware.org/ml/gdb-patches/2012-01/msg00762.html
>
> Patch 8/9 and 9/9 are new in this series. They are about implementing new
> added target hooks in linux-nat, and enable info static tracepoint markers
> on native gdb in order to demo agent is able work well with GDB.
>
> Patches are tested as a whole on x86_64-linux with native gdb and native-gdbserver.
> Some fails appear in result, but not caused by this patch series. They can be fixed
> by this patch.
>
> [patch/testsuite/gdbserver] unsuspend lwps after step over
> http://sourceware.org/ml/gdb-patches/2012-02/msg00343.html
What about a NEWS entry? should we have one?
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [patch v2] GDB/GDBserver talks with agents
2012-02-17 12:03 ` Eli Zaretskii
@ 2012-02-27 9:43 ` Yao Qi
2012-02-27 18:04 ` Eli Zaretskii
0 siblings, 1 reply; 49+ messages in thread
From: Yao Qi @ 2012-02-27 9:43 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 382 bytes --]
On 02/17/2012 07:39 PM, Eli Zaretskii wrote:
> What about a NEWS entry? should we have one?
Yes, we should. If I understand NEWS file correctly, only user-visible
changes are mentioned in it. Most of the changes in this patch series
is not user-visible, so I only add one entry about using `info
static-tracepoint-marker' on native-linux platform. WDYT?
--
Yao (é½å°§)
[-- Attachment #2: 0010-talk-with-agent-in-NEWS.patch --]
[-- Type: text/x-patch, Size: 608 bytes --]
2012-02-26 Yao Qi <yao@codesourcery.com>
* NEWS: Add one entry about `info static-tracepoint-marker'.
---
gdb/NEWS | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/gdb/NEWS b/gdb/NEWS
index 46ef6d8..881c185 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -44,6 +44,9 @@
* The command "info catch" has been removed. It has been disabled
since December 2007.
+* The "info static-tracepoint-marker" command will now also work on
+ native Linux targets with in-process agent.
+
* New commands
** "catch load" and "catch unload" can be used to stop when a shared
--
1.7.0.4
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [patch v2] GDB/GDBserver talks with agents
2012-02-27 9:43 ` Yao Qi
@ 2012-02-27 18:04 ` Eli Zaretskii
0 siblings, 0 replies; 49+ messages in thread
From: Eli Zaretskii @ 2012-02-27 18:04 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
> Date: Mon, 27 Feb 2012 16:03:36 +0800
> From: Yao Qi <yao@codesourcery.com>
> CC: <gdb-patches@sourceware.org>
>
> On 02/17/2012 07:39 PM, Eli Zaretskii wrote:
> > What about a NEWS entry? should we have one?
>
> Yes, we should. If I understand NEWS file correctly, only user-visible
> changes are mentioned in it. Most of the changes in this patch series
> is not user-visible, so I only add one entry about using `info
> static-tracepoint-marker' on native-linux platform. WDYT?
OK, thanks.
^ permalink raw reply [flat|nested] 49+ messages in thread