aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorSergio Durigan Junior <sergiodj@redhat.com>2013-07-24 19:50:32 +0000
committerSergio Durigan Junior <sergiodj@redhat.com>2013-07-24 19:50:32 +0000
commit25f9533e5145c7d1f41649536b710e12f3a1fcd9 (patch)
tree39c61fb54a54ee205ffe3d5f5fac735959a57535 /gdb
parentdf71cb5cbfa26ad79e5cf674056205f0505e229d (diff)
downloadgdb-25f9533e5145c7d1f41649536b710e12f3a1fcd9.zip
gdb-25f9533e5145c7d1f41649536b710e12f3a1fcd9.tar.gz
gdb-25f9533e5145c7d1f41649536b710e12f3a1fcd9.tar.bz2
2013-07-24 Sergio Durigan Junior <sergiodj@redhat.com>
* breakpoint.c (create_longjmp_master_breakpoint): Check if probe interface can evaluate arguments. Fallback to the old mode if it cannot. (create_exception_master_breakpoint): Likewise. * elfread.c (elf_can_evaluate_probe_arguments): New function. (struct sym_probe_fns elf_probe_fns): Export function above to the probe interface. * probe.c (can_evaluate_probe_arguments): New function. * probe.h (struct probe_ops) <can_evaluate_probe_arguments>: New function pointer. (can_evaluate_probe_arguments): New function prototype. * solib-svr4.c (svr4_create_solib_event_breakpoints): Check if probe interface can evaluate arguments. Fallback to the old mode if it cannot. * stap-probe.c (stap_get_probe_argument_count): Check if probe interface can evaluate arguments. Warning the user if it cannot. (stap_can_evaluate_probe_arguments): New function. (struct probe_ops stap_probe_ops): Export function above to the probe interface. * symfile.h (struct sym_probe_fns) <can_evaluate_probe_arguments>: New function pointer.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog24
-rw-r--r--gdb/breakpoint.c39
-rw-r--r--gdb/elfread.c20
-rw-r--r--gdb/probe.c17
-rw-r--r--gdb/probe.h12
-rw-r--r--gdb/solib-svr4.c14
-rw-r--r--gdb/stap-probe.c37
-rw-r--r--gdb/symfile.h8
8 files changed, 161 insertions, 10 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 672fb5d..2ebf9db 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,27 @@
+2013-07-24 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ * breakpoint.c (create_longjmp_master_breakpoint): Check if probe
+ interface can evaluate arguments. Fallback to the old mode if it
+ cannot.
+ (create_exception_master_breakpoint): Likewise.
+ * elfread.c (elf_can_evaluate_probe_arguments): New function.
+ (struct sym_probe_fns elf_probe_fns): Export function above to the
+ probe interface.
+ * probe.c (can_evaluate_probe_arguments): New function.
+ * probe.h (struct probe_ops) <can_evaluate_probe_arguments>: New
+ function pointer.
+ (can_evaluate_probe_arguments): New function prototype.
+ * solib-svr4.c (svr4_create_solib_event_breakpoints): Check if
+ probe interface can evaluate arguments. Fallback to the old mode
+ if it cannot.
+ * stap-probe.c (stap_get_probe_argument_count): Check if probe
+ interface can evaluate arguments. Warning the user if it cannot.
+ (stap_can_evaluate_probe_arguments): New function.
+ (struct probe_ops stap_probe_ops): Export function above to the
+ probe interface.
+ * symfile.h (struct sym_probe_fns) <can_evaluate_probe_arguments>:
+ New function pointer.
+
2013-07-24 Luis Machado <lgustavo@codesourcery.com>
* Makefile.in (SFILES): Add common/target-common.c.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 4d09b30..1e89407 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -3194,8 +3194,23 @@ create_longjmp_master_breakpoint (void)
if (!bp_objfile_data->longjmp_searched)
{
- bp_objfile_data->longjmp_probes
- = find_probes_in_objfile (objfile, "libc", "longjmp");
+ VEC (probe_p) *ret;
+
+ ret = find_probes_in_objfile (objfile, "libc", "longjmp");
+ if (ret != NULL)
+ {
+ /* We are only interested in checking one element. */
+ struct probe *p = VEC_index (probe_p, ret, 0);
+
+ if (!can_evaluate_probe_arguments (p))
+ {
+ /* We cannot use the probe interface here, because it does
+ not know how to evaluate arguments. */
+ VEC_free (probe_p, ret);
+ ret = NULL;
+ }
+ }
+ bp_objfile_data->longjmp_probes = ret;
bp_objfile_data->longjmp_searched = 1;
}
@@ -3336,8 +3351,24 @@ create_exception_master_breakpoint (void)
/* We prefer the SystemTap probe point if it exists. */
if (!bp_objfile_data->exception_searched)
{
- bp_objfile_data->exception_probes
- = find_probes_in_objfile (objfile, "libgcc", "unwind");
+ VEC (probe_p) *ret;
+
+ ret = find_probes_in_objfile (objfile, "libgcc", "unwind");
+
+ if (ret != NULL)
+ {
+ /* We are only interested in checking one element. */
+ struct probe *p = VEC_index (probe_p, ret, 0);
+
+ if (!can_evaluate_probe_arguments (p))
+ {
+ /* We cannot use the probe interface here, because it does
+ not know how to evaluate arguments. */
+ VEC_free (probe_p, ret);
+ ret = NULL;
+ }
+ }
+ bp_objfile_data->exception_probes = ret;
bp_objfile_data->exception_searched = 1;
}
diff --git a/gdb/elfread.c b/gdb/elfread.c
index cfdfe45..1aa10d1 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1643,6 +1643,15 @@ elf_get_probe_argument_count (struct probe *probe)
return probe->pops->get_probe_argument_count (probe);
}
+/* Implementation of `sym_can_evaluate_probe_arguments', as documented in
+ symfile.h. */
+
+static int
+elf_can_evaluate_probe_arguments (struct probe *probe)
+{
+ return probe->pops->can_evaluate_probe_arguments (probe);
+}
+
/* Implementation of `sym_evaluate_probe_argument', as documented in
symfile.h. */
@@ -1700,11 +1709,12 @@ probe_key_free (struct objfile *objfile, void *d)
static const struct sym_probe_fns elf_probe_fns =
{
- elf_get_probes, /* sym_get_probes */
- elf_get_probe_argument_count, /* sym_get_probe_argument_count */
- elf_evaluate_probe_argument, /* sym_evaluate_probe_argument */
- elf_compile_to_ax, /* sym_compile_to_ax */
- elf_symfile_relocate_probe, /* sym_relocate_probe */
+ elf_get_probes, /* sym_get_probes */
+ elf_get_probe_argument_count, /* sym_get_probe_argument_count */
+ elf_can_evaluate_probe_arguments, /* sym_can_evaluate_probe_arguments */
+ elf_evaluate_probe_argument, /* sym_evaluate_probe_argument */
+ elf_compile_to_ax, /* sym_compile_to_ax */
+ elf_symfile_relocate_probe, /* sym_relocate_probe */
};
/* Register that we are able to handle ELF object file formats. */
diff --git a/gdb/probe.c b/gdb/probe.c
index e650892..c313c38 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -628,6 +628,23 @@ get_probe_argument_count (struct probe *probe)
/* See comments in probe.h. */
+int
+can_evaluate_probe_arguments (struct probe *probe)
+{
+ const struct sym_probe_fns *probe_fns;
+
+ gdb_assert (probe->objfile != NULL);
+ gdb_assert (probe->objfile->sf != NULL);
+
+ probe_fns = probe->objfile->sf->sym_probe_fns;
+
+ gdb_assert (probe_fns != NULL);
+
+ return probe_fns->can_evaluate_probe_arguments (probe);
+}
+
+/* See comments in probe.h. */
+
struct value *
evaluate_probe_argument (struct probe *probe, unsigned n)
{
diff --git a/gdb/probe.h b/gdb/probe.h
index de07f50..dd5387b 100644
--- a/gdb/probe.h
+++ b/gdb/probe.h
@@ -73,6 +73,12 @@ struct probe_ops
unsigned (*get_probe_argument_count) (struct probe *probe);
+ /* Return 1 if the probe interface can evaluate the arguments of probe
+ PROBE, zero otherwise. See the comments on
+ sym_probe_fns:can_evaluate_probe_arguments for more details. */
+
+ int (*can_evaluate_probe_arguments) (struct probe *probe);
+
/* Evaluate the Nth argument from the PROBE, returning a value
corresponding to it. The argument number is represented N. */
@@ -218,6 +224,12 @@ extern struct cmd_list_element **info_probes_cmdlist_get (void);
extern unsigned get_probe_argument_count (struct probe *probe);
+/* Return 1 if the probe interface associated with PROBE can evaluate
+ arguments, zero otherwise. See the comments on the definition of
+ sym_probe_fns:can_evaluate_probe_arguments for more details. */
+
+extern int can_evaluate_probe_arguments (struct probe *probe);
+
/* Evaluate argument N of the specified probe. N must be between 0
inclusive and get_probe_argument_count exclusive. */
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index ccfd158..a497c6c 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1978,12 +1978,14 @@ svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch,
{
VEC (probe_p) *probes[NUM_PROBES];
int all_probes_found = 1;
+ int checked_can_use_probe_arguments = 0;
int i;
memset (probes, 0, sizeof (probes));
for (i = 0; i < NUM_PROBES; i++)
{
const char *name = probe_info[i].name;
+ struct probe *p;
char buf[32];
/* Fedora 17 and Red Hat Enterprise Linux 6.2-6.4
@@ -2012,6 +2014,18 @@ svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch,
all_probes_found = 0;
break;
}
+
+ /* Ensure probe arguments can be evaluated. */
+ if (!checked_can_use_probe_arguments)
+ {
+ p = VEC_index (probe_p, probes[i], 0);
+ if (!can_evaluate_probe_arguments (p))
+ {
+ all_probes_found = 0;
+ break;
+ }
+ checked_can_use_probe_arguments = 1;
+ }
}
if (all_probes_found)
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index 1079e3b..cbbdf391 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -1009,7 +1009,27 @@ stap_get_probe_argument_count (struct probe *probe_generic)
gdb_assert (probe_generic->pops == &stap_probe_ops);
if (!probe->args_parsed)
- stap_parse_probe_arguments (probe);
+ {
+ if (probe_generic->pops->can_evaluate_probe_arguments (probe_generic))
+ stap_parse_probe_arguments (probe);
+ else
+ {
+ static int have_warned_stap_incomplete = 0;
+
+ if (!have_warned_stap_incomplete)
+ {
+ warning (_(
+"The SystemTap SDT probe support is not fully implemented on this target;\n"
+"you will not be able to inspect the arguments of the probes.\n"
+"Please report a bug against GDB requesting a port to this target."));
+ have_warned_stap_incomplete = 1;
+ }
+
+ /* Marking the arguments as "already parsed". */
+ probe->args_u.vec = NULL;
+ probe->args_parsed = 1;
+ }
+ }
gdb_assert (probe->args_parsed);
return VEC_length (stap_probe_arg_s, probe->args_u.vec);
@@ -1060,6 +1080,20 @@ stap_get_arg (struct stap_probe *probe, unsigned n)
return VEC_index (stap_probe_arg_s, probe->args_u.vec, n);
}
+/* Implement the `can_evaluate_probe_arguments' method of probe_ops. */
+
+static int
+stap_can_evaluate_probe_arguments (struct probe *probe_generic)
+{
+ struct stap_probe *stap_probe = (struct stap_probe *) probe_generic;
+ struct gdbarch *gdbarch = stap_probe->p.objfile->gdbarch;
+
+ /* For SystemTap probes, we have to guarantee that the method
+ stap_is_single_operand is defined on gdbarch. If it is not, then it
+ means that argument evaluation is not implemented on this target. */
+ return gdbarch_stap_is_single_operand_p (gdbarch);
+}
+
/* Evaluate the probe's argument N (indexed from 0), returning a value
corresponding to it. Assertion is thrown if N does not exist. */
@@ -1520,6 +1554,7 @@ static const struct probe_ops stap_probe_ops =
stap_get_probes,
stap_relocate,
stap_get_probe_argument_count,
+ stap_can_evaluate_probe_arguments,
stap_evaluate_probe_argument,
stap_compile_to_ax,
stap_set_semaphore,
diff --git a/gdb/symfile.h b/gdb/symfile.h
index c0e367d..c36e6b3 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -315,6 +315,14 @@ struct sym_probe_fns
implement this method as well. */
unsigned (*sym_get_probe_argument_count) (struct probe *probe);
+ /* Return 1 if the probe interface can evaluate the arguments of probe
+ PROBE, zero otherwise. This function can be probe-specific, informing
+ whether only the arguments of PROBE can be evaluated, of generic,
+ informing whether the probe interface is able to evaluate any kind of
+ argument. If you provide an implementation of sym_get_probes, you must
+ implement this method as well. */
+ int (*can_evaluate_probe_arguments) (struct probe *probe);
+
/* Evaluate the Nth argument available to PROBE. PROBE will have
come from a call to this objfile's sym_get_probes method. N will
be between 0 and the number of arguments available to this probe.