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.
This commit is contained in:
Sergio Durigan Junior 2013-07-24 19:50:32 +00:00
parent df71cb5cbf
commit 25f9533e51
8 changed files with 161 additions and 10 deletions

View file

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

View file

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

View file

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

View file

@ -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)
{

View file

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

View file

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

View file

@ -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,

View file

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