]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
breakpoint_re_set probes
authorPedro Alves <palves@redhat.com>
Fri, 1 Apr 2016 14:55:32 +0000 (15:55 +0100)
committerPedro Alves <palves@redhat.com>
Mon, 19 Sep 2016 14:44:42 +0000 (15:44 +0100)
gdb/break-catch-throw.c
gdb/breakpoint.c
gdb/probe.c
gdb/probe.h

index efaad3acbd55daba07e492251acc21581e8c44ba..ecc8bcdda7a2887f194a7445caa3238fc69d6610 100644 (file)
@@ -212,12 +212,7 @@ re_set_exception_catchpoint (struct breakpoint *self,
   struct cleanup *cleanup;
   enum exception_event_kind kind = classify_exception_breakpoint (self);
   struct event_location *location;
-  struct sym_search_scope pspace_scope = null_search_scope ();
-  struct program_space *filter_pspace = search_scope->pspace;
-
-  /* Re-set in the whole pspace for now.  */
-  pspace_scope.pspace = search_scope->pspace;
-  search_scope = &pspace_scope;
+  struct sym_search_scope pspace_search_scope;
 
   /* We first try to use the probe interface.  */
   TRY
@@ -225,13 +220,28 @@ re_set_exception_catchpoint (struct breakpoint *self,
       location
        = new_probe_location (exception_functions[kind].probe);
       cleanup = make_cleanup_delete_event_location (location);
-      sals = parse_probes (location, filter_pspace, NULL);
+      sals = parse_probes (location, search_scope, NULL);
       do_cleanups (cleanup);
     }
   CATCH (e, RETURN_MASK_ERROR)
     {
       /* Using the probe interface failed.  Let's fallback to the normal
         catchpoint mode.  */
+
+      /* However, we may have already found a probe in another
+        objfile.  In that case, leave it be.  */
+      if (search_scope->objfile != NULL)
+       {
+         struct bp_location *l;
+
+         for (l = self->loc; l != NULL; l = l->next)
+           {
+             if (l->pspace == search_scope->pspace
+                 && l->sal.probe != NULL)
+               return;
+           }
+       }
+
       TRY
        {
          struct explicit_location explicit_loc;
@@ -255,6 +265,22 @@ re_set_exception_catchpoint (struct breakpoint *self,
     }
   END_CATCH
 
+  /* If we found a probe, remove all by-symbol locations
+     (__cxa_begin_catch, etc.) we may have found earlier on other
+     objfiles of the same progspace.  E.g., if you set a catchpoint
+     before the program is running, we'll find __cxa_begin_catch@plt
+     in the main executable.  Then when the program starts, we'll find
+     the real __cxa_begin_catch text minsym in
+     /usr/lib/debug/usr/lib64/libstdc++.so.debug, and then only later
+     will we find the probe when /lib64/libstdc++.so.6 is finally
+     loaded.  */
+  if (sals.nelts == 1 && sals.sals[0].probe != NULL && search_scope->objfile != NULL)
+    {
+      pspace_search_scope = null_search_scope ();
+      pspace_search_scope.pspace = search_scope->pspace;
+      search_scope = &pspace_search_scope;
+    }
+
   cleanup = make_cleanup (xfree, sals.sals);
   update_breakpoint_locations (self, search_scope, sals, sals_end);
   do_cleanups (cleanup);
index afce9d314b016e2d86bc01eb8c11b4223a9694e2..8faea5813c31af0094d656fd8b3c73d4b54698b3 100644 (file)
@@ -13492,8 +13492,9 @@ bkpt_probe_create_sals_from_location (const struct event_location *location,
                                      enum bptype type_wanted)
 {
   struct linespec_sals lsal;
+  struct sym_search_scope search_scope = null_search_scope ();
 
-  lsal.sals = parse_probes (location, NULL, canonical);
+  lsal.sals = parse_probes (location, &search_scope, canonical);
   lsal.canonical = xstrdup (event_location_to_string (canonical->location));
   VEC_safe_push (linespec_sals, canonical->sals, &lsal);
 }
@@ -13504,7 +13505,7 @@ bkpt_probe_decode_location (struct breakpoint *b,
                            struct sym_search_scope *search_scope,
                            struct symtabs_and_lines *sals)
 {
-  *sals = parse_probes (location, search_scope->pspace, NULL);
+  *sals = parse_probes (location, search_scope, NULL);
   if (!sals->sals)
     error (_("probe not found"));
 }
index 285f4e128903e0cd2131d1ecf12c8d462590311e..342a093798742f9410439081d9cab762ee477331 100644 (file)
@@ -43,62 +43,57 @@ DEF_VEC_O (bound_probe_s);
 \f
 
 /* A helper for parse_probes that decodes a probe specification in
-   SEARCH_PSPACE.  It appends matching SALs to RESULT.  */
+   OBJFILE.  It appends matching SALs to RESULT.  */
 
 static void
-parse_probes_in_pspace (const struct probe_ops *probe_ops,
-                       struct program_space *search_pspace,
-                       const char *objfile_namestr,
-                       const char *provider,
-                       const char *name,
-                       struct symtabs_and_lines *result)
+parse_probes_in_objfile (const struct probe_ops *probe_ops,
+                        struct objfile *objfile,
+                        const char *objfile_namestr,
+                        const char *provider,
+                        const char *name,
+                        struct symtabs_and_lines *result)
 {
-  struct objfile *objfile;
-
-  ALL_PSPACE_OBJFILES (search_pspace, objfile)
-    {
-      VEC (probe_p) *probes;
-      struct probe *probe;
-      int ix;
+  VEC (probe_p) *probes;
+  struct probe *probe;
+  int ix;
 
-      if (!objfile->sf || !objfile->sf->sym_probe_fns)
-       continue;
+  if (!objfile->sf || !objfile->sf->sym_probe_fns)
+    return;
 
-      if (objfile_namestr
-         && FILENAME_CMP (objfile_name (objfile), objfile_namestr) != 0
-         && FILENAME_CMP (lbasename (objfile_name (objfile)),
-                          objfile_namestr) != 0)
-       continue;
+  if (objfile_namestr
+      && FILENAME_CMP (objfile_name (objfile), objfile_namestr) != 0
+      && FILENAME_CMP (lbasename (objfile_name (objfile)),
+                      objfile_namestr) != 0)
+    return;
 
-      probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
+  probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
 
-      for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
-       {
-         struct symtab_and_line *sal;
+  for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
+    {
+      struct symtab_and_line *sal;
 
-         if (probe_ops != &probe_ops_any && probe->pops != probe_ops)
-           continue;
+      if (probe_ops != &probe_ops_any && probe->pops != probe_ops)
+       continue;
 
-         if (provider && strcmp (probe->provider, provider) != 0)
-           continue;
+      if (provider && strcmp (probe->provider, provider) != 0)
+       continue;
 
-         if (strcmp (probe->name, name) != 0)
-           continue;
+      if (strcmp (probe->name, name) != 0)
+       continue;
 
-         ++result->nelts;
-         result->sals = XRESIZEVEC (struct symtab_and_line, result->sals,
-                                    result->nelts);
-         sal = &result->sals[result->nelts - 1];
+      ++result->nelts;
+      result->sals = XRESIZEVEC (struct symtab_and_line, result->sals,
+                                result->nelts);
+      sal = &result->sals[result->nelts - 1];
 
-         init_sal (sal);
+      init_sal (sal);
 
-         sal->pc = get_probe_address (probe, objfile);
-         sal->explicit_pc = 1;
-         sal->section = find_pc_overlay (sal->pc);
-         sal->pspace = search_pspace;
-         sal->probe = probe;
-         sal->objfile = objfile;
-       }
+      sal->pc = get_probe_address (probe, objfile);
+      sal->explicit_pc = 1;
+      sal->section = find_pc_overlay (sal->pc);
+      sal->pspace = objfile->pspace;
+      sal->probe = probe;
+      sal->objfile = objfile;
     }
 }
 
@@ -106,7 +101,7 @@ parse_probes_in_pspace (const struct probe_ops *probe_ops,
 
 struct symtabs_and_lines
 parse_probes (const struct event_location *location,
-             struct program_space *search_pspace,
+             struct sym_search_scope *search_scope,
              struct linespec_result *canonical)
 {
   char *arg_end, *arg;
@@ -115,6 +110,8 @@ parse_probes (const struct event_location *location,
   struct symtabs_and_lines result;
   const struct probe_ops *probe_ops;
   const char *arg_start, *cs;
+  struct program_space *pspace_iter;
+  struct objfile *objfile_iter;
 
   result.sals = NULL;
   result.nelts = 0;
@@ -174,18 +171,10 @@ parse_probes (const struct event_location *location,
   if (objfile_namestr && *objfile_namestr == '\0')
     error (_("invalid objfile name"));
 
-  if (search_pspace != NULL)
+  ALL_SEARCH_SCOPE_OBJFILES (search_scope, pspace_iter, objfile_iter)
     {
-      parse_probes_in_pspace (probe_ops, search_pspace, objfile_namestr,
-                             provider, name, &result);
-    }
-  else
-    {
-      struct program_space *pspace;
-
-      ALL_PSPACES (pspace)
-       parse_probes_in_pspace (probe_ops, pspace, objfile_namestr,
-                               provider, name, &result);
+      parse_probes_in_objfile (probe_ops, objfile_iter, objfile_namestr,
+                              provider, name, &result);
     }
 
   if (result.nelts == 0)
index 1e15328ffb062e255ff8de82fa0e22fc2d0c69ed..203d9ce0f3b8ad5372a84b9aea32285f0f82b291 100644 (file)
@@ -21,6 +21,7 @@
 #define PROBE_H 1
 
 struct event_location;
+struct sym_search_scope;
 
 #include "gdb_vecs.h"
 
@@ -228,7 +229,7 @@ struct bound_probe
    symtabs_and_lines object and updates LOC or throws an error.  */
 
 extern struct symtabs_and_lines parse_probes (const struct event_location *loc,
-                                             struct program_space *pspace,
+                                             struct sym_search_scope *search_scope,
                                              struct linespec_result *canon);
 
 /* Helper function to register the proper probe_ops to a newly created probe.