]> sourceware.org Git - systemtap.git/commitdiff
PR10208 Support probing weak symbols
authorLukas Berk <lberk@redhat.com>
Fri, 29 Nov 2013 21:34:11 +0000 (16:34 -0500)
committerLukas Berk <lberk@redhat.com>
Fri, 29 Nov 2013 21:34:11 +0000 (16:34 -0500)
*tapsets.cxx - Now always query the symtab (unless there is a pending interrupt
       or dwarf callback error) on a function probe.  We need to be careful
       to check probe point's we've already resolved which will already
       have full debug information and to not place another probe there.
       We've removed the case of probing the symbol table on a statement probe,
       as that code was written specifically for the kernel without userspace
       in mind and was resolving the function the statement resided in (causing
       errors in some cases).

*list.exp    - Added testcase for weak symbols
*last_100_frees.stp   - we use @defined($mem) here because on 64 bit systems, the
        wildcard search takes us through both 64 bit and 32 bit libc
        (which doesn't have debuginfo), this means the probe point
        resolved from the 32 bit library has no context info
*mutex-contention.stp - ditto but for @defined($mutex) and @defined($rwlock)

tapsets.cxx
testsuite/systemtap.base/list.exp
testsuite/systemtap.examples/memory/last_100_frees.stp
testsuite/systemtap.examples/process/mutex-contention.stp

index 7927106b4cf010e01e78db23cbfd5001afe0b5cb..4e05d4a50efd0821d162d860f1e0da6bd4b56f04 100644 (file)
@@ -989,6 +989,40 @@ dwarf_query::query_module_dwarf()
 static void query_func_info (Dwarf_Addr entrypc, func_info & fi,
                                                        dwarf_query * q);
 
+static void
+query_symtab_func_info (func_info & fi, dwarf_query * q)
+{
+  assert(null_die(&fi.die));
+
+  Dwarf_Addr addr = fi.addr;
+
+  // Now compensate for the dw bias because the addresses come
+  // from dwfl_module_symtab, so fi->addr is NOT a normal dw address.
+  q->dw.get_module_dwarf(false, false);
+  addr -= q->dw.module_bias;
+
+  // If there are already probes in this module, lets not duplicate.
+  // This can come from other weak symbols/aliases or existing
+  // matches from Dwarf DIE functions.
+  if (q->alias_dupes.size() > 0)
+    {
+      for (set<Dwarf_Addr>::iterator it=q->alias_dupes.begin(); it!=q->alias_dupes.end(); ++it)
+       {
+         // If we've already got a probe at that pc, skip it
+         if (*it == addr)
+           return;
+         if (*it != addr && ++it==q->alias_dupes.end())
+           {
+             // Build a probe at this point
+             query_func_info(addr, fi, q);
+             return;
+           }
+       }
+    }
+  else
+    query_func_info(addr,fi,q);
+}
+
 void
 dwarf_query::query_module_symtab()
 {
@@ -1014,15 +1048,6 @@ dwarf_query::query_module_symtab()
       assert(spec_type == function_alone);
       if (dw.name_has_wildcard(function_str_val))
         {
-          // Until we augment the blacklist sufficently...
-         if ((function_str_val.find_first_not_of("*?") == string::npos) && !dw.has_gnu_debugdata())
-            {
-              // e.g., kernel.function("*")
-              cerr << _F("Error: Pattern '%s' matches every single "
-                         "instruction address in the symbol table,\n"
-                         "some of which aren't even functions.\n", function_str_val.c_str()) << endl;
-              return;
-            }
           symbol_table::iterator_t iter;
           for (iter = sym_table->map_by_addr.begin();
                iter != sym_table->map_by_addr.end();
@@ -1032,41 +1057,15 @@ dwarf_query::query_module_symtab()
               if (!null_die(&fi->die))
                 continue;       // already handled in query_module_dwarf()
               if (dw.function_name_matches_pattern(fi->name, function_str_val))
-                query_func_info(fi->addr, *fi, this);
+                query_symtab_func_info(*fi, this);
             }
         }
       else
         {
           fi = sym_table->lookup_symbol(function_str_val);
           if (fi && !fi->descriptor && null_die(&fi->die))
-            query_func_info(fi->addr, *fi, this);
-        }
-    }
-  else
-    {
-      assert(has_function_num || has_statement_num);
-      // Find the "function" in which the indicated address resides.
-      Dwarf_Addr addr =
-               (has_function_num ? function_num_val : statement_num_val);
-      fi = sym_table->get_func_containing_address(addr);
-
-      if (!fi)
-        {
-          sess.print_warning(_F("address %#" PRIx64 " out of range for module %s",
-                  addr, dw.module_name.c_str()));
-          return;
-        }
-      if (!null_die(&fi->die))
-        {
-          // addr looks like it's in the compilation unit containing
-          // the indicated function, but query_module_dwarf() didn't
-          // match addr to any compilation unit, so addr must be
-          // above that cu's address range.
-          sess.print_warning(_F("address %#" PRIx64 " maps to no known compilation unit in module %s",
-                       addr, dw.module_name.c_str()));
-          return;
+            query_symtab_func_info(*fi, this);
         }
-      query_func_info(fi->addr, *fi, this);
     }
 }
 
@@ -1092,10 +1091,11 @@ dwarf_query::handle_query_module()
   if (dw.mod_info->dwarf_status == info_present)
     query_module_dwarf();
 
-  // Consult the symbol table if we haven't found all we're looking for.
-  // asm functions can show up in the symbol table but not in dwarf,
-  // or if we want to check the .gnu_debugdata section
-  if ((sess.consult_symtab || dw.has_gnu_debugdata()) && !query_done)
+  // Consult the symbol table, asm and weak functions can show up
+  // in the symbol table but not in dwarf and minidebuginfo is
+  // located in the gnu_debugdata section, alias_dupes checking
+  // is done before adding any probe points
+  if (!query_done && !pending_interrupts)
     query_module_symtab();
 }
 
@@ -1252,7 +1252,7 @@ dwarf_query::add_probe_point(const string& dw_funcname,
 
   // If we originally used the linkage name, then let's call it that way
   const char* linkage_name;
-  if (scope_die && startswith (this->function, "_Z")
+  if (!null_die(scope_die) && startswith (this->function, "_Z")
       && (linkage_name = dwarf_linkage_name (scope_die)))
     funcname = linkage_name;
 
@@ -1954,8 +1954,14 @@ dwarf_query::query_module_functions ()
       inline_dupes.clear();
 
       // Run the query again on the individual CUs
-      for (vector<Dwarf_Die>::iterator i = cus.begin(); i != cus.end(); ++i)
-        query_cu(&*i, this);
+      for (vector<Dwarf_Die>::iterator i = cus.begin(); i != cus.end(); ++i){
+        rc = query_cu(&*i, this);
+       if (rc != DWARF_CB_OK)
+         {
+           query_done = true;
+           return;
+         }
+      }
     }
   catch (const semantic_error& e)
     {
index 1aa97f830e6922978451aefc33227bb2651df7b8..bae7e0ec1ad40f6b192ec2ad5dc4d5d9119a5a26 100644 (file)
@@ -81,3 +81,7 @@ test_list copy_flags-inline {kernel.function("copy_flags@kernel/fork.c").inline}
 # PR15587: make sure we have line numbers on statements of an inline function
 test_list copy_flags-statement {kernel.statement("copy_flags@kernel/fork.c:*")} \
     {kernel.statement."copy_flags@kernel/fork.c:\d+".\r\n}
+
+# PR10208: ensure we can probe weak symbols
+test_uprobes_list function-weak {process("/lib*/libc.so.*").function("chmod")} \
+    {process.*.function."chmod".\r\n}
index 06d7acf750c76f27734fea727398aa4a48e6d767..4ca43b5cc23d612b740bad346f8e00a5be669e5d 100755 (executable)
@@ -1,10 +1,16 @@
-#! /usr/bin/env stap 
+#! /usr/bin/env stap
 
 global bt%[100]
 
 probe process("/lib*/libc.so.*").function("free") {
-  bt[execname(),tid(),$mem,sprint_ubacktrace()]
-    <<< local_clock_ns()
+  // we use @defined($mem) here because on 64 bit systems, the
+  // wildcard search takes us through both 64 bit and 32 bit
+  // libc (which doesn't have debuginfo), this means the probe
+  // point resolved from the 32 bit library has no context info
+  if (@defined($mem)) {
+    bt[execname(),tid(),$mem,sprint_ubacktrace()]
+      <<< local_clock_ns()
+  }
   // Any monotonically increasing expression would do.
   // With some arbitrary expression or constant instead,
   // at worst we get the last 100ish results out of order.
index 669618e7acecaddeb835cf6d18fd24d9216f901c..f418754bce7fec6f12b6f8c06c7a6c6e33aee4dc 100755 (executable)
@@ -71,17 +71,25 @@ function show_contention(mutex, stack, type)
   }
 }
 
+// we use @defined($muex) and @defined($rwlock) here because
+// on 64 bit systems, the wildcard search takes us through
+// both 64 bit and 32 bit libc (which doesn't have debuginfo),
+// this means the probe point resolved from the 32 bit library
+// has no context info
 probe process("/lib*/libc.so*").function("pthread_mutex_init")
 {
-  process_mutex_init($mutex, probefunc())
+  if(@defined($mutex))
+    process_mutex_init($mutex, probefunc())
 }
 probe process("/lib*/libpthread.so*").function("__pthread_mutex_init")
 {
-  process_mutex_init($mutex, probefunc())
+  if(@defined($mutex))
+    process_mutex_init($mutex, probefunc())
 }
 probe process("/lib*/libpthread.so*").function("__pthread_rwlock_init")
 {
-  process_mutex_init($rwlock, probefunc())
+  if(@defined($rwlock))
+    process_mutex_init($rwlock, probefunc())
 }
 
 probe syscall.futex.return
This page took 0.055414 seconds and 5 git commands to generate.