This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: Support ENABLED sdt probe macro
- From: Stan Cox <scox at redhat dot com>
- To: SystemTap List <systemtap at sources dot redhat dot com>
- Date: Tue, 15 Sep 2009 14:15:30 -0400
- Subject: Re: Support ENABLED sdt probe macro
- References: <4A808B13.8000307@redhat.com> <4A88C407.3030408@redhat.com> <4AAFD754.9080205@redhat.com>
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\" ";