public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* add simple .library syntax
@ 2009-11-25 22:59 Stan Cox
  2009-12-01 19:04 ` Stan Cox
  0 siblings, 1 reply; 2+ messages in thread
From: Stan Cox @ 2009-11-25 22:59 UTC (permalink / raw)
  To: systemtap

[-- Attachment #1: Type: text/plain, Size: 790 bytes --]

This patch adds a simple implementation of .library("library") to
assist the task finder so that an external variable can be found in a
shared object.  This is bug 6880.  It adds .library to uprobe and utrace 
probes so that process("process").library("library").mark("mark") can be 
converted to either a uprobe or utrace probe.  The .library support is 
currently simple since  LD_LIBRARY_PATH is not searched.  emit_module_decls in 
both utrace_derived_probe_group and uprobe_derived_probe_group add
machinery to access and set a static user probe semaphore, which is
actually an external variable.  The writeable portion of a shared
object will be mapped into a separate segment, so when the task finder
notices this then the value is accessed via _access_process_vm and incremented.



[-- Attachment #2: ,git.diff --]
[-- Type: text/plain, Size: 24114 bytes --]

* dtrace.in (provider): Turn on semaphores
* includes/sys/sdt.h: Likewise
* tapset-utrace.cxx: Add TOK_LIBRARY.
(utrace_derived_probe): Add has_library and library
(utrace_derived_probe_group::emit_module_decls): Add sdt_sem_offset to 
stap_utrace_probes.
Emit an stap_utrace_probe for stap_utrace_mmap_found
Add sdt_sem_offset to stap_utrace_probe.
Cleanup semaphore increment.
Emit new stap_utrace_mmap_found.
* tapsets.cxx (X): Add new TOK_LIBRARY.
(dwarf_derived_probe): Add path and has_library.
(base_query::base_query): Check for TOK_LIBRARY.
(sdt_query::convert_location): Allow for TOK_LIBRARY.
(uprobe_derived_probe_group::emit_module_decls): Add procname to 
stap_uprobe_finders.
Add new sdt_sem_address.
Change signature of stap_uprobe_change_plus to add offset and vm_flags.
Add emit to set sdt_sem_address


diff --git a/dtrace.in b/dtrace.in
index 74d70e7..269f398 100755
--- a/dtrace.in
+++ b/dtrace.in
@@ -48,3 +48,3 @@ class provider:
         self.h.write("/* Generated by the Systemtap dtrace wrapper */\n")
-        # self.h.write("\n#define STAP_HAS_SEMAPHORES 1\n\n")
+        self.h.write("\n#define STAP_HAS_SEMAPHORES 1\n\n")
         self.h.write("\n#include <sys/sdt.h>\n\n")
@@ -109,3 +109,3 @@ class provider:
                 # XXX Enable this when .so semaphores work properly
-                self.h.write ('#define %s_ENABLED() 1 /*%s_semaphore*/\n' % (this_probe_canon,this_probe))
+                self.h.write ('#define %s_ENABLED() %s_semaphore\n' % (this_probe_canon,this_probe))
                 # NB: unsigned short is fixed in ABI
diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h
index 3847c49..fb813cc 100644
--- a/includes/sys/sdt.h
+++ b/includes/sys/sdt.h
@@ -42,3 +42,4 @@
 
-#if defined STAP_HAS_SEMAPHORES && defined EXPERIMENTAL_UTRACE_SDT
+// #if defined STAP_HAS_SEMAPHORES && defined EXPERIMENTAL_UTRACE_SDT
+#if defined STAP_HAS_SEMAPHORES && ! defined EXPERIMENTAL_KPROBE_SDT
 #define STAP_SEMAPHORE(probe)	\
diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx
index 795d88b..23029e9 100644
--- a/tapset-utrace.cxx
+++ b/tapset-utrace.cxx
@@ -31,2 +31,3 @@ static const string TOK_SYSCALL("syscall");
 static const string TOK_RETURN("return");
+static const string TOK_LIBRARY("library");
 
@@ -54,2 +55,4 @@ struct utrace_derived_probe: public derived_probe
   string path;
+  bool has_library;
+  string library;
   int64_t pid;
@@ -59,4 +62,4 @@ struct utrace_derived_probe: public derived_probe
   utrace_derived_probe (systemtap_session &s, probe* p, probe_point* l,
-                        bool hp, string &pn, int64_t pd,
-			enum utrace_derived_probe_flags f);
+                        bool hp, string &pn, bool hl, string &ln, 
+			int64_t pd, enum utrace_derived_probe_flags f);
   void join_group (systemtap_session& s);
@@ -117,6 +120,6 @@ utrace_derived_probe::utrace_derived_probe (systemtap_session &s,
                                             probe* p, probe_point* l,
-                                            bool hp, string &pn, int64_t pd,
-					    enum utrace_derived_probe_flags f):
+                                            bool hp, string &pn, bool hl, string &ln,
+					    int64_t pd, enum utrace_derived_probe_flags f):
   derived_probe (p, new probe_point (*l) /* .components soon rewritten */ ),
-  has_path(hp), path(pn), pid(pd), flags(f),
+  has_path(hp), path(pn), has_library(hl), library(ln), pid(pd), flags(f),
   target_symbol_seen(false)
@@ -601,2 +604,3 @@ struct utrace_builder: public derived_probe_builder
     string path;
+    string lib;
     int64_t pid;
@@ -604,2 +608,3 @@ struct utrace_builder: public derived_probe_builder
     bool has_path = get_param (parameters, TOK_PROCESS, path);
+    bool has_lib = get_param (parameters, TOK_LIBRARY, lib);
     bool has_pid = get_param (parameters, TOK_PROCESS, pid);
@@ -649,5 +654,7 @@ struct utrace_builder: public derived_probe_builder
       }
+    if (has_lib)
+      lib = find_executable (lib); // FIXME: Search LD_LIBRARY_PATH
 
     finished_results.push_back(new utrace_derived_probe(sess, base, location,
-                                                        has_path, path, pid,
+                                                        has_path, path, has_lib, lib, pid,
 							flags));
@@ -752,7 +759,21 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
   if (p->sdt_semaphore_addr != 0)
-    s.op->line() << " .sdt_sem_address=(unsigned long)0x"
+    s.op->line() << " .sdt_sem_offset=(unsigned long)0x"
                  << hex << p->sdt_semaphore_addr << dec << "ULL,";
-
+  s.op->line() << " .sdt_sem_address=0,";
   s.op->line() << " .tsk=0,";
   s.op->line() << " },";
+
+  if (p->sdt_semaphore_addr != 0)
+    {
+      s.op->newline() << "{";
+      s.op->line() << " .tgt={";
+      s.op->line() << " .procname=\"" << p->path << "\",";
+      s.op->line() << " .mmap_callback=&stap_utrace_mmap_found,";
+      s.op->line() << " },";
+      s.op->line() << " .pathname=\"" << p->library << "\",";
+      s.op->line() << " .sdt_sem_offset=(unsigned long)0x"
+		   << hex << p->sdt_semaphore_addr << dec << "ULL,";
+      s.op->line() << " .sdt_sem_address=0,";
+      s.op->line() << " },";
+    }
 }
@@ -791,3 +812,7 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline() << "struct task_struct *tsk;";
+  s.op->newline() << "unsigned long sdt_sem_offset;";
+  // FIXME: if this probe is attached to more than 1 task, having 1
+  // address here won't work
   s.op->newline() << "unsigned long sdt_sem_address;";
+  s.op->newline(0) << "const char *pathname;";
   s.op->newline(-1) << "};";
@@ -915,2 +940,3 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
 
+  // Before writing to the semaphore, we need to check for VM_WRITE access.
   s.op->newline() << "if (p->sdt_sem_address != 0) {";
@@ -919,7 +945,11 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline() << "p->tsk = tsk;";
-  s.op->newline() << "__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
-  s.op->newline() << "sdt_semaphore += 1;";
+
+  s.op->newline() << "if (__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0) == sizeof (sdt_semaphore)) {";
+  s.op->newline(1) << "sdt_semaphore ++;";
   s.op->newline() << "__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
   s.op->newline(-1) << "}";
-
+  s.op->newline() << "else {";
+  s.op->newline(1) << "_stp_error(\"__access_process_vm failed at %s:%d\", __FUNCTION__, __LINE__);";
+  s.op->newline(-1) << "}";
+  s.op->newline(-1) << "}";
   s.op->newline(-1) << "}";
@@ -987,2 +1017,44 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
 
+  // The task_finder_mmap_callback
+  s.op->newline() << "static int stap_utrace_mmap_found (struct stap_task_finder_target *tgt, struct task_struct *tsk, char *path, unsigned long addr, unsigned long length, unsigned long offset, unsigned long vm_flags) {";
+  s.op->newline(1) << "struct stap_utrace_probe *p = container_of(tgt, struct stap_utrace_probe, tgt);";
+  s.op->newline() << "int rc = 0;";
+  // the shared library we're interested in
+  s.op->newline() << "if (path == NULL || strcmp (path, p->pathname)) return 0;";
+  s.op->newline() << "_stp_printf (\"stap_utrace_mmap_found %s %#lx path %s reloc %#lx %#lx\\n\",p->pathname,p->sdt_sem_offset,path,addr,offset);";
+  s.op->newline() << "if (p->sdt_sem_address == 0) {";
+  s.op->indent(1);
+  // If the probe is in the executable itself, the offset *is* the
+  // address.
+  s.op->newline() << "if (vm_flags & VM_EXECUTABLE) {";
+  s.op->indent(1);
+  s.op->newline() << "p->sdt_sem_address = p->sdt_sem_offset;";
+  s.op->newline(-1) << "}";
+  // If the probe is in a .so, we have to calculate the address.
+  s.op->newline() << "else {";
+  s.op->indent(1);
+  s.op->newline() << "p->sdt_sem_address = (addr - offset) + p->sdt_sem_offset;";
+  s.op->newline(-1) << "}";
+  s.op->newline() << "_stp_printf (\"stap_utrace_mmap_found: sdt_sem_address %#lx = (%#lx - %#lx) + %#lx (%#lx)\\n\",p->sdt_sem_address,addr,offset,p->sdt_sem_offset, vm_flags);";
+  s.op->newline(-1) << "}";
+
+  s.op->newline() << "if (p->sdt_sem_address) {";
+  s.op->newline(1) << "unsigned short sdt_semaphore = 0;"; // NB: fixed size
+  s.op->newline() << "_stp_printf (\"+semaphore %#lx @ %#lx reloc %#lx addr %#lx \\n\", sdt_semaphore, p->sdt_sem_address,addr,p->sdt_sem_offset);";
+
+  s.op->newline() << "if (__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0) == sizeof (sdt_semaphore)) {";
+
+  s.op->newline(1) << "if (vm_flags & VM_WRITE) {";
+  s.op->indent(1);
+  s.op->newline() << "sdt_semaphore ++;";
+  s.op->newline() << "#ifdef DEBUG_UTRACE";
+  s.op->newline() << "_stp_dbug (__FUNCTION__,__LINE__, \"+semaphore %#x @ %#lx\\n\", sdt_semaphore, p->sdt_sem_address);";
+  s.op->newline() << "#endif";
+  s.op->newline() << "__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
+  s.op->newline(-1) << "}";
+  s.op->newline(-1) << "}";
+  s.op->newline(-1) << "}";
+  s.op->newline() << "return 0;";
+  s.op->newline(-1) << "}";
+
   s.op->newline() << "static struct stap_utrace_probe stap_utrace_probes[] = {";
@@ -1018,2 +1090,3 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline(-1) << "};";
+
 }
@@ -1057,2 +1130,3 @@ utrace_derived_probe_group::emit_module_exit (systemtap_session& s)
 
+  // Before writing to the semaphore, we need to check for VM_WRITE access.
   s.op->newline() << "if (p->sdt_sem_address) {";
@@ -1060,7 +1134,11 @@ utrace_derived_probe_group::emit_module_exit (systemtap_session& s)
   // XXX p could get registered to more than one task!
-  s.op->newline() << "__access_process_vm (p->tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
-  s.op->newline() << "sdt_semaphore -= 1;";
+  s.op->newline() << "if (__access_process_vm (p->tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0) == sizeof (sdt_semaphore)) {";
+  s.op->newline(1) << "sdt_semaphore -= 1;";
   s.op->newline() << "__access_process_vm (p->tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
   s.op->newline(-1) << "}";
-
+  s.op->newline() << "else {";
+  s.op->indent(1);
+  s.op->newline() << "_stp_error(\"__access_process_vm failed at %s:%d\", __FUNCTION__, __LINE__);";
+  s.op->newline(-1) << "}";
+  s.op->newline(-1) << "}";
   s.op->newline(-1) << "}";
@@ -1096,2 +1174,4 @@ register_tapset_utrace(systemtap_session& s)
 	->bind(builder);
+      roots[i]->bind_str(TOK_LIBRARY)->bind(TOK_SYSCALL)
+	->bind(builder);
     }
diff --git a/tapsets.cxx b/tapsets.cxx
index 7bae461..a261d7f 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -262,2 +262,3 @@ static const string TOK_TRACE("trace");
 static const string TOK_LABEL("label");
+static const string TOK_LIBRARY("library");
 
@@ -351,4 +352,6 @@ struct dwarf_derived_probe: public derived_probe
   Dwarf_Addr addr;
+  string path;
   bool has_return;
   bool has_maxactive;
+  bool has_library;
   long maxactive_val;
@@ -462,3 +465,5 @@ struct base_query
   bool has_process;
+  bool has_library;
   string module_val; // has_kernel => module_val = "kernel"
+  string path;	     // executable path if module is a .so
 
@@ -480,3 +485,12 @@ base_query::base_query(dwflpp & dw, literal_map_t const & params):
     {
+      string library_name;
       has_process = get_string_param(params, TOK_PROCESS, module_val);
+      if (get_string_param (params, TOK_LIBRARY, library_name))
+	{
+	  has_library = true;
+	  path = find_executable (module_val);
+	  module_val = library_name; // FIXME: Search LD_LIBRARY_PATH
+	}
+      else
+	has_library = false;
       if (has_process)
@@ -2842,7 +2856,9 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
     module (module), section (section), addr (addr),
+    path (q.path),
     has_return (q.has_return),
     has_maxactive (q.has_maxactive),
+    has_library (q.has_library), 
     maxactive_val (q.maxactive_val),
     access_vars(false),
-    saved_longs(0), saved_strings(0),
+    saved_longs(0), saved_strings(0), 
     entry_handler(0)
@@ -3142,2 +3158,4 @@ dwarf_derived_probe::register_patterns(systemtap_session& s)
     ->bind(dw);
+  root->bind_str(TOK_PROCESS)->bind_str(TOK_LIBRARY)->bind_str(TOK_MARK)
+    ->bind(dw);
   root->bind_str(TOK_PROCESS)->bind_str(TOK_MARK)
@@ -3985,42 +4003,48 @@ sdt_query::convert_location (probe *base, probe_point *location)
 {
-  switch (probe_type)
-    {
-    case uprobe_type:
-      if (sess.verbose > 3)
-        clog << "probe_type == uprobe_type, use statement addr: 0x"
-             << hex << probe_arg << dec << endl;
-      // process("executable").statement(probe_arg)
-      location->components[1]->functor = TOK_STATEMENT;
-      location->components[1]->arg = new literal_number(probe_arg);
-      break;
+  for (unsigned i = 0; i < location->components.size(); ++i)
+    if (location->components[i]->functor == TOK_MARK)
+      switch (probe_type)
+	{
+	case uprobe_type:
+	  if (sess.verbose > 3)
+	    clog << "probe_type == uprobe_type, use statement addr: 0x"
+		 << hex << probe_arg << dec << endl;
+	  // process("executable").statement(probe_arg)
+	  location->components[i]->functor = TOK_STATEMENT;
+	  location->components[i]->arg = new literal_number(probe_arg);
+	  break;
 
-    case kprobe_type:
-      if (sess.verbose > 3)
-        clog << "probe_type == kprobe_type" << endl;
-      // kernel.function("*getegid*")
-      location->components[0]->functor = TOK_KERNEL;
-      location->components[0]->arg = NULL;
-      location->components[1]->functor = TOK_FUNCTION;
-      location->components[1]->arg = new literal_string("*getegid*");
-      break;
+	case kprobe_type:
+	  if (sess.verbose > 3)
+	    clog << "probe_type == kprobe_type" << endl;
+	  // kernel.function("*getegid*")
+	  location->components[i]->functor = TOK_FUNCTION;
+	  location->components[i]->arg = new literal_string("*getegid*");
+	  break;
 
-    case utrace_type:
-      if (sess.verbose > 3)
-        clog << "probe_type == utrace_type" << endl;
-      // process("executable").syscall
-      location->components[1]->functor = "syscall";
-      location->components[1]->arg = NULL;
-      break;
+	case utrace_type:
+	  if (sess.verbose > 3)
+	    clog << "probe_type == utrace_type" << endl;
+	  // process("executable").syscall
+	  location->components[i]->functor = "syscall";
+	  location->components[i]->arg = NULL;
+	  break;
 
-    default:
-      if (sess.verbose > 3)
-        clog << "probe_type == use_uprobe_no_dwarf, use label name: "
-          << "_stapprobe1_" << mark_name << endl;
-      // process("executable").function("*").label("_stapprobe1_MARK_NAME")
-      location->components[1]->functor = TOK_FUNCTION;
-      location->components[1]->arg = new literal_string("*");
-      location->components.push_back(new probe_point::component(TOK_LABEL));
-      location->components[2]->arg = new literal_string("_stapprobe1_" + mark_name);
-      break;
-    }
+	default:
+	  if (sess.verbose > 3)
+	    clog << "probe_type == use_uprobe_no_dwarf, use label name: "
+		 << "_stapprobe1_" << mark_name << endl;
+	  // process("executable").function("*").label("_stapprobe1_MARK_NAME")
+	  location->components[1]->functor = TOK_FUNCTION;
+	  location->components[1]->arg = new literal_string("*");
+	  location->components.push_back(new probe_point::component(TOK_LABEL));
+	  location->components[2]->arg = new literal_string("_stapprobe1_" + mark_name);
+	  break;
+	}
+    else if (location->components[i]->functor == TOK_PROCESS
+	     && probe_type == kprobe_type)
+      {
+	location->components[i]->functor = TOK_KERNEL;
+	location->components[i]->arg = NULL;
+      }
 
@@ -4055,2 +4079,5 @@ dwarf_builder::build(systemtap_session & sess,
     {
+      string library_name;
+      if (get_param (parameters, TOK_LIBRARY, library_name))
+	module_name = library_name;		   // FIXME: search LD_LIBRARY_PATH
       module_name = find_executable (module_name); // canonicalize it
@@ -4559,3 +4586,2 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline(1) << "union { struct uprobe up; struct uretprobe urp; };";
-  s.op->newline() << "unsigned long sdt_sem_address;"; // relocated to this process
   s.op->newline() << "int spec_index;"; // index into stap_uprobe_specs; <0 == free && unregistered
@@ -4602,2 +4628,4 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
             {
+	      if (p->sdt_semaphore_addr != 0)
+		s.op->line() << " .procname=\"" << p->path << "\", ";
               s.op->line() << " .mmap_callback=&stap_uprobe_mmap_found, ";
@@ -4617,2 +4645,6 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
 
+  s.op->newline() << "unsigned long sdt_sem_address [] = {";
+  for (unsigned i =0; i<probes.size(); i++)
+    s.op->line() << "0,";
+  s.op->line() << "0};";
   s.op->newline() << "static const struct stap_uprobe_spec {"; // NB: read-only structure
@@ -4623,3 +4655,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline() << "void (*ph) (struct context*);";
-  s.op->newline() << "unsigned long sdt_sem_address;";
+  s.op->newline() << "unsigned long sdt_sem_offset;";
   s.op->newline(-1) << "} stap_uprobe_specs [] = {"; // NB: read-only structure
@@ -4639,3 +4671,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
       if (p->sdt_semaphore_addr != 0)
-        s.op->line() << " .sdt_sem_address=(unsigned long)0x"
+        s.op->line() << " .sdt_sem_offset=(unsigned long)0x"
                      << hex << p->sdt_semaphore_addr << dec << "ULL,";
@@ -4708,3 +4740,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline();
-  s.op->newline() << "static int stap_uprobe_change_plus (struct task_struct *tsk, unsigned long relocation, unsigned long length, const struct stap_uprobe_tf *stf) {";
+  s.op->newline() << "static int stap_uprobe_change_plus (struct task_struct *tsk, unsigned long relocation, unsigned long length, const struct stap_uprobe_tf *stf, unsigned long offset, unsigned long vm_flags) {";
   s.op->newline(1) << "int tfi = (stf - stap_uprobe_finders);";
@@ -4759,2 +4791,16 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
 
+  s.op->newline() << "if (sups->sdt_sem_offset && sdt_sem_address[spec_index] == 0) {";
+  s.op->indent(1);
+  // If the probe is in the executable itself, the offset *is* the address.
+  s.op->newline() << "if (vm_flags & VM_EXECUTABLE) {";
+  s.op->indent(1);
+  s.op->newline() << "sdt_sem_address[spec_index] = sups->sdt_sem_offset;";
+  s.op->newline(-1) << "}";
+  // If the probe is in a .so, we have to calculate the address.
+  s.op->newline() << "else {";
+  s.op->indent(1);
+  s.op->newline() << "sdt_sem_address[spec_index] = (relocation - offset) + sups->sdt_sem_offset;";
+  s.op->newline(-1) << "}";
+  s.op->newline(-1) << "}";	// sdt_sem_offset
+
   s.op->newline() << "if (slotted_p) {";
@@ -4772,15 +4818,14 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
 
-  // PR10655: also handle ENABLED semaphore manipulations here
-  s.op->newline() << "if (!rc && sups->sdt_sem_address) {";
-  s.op->newline(1) << "unsigned short sdt_semaphore;"; // NB: fixed size
-  s.op->newline() << "sup->sdt_sem_address = relocation + sups->sdt_sem_address;";
-  s.op->newline() << "(void) __access_process_vm (tsk, sup->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
-  s.op->newline() << "sdt_semaphore ++;";
-  s.op->newline() << "#ifdef DEBUG_UPROBES";
-  s.op->newline() << "_stp_dbug (__FUNCTION__,__LINE__, \"+semaphore %#x @ %#lx\\n\", sdt_semaphore, sup->sdt_sem_address);";
-  s.op->newline() << "#endif";
-
-  s.op->newline() << "(void) __access_process_vm (tsk, sup->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
+  s.op->newline() << "if (sdt_sem_address[spec_index]) {";
+  s.op->newline(1) << "unsigned short sdt_semaphore = 0;"; // NB: fixed size
+  s.op->newline() << "if ( __access_process_vm (tsk, sdt_sem_address[spec_index], &sdt_semaphore, sizeof (sdt_semaphore), 0)) {";
+  s.op->newline(1) << "if (vm_flags & VM_WRITE) {";
+  s.op->newline(1) << "sdt_semaphore ++;";
+  s.op->newline() << "__access_process_vm (tsk, sdt_sem_address[spec_index], &sdt_semaphore, sizeof (sdt_semaphore), 1);";
+  s.op->newline() << "rc = 0;";
+  s.op->newline(-1) << "}";
+  s.op->newline(-1) << "}";	// sdt_sem_address
   // XXX: error handling in __access_process_vm!
   // XXX: need to analyze possibility of race condition
+
   s.op->newline(-1) << "}";
@@ -4788,2 +4833,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline(-1) << "}";
+
   s.op->newline() << "if (rc) {"; // failed to register
@@ -4921,3 +4967,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline() << "if (register_p)";
-  s.op->newline(1) << "return stap_uprobe_change_plus (tsk, 0, TASK_SIZE, stf);";
+  s.op->newline(1) << "return stap_uprobe_change_plus (tsk, 0, TASK_SIZE, stf, 0, 0);";
   s.op->newline(-1) << "else";
@@ -4934,7 +4980,8 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
   // 1 - shared libraries' executable segments load from offset 0 - ld.so convention
-  s.op->newline() << "if (offset != 0) return 0;";
+  // offset != 0 is now allowed so stap_uprobe_change_plus can set a semaphore,
+  // i.e. a static extern, in a shared object
   // 2 - the shared library we're interested in
   s.op->newline() << "if (path == NULL || strcmp (path, stf->pathname)) return 0;";
-  // 3 - mapping should be executable
-  s.op->newline() << "if (!(vm_flags & VM_EXEC)) return 0;";
+  // 3 - mapping should be executable or writeable (for semaphore in .so)
+  s.op->newline() << "if (!((vm_flags & VM_EXEC) || (vm_flags & VM_WRITE))) return 0;";
 
@@ -4945,3 +4992,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
 
-  s.op->newline() << "return stap_uprobe_change_plus (tsk, addr, length, stf);";
+  s.op->newline() << "return stap_uprobe_change_plus (tsk, addr, length, stf, offset, vm_flags);";
   s.op->newline(-1) << "}";
@@ -4963,2 +5010,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
 
+
   s.op->assert_0_indent();
@@ -5023,3 +5071,3 @@ uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
   // PR10655: decrement that ENABLED semaphore
-  s.op->newline() << "if (sups->sdt_sem_address != 0) {";
+  s.op->newline() << "if (sdt_sem_address[sup->spec_index]) {";
   s.op->newline(1) << "unsigned short sdt_semaphore;"; // NB: fixed size
@@ -5043,8 +5091,9 @@ uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
   s.op->newline() << "if (tsk) {"; // just in case the thing exited while we weren't watching
-  s.op->newline(1) << "(void) __access_process_vm (tsk, sup->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
-  s.op->newline() << "sdt_semaphore --;";
+  s.op->newline(1) << "if (__access_process_vm (tsk, sdt_sem_address[sup->spec_index], &sdt_semaphore, sizeof (sdt_semaphore), 0)) {";
+  s.op->newline(1) << "sdt_semaphore --;";
   s.op->newline() << "#ifdef DEBUG_UPROBES";
-  s.op->newline() << "_stp_dbug (__FUNCTION__,__LINE__, \"-semaphore %#x @ %#lx\\n\", sdt_semaphore, sup->sdt_sem_address);";
+  s.op->newline() << "_stp_dbug (__FUNCTION__,__LINE__, \"-semaphore %#x @ %#lx\\n\", sdt_semaphore, sdt_sem_address[sup->spec_index]);";
   s.op->newline() << "#endif";
-  s.op->newline() << "(void) __access_process_vm (tsk, sup->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
+  s.op->newline() << "(void) __access_process_vm (tsk, sdt_sem_address[sup->spec_index], &sdt_semaphore, sizeof (sdt_semaphore), 1);";
+  s.op->newline(-1) << "}";	// access_process_vm
   // XXX: error handling in __access_process_vm!

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: add simple .library syntax
  2009-11-25 22:59 add simple .library syntax Stan Cox
@ 2009-12-01 19:04 ` Stan Cox
  0 siblings, 0 replies; 2+ messages in thread
From: Stan Cox @ 2009-12-01 19:04 UTC (permalink / raw)
  To: systemtap

util.cxx (find_executable): Add env_path to signature for searching 
LD_LIBRARY_PATH for a .so


--- a/util.cxx
+++ b/util.cxx
@@ -215,3 +214,3 @@ tokenize(const string& str, vector<string>& tokens,
-string find_executable(const string& name)
+string find_executable(const string& name, const string& env_path)
  {
@@ -230,3 +229,3 @@ string find_executable(const string& name)
      {
-      char *path = getenv("PATH");
+      char *path = getenv(env_path.c_str());
        if (path)

--- a/util.h
+++ b/util.h
@@ -16,3 +16,4 @@ void tokenize(const std::string& str, 
std::vector<std::string>& tokens,
  	      const std::string& delimiters);
-std::string find_executable(const std::string& name);
+std::string find_executable(const std::string& name,
+			    const std::string& env_path = "PATH");
  const std::string cmdstr_quoted(const std::string& cmd);

--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -480,3 +485,12 @@ base_query::base_query(dwflpp & dw, literal_map_t const & 
params):
      {
+      string library_name;
        has_process = get_string_param(params, TOK_PROCESS, module_val);
+      if (get_string_param (params, TOK_LIBRARY, library_name))
+	{
+	  has_library = true;
+	  path = find_executable (module_val);
+	  module_val = find_executable (library_name, "LD_LIBRARY_PATH");

--- a/tapset-utrace.cxx
+++ b/tapset-utrace.cxx
@@ -649,5 +654,7 @@ struct utrace_builder: public derived_probe_builder
        }
+    if (has_lib)
+      lib = find_executable (lib, "LD_LIBRARY_PATH");


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-12-01 19:04 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-25 22:59 add simple .library syntax Stan Cox
2009-12-01 19:04 ` Stan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).