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:
parent
df71cb5cbf
commit
25f9533e51
8 changed files with 161 additions and 10 deletions
|
@ -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>
|
2013-07-24 Luis Machado <lgustavo@codesourcery.com>
|
||||||
|
|
||||||
* Makefile.in (SFILES): Add common/target-common.c.
|
* Makefile.in (SFILES): Add common/target-common.c.
|
||||||
|
|
|
@ -3194,8 +3194,23 @@ create_longjmp_master_breakpoint (void)
|
||||||
|
|
||||||
if (!bp_objfile_data->longjmp_searched)
|
if (!bp_objfile_data->longjmp_searched)
|
||||||
{
|
{
|
||||||
bp_objfile_data->longjmp_probes
|
VEC (probe_p) *ret;
|
||||||
= find_probes_in_objfile (objfile, "libc", "longjmp");
|
|
||||||
|
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;
|
bp_objfile_data->longjmp_searched = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3336,8 +3351,24 @@ create_exception_master_breakpoint (void)
|
||||||
/* We prefer the SystemTap probe point if it exists. */
|
/* We prefer the SystemTap probe point if it exists. */
|
||||||
if (!bp_objfile_data->exception_searched)
|
if (!bp_objfile_data->exception_searched)
|
||||||
{
|
{
|
||||||
bp_objfile_data->exception_probes
|
VEC (probe_p) *ret;
|
||||||
= find_probes_in_objfile (objfile, "libgcc", "unwind");
|
|
||||||
|
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;
|
bp_objfile_data->exception_searched = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1643,6 +1643,15 @@ elf_get_probe_argument_count (struct probe *probe)
|
||||||
return probe->pops->get_probe_argument_count (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
|
/* Implementation of `sym_evaluate_probe_argument', as documented in
|
||||||
symfile.h. */
|
symfile.h. */
|
||||||
|
|
||||||
|
@ -1700,11 +1709,12 @@ probe_key_free (struct objfile *objfile, void *d)
|
||||||
|
|
||||||
static const struct sym_probe_fns elf_probe_fns =
|
static const struct sym_probe_fns elf_probe_fns =
|
||||||
{
|
{
|
||||||
elf_get_probes, /* sym_get_probes */
|
elf_get_probes, /* sym_get_probes */
|
||||||
elf_get_probe_argument_count, /* sym_get_probe_argument_count */
|
elf_get_probe_argument_count, /* sym_get_probe_argument_count */
|
||||||
elf_evaluate_probe_argument, /* sym_evaluate_probe_argument */
|
elf_can_evaluate_probe_arguments, /* sym_can_evaluate_probe_arguments */
|
||||||
elf_compile_to_ax, /* sym_compile_to_ax */
|
elf_evaluate_probe_argument, /* sym_evaluate_probe_argument */
|
||||||
elf_symfile_relocate_probe, /* sym_relocate_probe */
|
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. */
|
/* Register that we are able to handle ELF object file formats. */
|
||||||
|
|
17
gdb/probe.c
17
gdb/probe.c
|
@ -628,6 +628,23 @@ get_probe_argument_count (struct probe *probe)
|
||||||
|
|
||||||
/* See comments in probe.h. */
|
/* 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 *
|
struct value *
|
||||||
evaluate_probe_argument (struct probe *probe, unsigned n)
|
evaluate_probe_argument (struct probe *probe, unsigned n)
|
||||||
{
|
{
|
||||||
|
|
12
gdb/probe.h
12
gdb/probe.h
|
@ -73,6 +73,12 @@ struct probe_ops
|
||||||
|
|
||||||
unsigned (*get_probe_argument_count) (struct probe *probe);
|
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
|
/* Evaluate the Nth argument from the PROBE, returning a value
|
||||||
corresponding to it. The argument number is represented N. */
|
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);
|
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
|
/* Evaluate argument N of the specified probe. N must be between 0
|
||||||
inclusive and get_probe_argument_count exclusive. */
|
inclusive and get_probe_argument_count exclusive. */
|
||||||
|
|
||||||
|
|
|
@ -1978,12 +1978,14 @@ svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch,
|
||||||
{
|
{
|
||||||
VEC (probe_p) *probes[NUM_PROBES];
|
VEC (probe_p) *probes[NUM_PROBES];
|
||||||
int all_probes_found = 1;
|
int all_probes_found = 1;
|
||||||
|
int checked_can_use_probe_arguments = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset (probes, 0, sizeof (probes));
|
memset (probes, 0, sizeof (probes));
|
||||||
for (i = 0; i < NUM_PROBES; i++)
|
for (i = 0; i < NUM_PROBES; i++)
|
||||||
{
|
{
|
||||||
const char *name = probe_info[i].name;
|
const char *name = probe_info[i].name;
|
||||||
|
struct probe *p;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
|
||||||
/* Fedora 17 and Red Hat Enterprise Linux 6.2-6.4
|
/* 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;
|
all_probes_found = 0;
|
||||||
break;
|
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)
|
if (all_probes_found)
|
||||||
|
|
|
@ -1009,7 +1009,27 @@ stap_get_probe_argument_count (struct probe *probe_generic)
|
||||||
gdb_assert (probe_generic->pops == &stap_probe_ops);
|
gdb_assert (probe_generic->pops == &stap_probe_ops);
|
||||||
|
|
||||||
if (!probe->args_parsed)
|
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);
|
gdb_assert (probe->args_parsed);
|
||||||
return VEC_length (stap_probe_arg_s, probe->args_u.vec);
|
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);
|
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
|
/* Evaluate the probe's argument N (indexed from 0), returning a value
|
||||||
corresponding to it. Assertion is thrown if N does not exist. */
|
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_get_probes,
|
||||||
stap_relocate,
|
stap_relocate,
|
||||||
stap_get_probe_argument_count,
|
stap_get_probe_argument_count,
|
||||||
|
stap_can_evaluate_probe_arguments,
|
||||||
stap_evaluate_probe_argument,
|
stap_evaluate_probe_argument,
|
||||||
stap_compile_to_ax,
|
stap_compile_to_ax,
|
||||||
stap_set_semaphore,
|
stap_set_semaphore,
|
||||||
|
|
|
@ -315,6 +315,14 @@ struct sym_probe_fns
|
||||||
implement this method as well. */
|
implement this method as well. */
|
||||||
unsigned (*sym_get_probe_argument_count) (struct probe *probe);
|
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
|
/* Evaluate the Nth argument available to PROBE. PROBE will have
|
||||||
come from a call to this objfile's sym_get_probes method. N will
|
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.
|
be between 0 and the number of arguments available to this probe.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue