2013-07-24 Sergio Durigan Junior <sergiodj@redhat.com>
authorSergio Durigan Junior <sergiodj@redhat.com>
Wed, 24 Jul 2013 19:50:32 +0000 (19:50 +0000)
committerSergio Durigan Junior <sergiodj@redhat.com>
Wed, 24 Jul 2013 19:50:32 +0000 (19:50 +0000)
* 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.

gdb/ChangeLog
gdb/breakpoint.c
gdb/elfread.c
gdb/probe.c
gdb/probe.h
gdb/solib-svr4.c
gdb/stap-probe.c
gdb/symfile.h

index 672fb5ddebf523b6a7f106cc2b528b4a4be5ddfc..2ebf9dbaa76008b913ee0cc84632f4560b84d6b4 100644 (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.
index 4d09b30873aad73863ae1a84f73fa403400c4dd5..1e89407eadd19f1e5430db3256b9ff0ac577e90a 100644 (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;
        }
 
index cfdfe4540f5e44538b6ab881b7578379e98d947e..1aa10d1e384b9dc9c13a38f6d87d31219dcab0e2 100644 (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.  */
index e6508927ac276141963795198e584321b8705d17..c313c38911d0cecf27c5adee6fea091cf743255c 100644 (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)
 {
index de07f506523aa258a3a62fc380c2f2b97c2a9721..dd5387b091bc04fe6ccf5578644e4679ab522e30 100644 (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.  */
 
index ccfd158a9482db77a0e54b8b2451efa29bfdd382..a497c6c546d2a11e6b360d24b312107511dd88f8 100644 (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)
index 1079e3ba497115ec32372551a3d70df535fc1e1f..cbbdf391130b9d4e1754ab8d693d8fe9c1b0b466 100644 (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,
index c0e367d1d14668b5a9130028f09bb03977c17932..c36e6b3737c19b180d5075ced31fe5a102af1d1c 100644 (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.