This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Support ENABLED sdt probe macro



diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h

--- a/includes/sys/sdt.h
+++ b/includes/sys/sdt.h
@@ -44,2 +44,9 @@
 
+#if defined STAP_HAS_SEMAPHORES && ! defined EXPERIMENTAL_KPROBE_SDT
+#define STAP_SEMAPHORE(probe)			\
+  if ( probe ## _semaphore )
+#else
+#define STAP_SEMAPHORE(probe) ;
+#endif
+
 #if ! (defined EXPERIMENTAL_UTRACE_SDT || defined EXPERIMENTAL_KPROBE_SDT)
@@ -83,2 +90,3 @@ do { \
 #define STAP_PROBE1_(probe,label,parm1)			\
+STAP_SEMAPHORE(probe) \
 do {							\

... for all probes ...

diff --git a/runtime/itrace.c b/runtime/itrace.c

--- a/runtime/itrace.c
+++ b/runtime/itrace.c
@@ -79,56 +79,4 @@ static struct itrace_info *create_itrace_info(
 
-/*
- * The kernel's access_process_vm is not exported in kernel.org kernels, although
- * some distros export it on some architectures.  To workaround this inconsistency,
- * we copied and pasted it here.  Fortunately, everything it calls is exported.
- */
-#include <linux/pagemap.h>
-#include <asm/cacheflush.h>
-static int __access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
-{
-	struct mm_struct *mm;
-	struct vm_area_struct *vma;
-	struct page *page;
-	void *old_buf = buf;
-
-	mm = get_task_mm(tsk);
-	if (!mm)
-		return 0;
-
-	down_read(&mm->mmap_sem);
-	/* ignore errors, just check how much was sucessfully transfered */
-	while (len) {
-		int bytes, ret, offset;
-		void *maddr;
 
-		ret = get_user_pages(tsk, mm, addr, 1,
-				     write, 1, &page, &vma);
-		if (ret <= 0)
-			break;
-
-		bytes = len;
-		offset = addr & (PAGE_SIZE-1);
-		if (bytes > PAGE_SIZE-offset)
-			bytes = PAGE_SIZE-offset;
-
-		maddr = kmap(page);
-		if (write) {
-			copy_to_user_page(vma, page, addr,
-					  maddr + offset, buf, bytes);
-			set_page_dirty_lock(page);
-		} else {
-			copy_from_user_page(vma, page, addr,
-					    buf, maddr + offset, bytes);
-		}
-		kunmap(page);
-		page_cache_release(page);
-		len -= bytes;
-		buf += bytes;
-		addr += bytes;
-	}
-	up_read(&mm->mmap_sem);
-	mmput(mm);
-
-	return buf - old_buf;
-}
+/* Note: __access_process_vm moved to access_process_vm.h */
 
diff --git a/session.h b/session.h

--- a/session.h
+++ b/session.h
@@ -223,2 +223,6 @@ struct systemtap_session
 
+
+  // Location of semaphores to activate sdt probes
+  std::map<Dwarf_Addr, derived_probe*> sdt_semaphore_addr;
+
   // NB: It is very important for all of the above (and below) fields

diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx

--- a/tapset-utrace.cxx
+++ b/tapset-utrace.cxx
@@ -718,2 +718,17 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
   s.op->line() << " .engine_attached=0,";
+  map<Dwarf_Addr, derived_probe*>::iterator its;
+  if (s.sdt_semaphore_addr.empty())
+    s.op->line() << " .sdt_sem_address=(unsigned long)0x0,";
+  else
+    for (its = s.sdt_semaphore_addr.begin();
+	 its != s.sdt_semaphore_addr.end();
+	 its++)
+      {
+	if (p == ((struct utrace_derived_probe*)(its->second)))
+	  {
+	    s.op->line() << " .sdt_sem_address=(unsigned long)0x" << hex << its->first << dec << "ULL,";
+	    break;
+	  }
+      }
+  s.op->line() << " .tsk=0,";
   s.op->line() << " },";
@@ -752,2 +767,4 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline() << "int engine_attached;";
+  s.op->newline() << "struct task_struct *tsk;";
+  s.op->newline() << "unsigned long sdt_sem_address;";
   s.op->newline(-1) << "};";
@@ -874,2 +891,11 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline(-1) << "}";
+
+  s.op->newline() << "if (p->sdt_sem_address != 0) {";
+  s.op->newline(1) << "size_t sdt_semaphore;";
+  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() << "__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
+  s.op->newline(-1) << "}";
+
   s.op->newline(-1) << "}";
@@ -1019,2 +1045,22 @@ utrace_derived_probe_group::emit_module_exit (systemtap_session& s)
   s.op->newline(-1) << "}";
+
+  int sem_idx = 0;
+  if (! s.sdt_semaphore_addr.empty())
+    for (p_b_path_iterator it = probes_by_path.begin();
+	 it != probes_by_path.end(); it++)
+      {
+	s.op->newline() << "{";
+	s.op->indent(1);
+	s.op->newline() << "size_t sdt_semaphore;";
+	s.op->newline() << "for (i=0; i<ARRAY_SIZE(stap_utrace_probes); i++) {";
+	s.op->newline(1) << "struct stap_utrace_probe *p = &stap_utrace_probes[i];";
+
+	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() << "__access_process_vm (p->tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
+	
+	s.op->newline(-1) << "}";
+	s.op->newline(-1) << "}";
+	sem_idx += it->second.size() - 1;
+      }
 }

diff --git a/tapsets.cxx b/tapsets.cxx

--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -3445,2 +3445,3 @@ private:
   probe_point * base_loc;
+  literal_map_t const & params;
   vector<derived_probe *> & results;
@@ -3460,2 +3461,3 @@ private:
   void convert_probe(probe *base);
+  void record_semaphore(vector<derived_probe *> & results);
   void convert_location(probe *base, probe_point *location);
@@ -3468,3 +3470,3 @@ sdt_query::sdt_query(probe * base_probe, probe_point * base_loc,
   base_query(dw, params), base_probe(base_probe),
-  base_loc(base_loc), results(results)
+  base_loc(base_loc), params(params), results(results)
 {
@@ -3510,3 +3512,7 @@ sdt_query::handle_query_module()
       if (probe_type == kprobe_type || probe_type == utrace_type)
-        derive_probes(sess, new_base, results);
+	{
+	  derive_probes(sess, new_base, results);
+	  record_semaphore(results);
+	}
+      
       else
@@ -3523,2 +3529,3 @@ sdt_query::handle_query_module()
           dw.iterate_over_modules(&query_module, &q);
+	  record_semaphore(results);
         }
@@ -3654,2 +3661,24 @@ sdt_query::get_next_probe()
 void
+sdt_query::record_semaphore (vector<derived_probe *> & results)
+{
+  int sym_count = dwfl_module_getsymtab(dw.module);
+  assert (sym_count >= 0);
+  for (int i = 0; i < sym_count; i++)
+    {
+      GElf_Sym sym;
+      GElf_Word shndxp;
+      char *sym_str = (char*)dwfl_module_getsym (dw.module, i, &sym, &shndxp);
+      if (strcmp(sym_str, string(probe_name + "_semaphore").c_str()) == 0)
+	{
+	  string process_name;
+	  derived_probe_builder::get_param(params, TOK_PROCESS, process_name);
+          for (unsigned int i = 0; i < results.size(); ++i)
+	      sess.sdt_semaphore_addr.insert(make_pair(sym.st_value, results[i]));
+	  break;
+	}
+    }
+}
+
+
+void
 sdt_query::convert_probe (probe *base)
@@ -3804,3 +3833,2 @@ sdt_query::convert_location (probe *base, probe_point *location)
 
-
 void
@@ -4379,2 +4407,4 @@ 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() << "struct task_struct *tsk;";
   s.op->newline() << "unsigned return_p:1;";
@@ -4392,2 +4422,17 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
       s.op->line() << " .ph=&" << p->name << ",";
+      map<Dwarf_Addr, derived_probe*>::iterator its;
+      if (s.sdt_semaphore_addr.empty())
+	s.op->line() << " .sdt_sem_address=(unsigned long)0x0,";
+      else
+	for (its = s.sdt_semaphore_addr.begin();
+	     its != s.sdt_semaphore_addr.end();
+	     its++)
+	  {
+	    if (p->module == ((struct uprobe_derived_probe*)(its->second))->module
+		&& p->addr == ((struct uprobe_derived_probe*)(its->second))->addr)
+	      {
+		s.op->line() << " .sdt_sem_address=(unsigned long)0x" << hex << its->first << dec << "ULL,";
+		break;
+	      }
+	  }
       if (p->has_return) s.op->line() << " .return_p=1,";
@@ -4401,3 +4446,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst, struct stap_uprobe, up);";
-  s.op->newline() << "const struct stap_uprobe_spec *sups = &stap_uprobe_specs [sup->spec_index];";
+  s.op->newline() << "const struct stap_uprobe_spec *sups =  &stap_uprobe_specs [sup->spec_index];";
   common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sups->pp");
@@ -4465,3 +4510,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline() << "int slotted_p = 0;";
-  s.op->newline() << "const struct stap_uprobe_spec *sups = &stap_uprobe_specs [spec_index];";
+  s.op->newline() << "struct stap_uprobe_spec *sups = (struct stap_uprobe_spec*) &stap_uprobe_specs [spec_index];";
   s.op->newline() << "int rc = 0;";
@@ -4545,2 +4590,12 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
 
+  //----------
+  s.op->newline() << "if (sups->sdt_sem_address != 0) {";
+  s.op->newline(1) << "size_t sdt_semaphore;";
+  s.op->newline() << "sups->tsk = tsk;";
+  s.op->newline() << "__access_process_vm (tsk, sups->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
+  s.op->newline() << "sdt_semaphore += 1;";
+  s.op->newline() << "__access_process_vm (tsk, sups->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
+  s.op->newline(-1) << "}";
+  //----------
+
   // close iteration over stap_uprobe_spec[]
@@ -4567,5 +4622,5 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[i];";
-  s.op->newline() << "const struct stap_uprobe_spec *sups;";
+  s.op->newline() << "struct stap_uprobe_spec *sups;";
   s.op->newline() << "if (sup->spec_index < 0) continue;"; // skip free uprobes slot
-  s.op->newline() << "sups = & stap_uprobe_specs[sup->spec_index];";
+  s.op->newline() << "sups = (struct stap_uprobe_spec*) & stap_uprobe_specs[sup->spec_index];";
 
@@ -4629,2 +4684,12 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
 
+  //----------
+  s.op->newline() << "if (sups->sdt_sem_address != 0) {";
+  s.op->newline(1) << "size_t sdt_semaphore;";
+  s.op->newline() << "sups->tsk = tsk;";
+  s.op->newline() << "__access_process_vm (tsk, sups->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
+  s.op->newline() << "sdt_semaphore += 1;";
+  s.op->newline() << "__access_process_vm (tsk, sups->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
+  s.op->newline(-1) << "}";
+  //----------
+
   // close iteration over stap_uprobes[]
@@ -4752,2 +4817,12 @@ uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
 
+  //----------
+  s.op->newline() << "if (sups->sdt_sem_address != 0) {";
+  s.op->newline(1) << "size_t sdt_semaphore;";
+  s.op->newline() << "__access_process_vm (sups->tsk, sups->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
+  s.op->newline() << "sdt_semaphore -= 1;";
+  s.op->newline() << "__access_process_vm (sups->tsk, sups->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
+  s.op->newline(-1) << "}";
+  //----------
+
+
   s.op->newline() << "if (sups->return_p) {";

diff --git a/translate.cxx b/translate.cxx

--- a/translate.cxx
+++ b/translate.cxx
@@ -5270,2 +5270,3 @@ translate_pass (systemtap_session& s)
       s.op->newline() << "#include \"loc2c-runtime.h\" ";
+      s.op->newline() << "#include \"access_process_vm.h\" ";
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]