Blame SOURCES/rhbz1073640.2.patch

f43afa
From 91bb9081f0f2342d2e7df985d448ea9c9ebd34b5 Mon Sep 17 00:00:00 2001
f43afa
From: Lukas Berk <lberk@redhat.com>
f43afa
Date: Fri, 29 Nov 2013 16:34:11 -0500
f43afa
Subject: [PATCH] PR10208 Support probing weak symbols
f43afa
f43afa
*tapsets.cxx - Now always query the symtab (unless there is a pending interrupt
f43afa
	       or dwarf callback error) on a function probe.  We need to be careful
f43afa
	       to check probe point's we've already resolved which will already
f43afa
	       have full debug information and to not place another probe there.
f43afa
	       We've removed the case of probing the symbol table on a statement probe,
f43afa
	       as that code was written specifically for the kernel without userspace
f43afa
	       in mind and was resolving the function the statement resided in (causing
f43afa
	       errors in some cases).
f43afa
f43afa
*list.exp    - Added testcase for weak symbols
f43afa
*last_100_frees.stp   - we use @defined($mem) here because on 64 bit systems, the
f43afa
		        wildcard search takes us through both 64 bit and 32 bit libc
f43afa
		        (which doesn't have debuginfo), this means the probe point
f43afa
		        resolved from the 32 bit library has no context info
f43afa
*mutex-contention.stp - ditto but for @defined($mutex) and @defined($rwlock)
f43afa
---
f43afa
 tapsets.cxx                                        | 94 ++++++++++++----------
f43afa
 testsuite/systemtap.base/list.exp                  |  4 +
f43afa
 .../systemtap.examples/memory/last_100_frees.stp   | 12 ++-
f43afa
 .../process/mutex-contention.stp                   | 14 +++-
f43afa
 4 files changed, 74 insertions(+), 50 deletions(-)
f43afa
f43afa
diff --git a/tapsets.cxx b/tapsets.cxx
f43afa
index 7927106..4e05d4a 100644
f43afa
--- a/tapsets.cxx
f43afa
+++ b/tapsets.cxx
f43afa
@@ -989,6 +989,40 @@ dwarf_query::query_module_dwarf()
f43afa
 static void query_func_info (Dwarf_Addr entrypc, func_info & fi,
f43afa
 							dwarf_query * q);
f43afa
 
f43afa
+static void
f43afa
+query_symtab_func_info (func_info & fi, dwarf_query * q)
f43afa
+{
f43afa
+  assert(null_die(&fi.die));
f43afa
+
f43afa
+  Dwarf_Addr addr = fi.addr;
f43afa
+
f43afa
+  // Now compensate for the dw bias because the addresses come
f43afa
+  // from dwfl_module_symtab, so fi->addr is NOT a normal dw address.
f43afa
+  q->dw.get_module_dwarf(false, false);
f43afa
+  addr -= q->dw.module_bias;
f43afa
+
f43afa
+  // If there are already probes in this module, lets not duplicate.
f43afa
+  // This can come from other weak symbols/aliases or existing
f43afa
+  // matches from Dwarf DIE functions.
f43afa
+  if (q->alias_dupes.size() > 0)
f43afa
+    {
f43afa
+      for (set<Dwarf_Addr>::iterator it=q->alias_dupes.begin(); it!=q->alias_dupes.end(); ++it)
f43afa
+	{
f43afa
+	  // If we've already got a probe at that pc, skip it
f43afa
+	  if (*it == addr)
f43afa
+	    return;
f43afa
+	  if (*it != addr && ++it==q->alias_dupes.end())
f43afa
+	    {
f43afa
+	      // Build a probe at this point
f43afa
+	      query_func_info(addr, fi, q);
f43afa
+	      return;
f43afa
+	    }
f43afa
+	}
f43afa
+    }
f43afa
+  else
f43afa
+    query_func_info(addr,fi,q);
f43afa
+}
f43afa
+
f43afa
 void
f43afa
 dwarf_query::query_module_symtab()
f43afa
 {
f43afa
@@ -1014,15 +1048,6 @@ dwarf_query::query_module_symtab()
f43afa
       assert(spec_type == function_alone);
f43afa
       if (dw.name_has_wildcard(function_str_val))
f43afa
         {
f43afa
-          // Until we augment the blacklist sufficently...
f43afa
-	  if ((function_str_val.find_first_not_of("*?") == string::npos) && !dw.has_gnu_debugdata())
f43afa
-            {
f43afa
-              // e.g., kernel.function("*")
f43afa
-              cerr << _F("Error: Pattern '%s' matches every single "
f43afa
-                         "instruction address in the symbol table,\n"
f43afa
-                         "some of which aren't even functions.\n", function_str_val.c_str()) << endl;
f43afa
-              return;
f43afa
-            }
f43afa
           symbol_table::iterator_t iter;
f43afa
           for (iter = sym_table->map_by_addr.begin();
f43afa
                iter != sym_table->map_by_addr.end();
f43afa
@@ -1032,42 +1057,16 @@ dwarf_query::query_module_symtab()
f43afa
               if (!null_die(&fi->die))
f43afa
                 continue;       // already handled in query_module_dwarf()
f43afa
               if (dw.function_name_matches_pattern(fi->name, function_str_val))
f43afa
-                query_func_info(fi->addr, *fi, this);
f43afa
+                query_symtab_func_info(*fi, this);
f43afa
             }
f43afa
         }
f43afa
       else
f43afa
         {
f43afa
           fi = sym_table->lookup_symbol(function_str_val);
f43afa
           if (fi && !fi->descriptor && null_die(&fi->die))
f43afa
-            query_func_info(fi->addr, *fi, this);
f43afa
+	     query_symtab_func_info(*fi, this);
f43afa
         }
f43afa
     }
f43afa
-  else
f43afa
-    {
f43afa
-      assert(has_function_num || has_statement_num);
f43afa
-      // Find the "function" in which the indicated address resides.
f43afa
-      Dwarf_Addr addr =
f43afa
-      		(has_function_num ? function_num_val : statement_num_val);
f43afa
-      fi = sym_table->get_func_containing_address(addr);
f43afa
-
f43afa
-      if (!fi)
f43afa
-        {
f43afa
-          sess.print_warning(_F("address %#" PRIx64 " out of range for module %s",
f43afa
-                  addr, dw.module_name.c_str()));
f43afa
-          return;
f43afa
-        }
f43afa
-      if (!null_die(&fi->die))
f43afa
-        {
f43afa
-          // addr looks like it's in the compilation unit containing
f43afa
-          // the indicated function, but query_module_dwarf() didn't
f43afa
-          // match addr to any compilation unit, so addr must be
f43afa
-          // above that cu's address range.
f43afa
-          sess.print_warning(_F("address %#" PRIx64 " maps to no known compilation unit in module %s",
f43afa
-                       addr, dw.module_name.c_str()));
f43afa
-          return;
f43afa
-        }
f43afa
-      query_func_info(fi->addr, *fi, this);
f43afa
-    }
f43afa
 }
f43afa
 
f43afa
 void
f43afa
@@ -1092,10 +1091,11 @@ dwarf_query::handle_query_module()
f43afa
   if (dw.mod_info->dwarf_status == info_present)
f43afa
     query_module_dwarf();
f43afa
 
f43afa
-  // Consult the symbol table if we haven't found all we're looking for.
f43afa
-  // asm functions can show up in the symbol table but not in dwarf,
f43afa
-  // or if we want to check the .gnu_debugdata section
f43afa
-  if ((sess.consult_symtab || dw.has_gnu_debugdata()) && !query_done)
f43afa
+  // Consult the symbol table, asm and weak functions can show up
f43afa
+  // in the symbol table but not in dwarf and minidebuginfo is
f43afa
+  // located in the gnu_debugdata section, alias_dupes checking
f43afa
+  // is done before adding any probe points
f43afa
+  if (!query_done && !pending_interrupts)
f43afa
     query_module_symtab();
f43afa
 }
f43afa
 
f43afa
@@ -1252,7 +1252,7 @@ dwarf_query::add_probe_point(const string& dw_funcname,
f43afa
 
f43afa
   // If we originally used the linkage name, then let's call it that way
f43afa
   const char* linkage_name;
f43afa
-  if (scope_die && startswith (this->function, "_Z")
f43afa
+  if (!null_die(scope_die) && startswith (this->function, "_Z")
f43afa
       && (linkage_name = dwarf_linkage_name (scope_die)))
f43afa
     funcname = linkage_name;
f43afa
 
f43afa
@@ -1954,8 +1954,14 @@ dwarf_query::query_module_functions ()
f43afa
       inline_dupes.clear();
f43afa
 
f43afa
       // Run the query again on the individual CUs
f43afa
-      for (vector<Dwarf_Die>::iterator i = cus.begin(); i != cus.end(); ++i)
f43afa
-        query_cu(&*i, this);
f43afa
+      for (vector<Dwarf_Die>::iterator i = cus.begin(); i != cus.end(); ++i){
f43afa
+        rc = query_cu(&*i, this);
f43afa
+	if (rc != DWARF_CB_OK)
f43afa
+	  {
f43afa
+	    query_done = true;
f43afa
+	    return;
f43afa
+	  }
f43afa
+      }
f43afa
     }
f43afa
   catch (const semantic_error& e)
f43afa
     {
f43afa
diff --git a/testsuite/systemtap.base/list.exp b/testsuite/systemtap.base/list.exp
f43afa
index 1aa97f8..bae7e0e 100644
f43afa
--- a/testsuite/systemtap.base/list.exp
f43afa
+++ b/testsuite/systemtap.base/list.exp
f43afa
@@ -81,3 +81,7 @@ test_list copy_flags-inline {kernel.function("copy_flags@kernel/fork.c").inline}
f43afa
 # PR15587: make sure we have line numbers on statements of an inline function
f43afa
 test_list copy_flags-statement {kernel.statement("copy_flags@kernel/fork.c:*")} \
f43afa
     {kernel.statement."copy_flags@kernel/fork.c:\d+".\r\n}
f43afa
+
f43afa
+# PR10208: ensure we can probe weak symbols
f43afa
+test_uprobes_list function-weak {process("/lib*/libc.so.*").function("chmod")} \
f43afa
+    {process.*.function."chmod".\r\n}
f43afa
diff --git a/testsuite/systemtap.examples/memory/last_100_frees.stp b/testsuite/systemtap.examples/memory/last_100_frees.stp
f43afa
index 06d7acf..4ca43b5 100755
f43afa
--- a/testsuite/systemtap.examples/memory/last_100_frees.stp
f43afa
+++ b/testsuite/systemtap.examples/memory/last_100_frees.stp
f43afa
@@ -1,10 +1,16 @@
f43afa
-#! /usr/bin/env stap 
f43afa
+#! /usr/bin/env stap
f43afa
 
f43afa
 global bt%[100]
f43afa
 
f43afa
 probe process("/lib*/libc.so.*").function("free") {
f43afa
-  bt[execname(),tid(),$mem,sprint_ubacktrace()]
f43afa
-    <<< local_clock_ns()
f43afa
+  // we use @defined($mem) here because on 64 bit systems, the
f43afa
+  // wildcard search takes us through both 64 bit and 32 bit
f43afa
+  // libc (which doesn't have debuginfo), this means the probe
f43afa
+  // point resolved from the 32 bit library has no context info
f43afa
+  if (@defined($mem)) {
f43afa
+    bt[execname(),tid(),$mem,sprint_ubacktrace()]
f43afa
+      <<< local_clock_ns()
f43afa
+  }
f43afa
   // Any monotonically increasing expression would do.
f43afa
   // With some arbitrary expression or constant instead,
f43afa
   // at worst we get the last 100ish results out of order.
f43afa
diff --git a/testsuite/systemtap.examples/process/mutex-contention.stp b/testsuite/systemtap.examples/process/mutex-contention.stp
f43afa
index 669618e..f418754 100755
f43afa
--- a/testsuite/systemtap.examples/process/mutex-contention.stp
f43afa
+++ b/testsuite/systemtap.examples/process/mutex-contention.stp
f43afa
@@ -71,17 +71,25 @@ function show_contention(mutex, stack, type)
f43afa
   }
f43afa
 }
f43afa
 
f43afa
+// we use @defined($muex) and @defined($rwlock) here because
f43afa
+// on 64 bit systems, the wildcard search takes us through
f43afa
+// both 64 bit and 32 bit libc (which doesn't have debuginfo),
f43afa
+// this means the probe point resolved from the 32 bit library
f43afa
+// has no context info
f43afa
 probe process("/lib*/libc.so*").function("pthread_mutex_init")
f43afa
 {
f43afa
-  process_mutex_init($mutex, probefunc())
f43afa
+  if(@defined($mutex))
f43afa
+    process_mutex_init($mutex, probefunc())
f43afa
 }
f43afa
 probe process("/lib*/libpthread.so*").function("__pthread_mutex_init")
f43afa
 {
f43afa
-  process_mutex_init($mutex, probefunc())
f43afa
+  if(@defined($mutex))
f43afa
+    process_mutex_init($mutex, probefunc())
f43afa
 }
f43afa
 probe process("/lib*/libpthread.so*").function("__pthread_rwlock_init")
f43afa
 {
f43afa
-  process_mutex_init($rwlock, probefunc())
f43afa
+  if(@defined($rwlock))
f43afa
+    process_mutex_init($rwlock, probefunc())
f43afa
 }
f43afa
 
f43afa
 probe syscall.futex.return
f43afa
-- 
f43afa
1.8.3.1
f43afa