]> sourceware.org Git - systemtap.git/commitdiff
nearest probes: allow ENUMERATED and WILDCARD linenos
authorJonathan Lebon <jlebon@redhat.com>
Fri, 20 Feb 2015 18:24:18 +0000 (13:24 -0500)
committerJonathan Lebon <jlebon@redhat.com>
Fri, 27 Feb 2015 14:56:07 +0000 (09:56 -0500)
This commit reverses commit 2ff2868 which added the restriction of only
allowing .nearest probes on ABSOLUTE and RELATIVE linenos. We now allow
this for all lineno types.

WILDCARD lineno types do not need any special handling for .nearest
probes since the resulting linenos are already known to be correct. For
ENUMERATED linenos however, we now must add .nearest handling: for each
lineno enumerated, if we fail to find an address, we check if there is a
nearby lineno we can instead probe.

This commit also fixes failures in the unprivileged_myproc.exp testcase.
Related PRs: PR17906, PR17986.

dwflpp.cxx
tapsets.cxx

index d894889a6723855c4621781583216f59855cbcc8..41863a5f92909e6757bdeb9918d189278765731a 100644 (file)
@@ -1863,12 +1863,46 @@ dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
   else if (lineno_type == WILDCARD)
     collect_all_lines(srcfile, current_funcs, matching_lines);
   else if (lineno_type == ENUMERATED)
-    for (vector<int>::const_iterator it = linenos.begin(); it != linenos.end(); it++)
-      collect_lines_for_single_lineno(srcfile, *it, false, /* is_relative */
-                                      current_funcs, matching_lines);
+    {
+      set<int> collected_linenos;
+      for (vector<int>::const_iterator it  = linenos.begin();
+                                       it != linenos.end(); it++)
+        {
+          // have we already collected this lineno?
+          if (collected_linenos.find(*it) != collected_linenos.end())
+            continue;
+
+          // remember end iterator so we can tell if things were found later
+          lines_t::const_iterator itend = matching_lines.end();
+
+          collect_lines_for_single_lineno(srcfile, *it, false, /* is_relative */
+                                          current_funcs, matching_lines);
+          // add to set if we found LRs
+          if (itend != matching_lines.end())
+            collected_linenos.insert(*it);
+
+          // if we didn't find anything and .nearest is given, then try nearest
+          if (itend == matching_lines.end() && has_nearest)
+            {
+              int nearest_lineno = get_nearest_lineno(srcfile, *it,
+                                                      current_funcs);
+              if (nearest_lineno <= 0) // no valid nearest linenos
+                continue;
+
+              bool new_lineno = collected_linenos.insert(nearest_lineno).second;
+              if (new_lineno)
+                collect_lines_for_single_lineno(srcfile, nearest_lineno,
+                                                false, /* is_relative */
+                                                current_funcs, matching_lines);
+            }
+        }
+    }
 
-  // should we try to collect the nearest line if we didn't collect everything on first try?
-  if (matching_lines.empty() && has_nearest)
+  // should we try to collect the nearest lines if we didn't collect everything
+  // on first try? (ABSOLUTE and RELATIVE only: ENUMERATED handles it already
+  // and WILDCARD doesn't need it)
+  if (matching_lines.empty() && has_nearest && (lineno_type == ABSOLUTE ||
+                                                lineno_type == RELATIVE))
     {
       int lineno = linenos[0];
       if (lineno_type == RELATIVE)
@@ -1877,7 +1911,8 @@ dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
 
       int nearest_lineno = get_nearest_lineno(srcfile, lineno, current_funcs);
       if (nearest_lineno > 0)
-        collect_lines_for_single_lineno(srcfile, nearest_lineno, false, /* is_relative */
+        collect_lines_for_single_lineno(srcfile, nearest_lineno,
+                                        false, /* is_relative */
                                         current_funcs, matching_lines);
     }
 
index 5d8ecf31326ea0332fdf4002d2a6a99bcfdbf289..1efbea3c252b5fb890143cc232b69377afb07e0d 100644 (file)
@@ -1231,11 +1231,6 @@ dwarf_query::parse_function_spec(const string & spec)
               {
                 goto bad;
               }
-
-            // only allow .nearest with ABSOLUTE and RELATIVE linenos
-            if (has_nearest && lineno_type != ABSOLUTE
-                            && lineno_type != RELATIVE)
-              throw SEMANTIC_ERROR(_(".nearest is only valid with absolute or relative line numbers"));
         }
     }
 
@@ -1960,7 +1955,8 @@ query_srcfile_line (Dwarf_Addr addr, int lineno, dwarf_query * q)
           string canon_func = q->final_function_name(i->name, i->decl_file,
                                                      lineno /* NB: not i->decl_line */ );
 
-          if (q->has_nearest)
+          if (q->has_nearest && (q->lineno_type == ABSOLUTE ||
+                                 q->lineno_type == RELATIVE))
             {
               int lineno_nearest = q->linenos[0];
               if (q->lineno_type == RELATIVE)
@@ -1980,7 +1976,8 @@ query_srcfile_line (Dwarf_Addr addr, int lineno, dwarf_query * q)
                            &scope, addr, q);
 
           q->unmount_well_formed_probe_point();
-          if (q->has_nearest)
+          if (q->has_nearest && (q->lineno_type == ABSOLUTE ||
+                                 q->lineno_type == RELATIVE))
             q->unmount_well_formed_probe_point();
         }
     }
This page took 0.052399 seconds and 5 git commands to generate.