* Support ENABLED sdt probe macro
@ 2009-08-10 21:03 Stan Cox
2009-08-17 2:44 ` Stan Cox
0 siblings, 1 reply; 3+ messages in thread
From: Stan Cox @ 2009-08-10 21:03 UTC (permalink / raw)
To: SystemTap List
[-- Attachment #1: Type: text/plain, Size: 1408 bytes --]
SW10013
This is for utrace only; uprobes is related.
For test.d 'dtrace -h -s test.d' emits in test.h
__extension__ extern long test_semaphore __attribute__ ((unused))
__attribute__ ((section (".probes")));
and for 'dtrace -G test.d' adds the definition
The changes for sdt.h are simple for a change, it checks that value
before each probe setup.
session.h defines a map from filename to variable location
tapset-utrace.cxx will produce the following additional generated code:
add 'struct task_struct *tsk;' to stap_utrace_probe
since there is not a means to determine the task from
systemtap_module_exit
in _stp_utrace_probe_cb add for each probe if the filename matches.
(There is not a means to determine what probe brought us here so
incrementing only the concerned probe is a challenge)
size_t sdt_semaphore = 1;
__access_process_vm (tsk, 0x601230, &sdt_semaphore,
sizeof (sdt_semaphore), 0);
sdt_semaphore += 1;
in systemtap_module_exit add for each probe if the filename matches
size_t sdt_semaphore;
__access_process_vm (tsk, 0x601230, &sdt_semaphore,
sizeof (sdt_semaphore, 0);
sdt_semaphore -= 1;
__access_process_vm (tsk, 0x601230, &sdt_semaphore,
sizeof (sdt_semaphore), 1);
In tapsets.cxx record the mapping from filename to variable location
In translate.cxx include a new "access_process_vm.h" (see itrace.c)
[-- Attachment #2: 10013.patch --]
[-- Type: text/plain, Size: 7742 bytes --]
diff --git a/dtrace.in b/dtrace.in
index 168bfb1..38fb03b 100755
--- a/dtrace.in
+++ b/dtrace.in
@@ -19,2 +19,3 @@ from tempfile import mkstemp
class provider:
+ semaphores_def = "\n"
def typedef_append(self, typedefs,this_probe,arg,c):
@@ -30,2 +31,6 @@ class provider:
return typedefs
+ def semaphore_def_append(self, this_probe):
+ self.semaphores_def += "__extension__ long %s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % (this_probe)
+ def semaphore_def_write(self, file):
+ file.write(self.semaphores_def)
def generate(self, provider, header, add_typedefs):
@@ -35,2 +40,4 @@ class provider:
self.h.write("/* Generated by the Systemtap dtrace wrapper */\n")
+ if (build_source):
+ self.h.write("\n#define STAP_HAS_SEMAPHORES 1\n\n")
self.h.write("\n#include <sys/sdt.h>\n\n")
@@ -66,2 +73,3 @@ class provider:
c = 0
+ self.semaphore_def_append (this_probe)
while (i < len(args)):
@@ -93,3 +101,4 @@ class provider:
self.h.write ('/* %s (%s) */\n' % (this_probe_canon,args_string))
- self.h.write ('#define %s_ENABLED() 1\n' % this_probe_canon)
+ self.h.write ('#define %s_ENABLED() %s_semaphore\n' % (this_probe_canon,this_probe))
+ self.h.write ("__extension__ extern long %s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % (this_probe))
self.h.write (define_str + ") \\\n")
@@ -176,2 +185,3 @@ if (build_header):
elif (build_source):
+ providers = provider()
(basename,ext) = os.path.splitext(s_filename)
@@ -181,2 +191,3 @@ elif (build_source):
f.write("static __dtrace () {}\n")
+ providers.semaphore_def_write(f)
f.close()
diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h
index f179c2a..6f3aaab 100644
--- a/includes/sys/sdt.h
+++ b/includes/sys/sdt.h
@@ -254,2 +254,9 @@ extern long int syscall (long int __sysno, ...) __THROW;
+#ifdef STAP_HAS_SEMAPHORES
+#define STAP_SEMAPHORE(probe) \
+ if ( probe ## _semaphore )
+#else
+#define STAP_SEMAPHORE(probe) ;
+#endif
+
#include <sys/syscall.h>
@@ -257,4 +264,5 @@ extern long int syscall (long int __sysno, ...) __THROW;
#define STAP_PROBE_(probe) \
+STAP_SEMAPHORE(probe) \
do { \
- STAP_PROBE_DATA(probe,STAP_SYSCALL,0); \
+ STAP_PROBE_DATA(probe,STAP_GUARD,0); \
syscall (STAP_SYSCALL, #probe, STAP_GUARD); \
@@ -263,2 +271,3 @@ do { \
#define STAP_PROBE1_(probe,label,parm1) \
+STAP_SEMAPHORE(probe) \
do { \
@@ -269,2 +278,3 @@ do { \
#define STAP_PROBE2_(probe,label,parm1,parm2) \
+STAP_SEMAPHORE(probe) \
do { \
@@ -278,2 +288,3 @@ do { \
....
diff --git a/session.h b/session.h
index ea91442..f642b74 100644
--- a/session.h
+++ b/session.h
@@ -223,2 +223,6 @@ struct systemtap_session
+
+ // Location of semaphores to activate sdt probes
+ std::multimap<std::string, Dwarf_Addr> 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
index a07e08b..844326d 100644
--- a/tapset-utrace.cxx
+++ b/tapset-utrace.cxx
@@ -718,2 +718,3 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
s.op->line() << " .engine_attached=0,";
+ s.op->line() << " .tsk=0,";
s.op->line() << " },";
@@ -752,2 +753,3 @@ 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(-1) << "};";
@@ -863,2 +865,3 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "p->engine_attached = 1;";
+ s.op->newline() << "p->tsk = tsk;";
s.op->newline(-1) << "}";
@@ -874,2 +877,24 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline(-1) << "}";
+
+ vector<Dwarf_Addr>::iterator it;
+ 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 = 1;";
+ multimap<std::string,Dwarf_Addr>::iterator its;
+ for (its = s.sdt_semaphore_addr.begin();
+ its != s.sdt_semaphore_addr.end();
+ its++)
+ if (it->first == its->first)
+ {
+ // Ideally we would increment this but we don't know what probe
+ // this corresponds to.
+ s.op->newline() << "__access_process_vm (tsk, " << hex << "0x" << its->second << ", &sdt_semaphore, sizeof (sdt_semaphore), 1);" << dec;
+ }
+ s.op->newline(-1) << "}";
+ }
+
s.op->newline(-1) << "}";
@@ -1047,2 +1072,27 @@ 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;";
+ multimap<std::string,Dwarf_Addr>::iterator its;
+ for (its = s.sdt_semaphore_addr.begin();
+ its != s.sdt_semaphore_addr.end();
+ its++)
+ {
+ if (it->first == its->first)
+ {
+ s.op->newline() << "__access_process_vm (stap_utrace_probes[" << sem_idx << "].tsk, " << hex << "0x" << its->second << ", &sdt_semaphore, sizeof (sdt_semaphore), 0);" << dec;
+ s.op->newline() << "sdt_semaphore -= 1;";
+ s.op->newline() << "__access_process_vm (stap_utrace_probes[" << sem_idx << "].tsk, " << hex << "0x" << its->second << ", &sdt_semaphore, sizeof (sdt_semaphore), 1);" << dec;
+ }
+ }
+
+ s.op->newline(-1) << "}";
+ sem_idx += it->second.size() - 1;
+ }
}
diff --git a/tapsets.cxx b/tapsets.cxx
index f91d15d..6bbf761 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -3352,2 +3352,3 @@ private:
probe_point * base_loc;
+ literal_map_t const & params;
vector<derived_probe *> & results;
@@ -3367,2 +3368,3 @@ private:
void convert_probe(probe *base);
+ void record_semaphore();
void convert_location(probe *base, probe_point *location);
@@ -3375,3 +3377,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)
{
@@ -3396,2 +3398,4 @@ sdt_query::handle_query_module()
+ record_semaphore();
+
probe *new_base = new probe(*base_probe);
@@ -3561,2 +3565,23 @@ sdt_query::get_next_probe()
void
+sdt_query::record_semaphore ()
+{
+ 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);
+ sess.sdt_semaphore_addr.insert(make_pair(find_executable(process_name), sym.st_value));
+ break;
+ }
+ }
+}
+
+
+void
sdt_query::convert_probe (probe *base)
@@ -3711,3 +3736,2 @@ sdt_query::convert_location (probe *base, probe_point *location)
-
void
diff --git a/translate.cxx b/translate.cxx
index 4a6a10b..f99cf0c 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -5179,2 +5181,4 @@ translate_pass (systemtap_session& s)
s.op->newline() << "#include \"loc2c-runtime.h\" ";
+ if (! s.sdt_semaphore_addr.empty())
+ s.op->newline() << "#include \"access_process_vm.h\" ";
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Support ENABLED sdt probe macro
2009-08-10 21:03 Support ENABLED sdt probe macro Stan Cox
@ 2009-08-17 2:44 ` Stan Cox
[not found] ` <4AAFD754.9080205@redhat.com>
0 siblings, 1 reply; 3+ messages in thread
From: Stan Cox @ 2009-08-17 2:44 UTC (permalink / raw)
To: SystemTap List
[-- Attachment #1: Type: text/plain, Size: 1372 bytes --]
uprobe and utrace are now supported similarly.
uprobe
stap_uprobe_spec add tsk and sdt_sem_address, initialize
stap_uprobe_change increment the semaphore variable using
__access_process_vm
systemtap_module_exit decrement all the semaphore variables
utrace
stap_utrace_probe add tsk and sdt_sem_address, initialize
_stp_utrace_probe_cb increment the semaphore variable
systemtap_module_exit decrement all the semaphore variables
session.h add std::map<Dwarf_Addr, derived_probe*> sdt_semaphore_addr;
tapsets.cxx record it
tapsets.cxx allow for uprobe enable variable to be set and unset
tapset-utrace.cxx all for utrace enable variable to be set and unset
Here are some performance results for a looping test:
uprobe and stap
1.06user 11.03system 0:12.17elapsed 99%CPU (0avgtext+0avgdata
0maxresident)k
0inputs+1248outputs (0major+8354minor)pagefaults 0swaps
utrace and stap
0.67user 4.33system 0:05.08elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+1024outputs (0major+7945minor)pagefaults 0swaps
kprobe and stap
1.08user 0.55system 0:01.66elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+936outputs (0major+25594minor)pagefaults 0swaps
uprobe no stap
real 0m0.004s user 0m0.004s sys 0m0.000s
utrace no stap
real 0m0.004s user 0m0.002s sys 0m0.002s
kprobe no stap
real 0m0.003s user 0m0.002s sys 0m0.002s
[-- Attachment #2: ,git.diff --]
[-- Type: text/plain, Size: 17492 bytes --]
diff --git a/dtrace.in b/dtrace.in
index 168bfb1..21d313c 100755
--- a/dtrace.in
+++ b/dtrace.in
@@ -17,9 +17,17 @@ from subprocess import call
from tempfile import mkstemp
class provider:
+ semaphores_def = "\n"
+ # is the type a basic scalar type?
+ def basic_type(self, arg):
+ basic_types = [ "int","int*","long","long*","short","short int","unsigned long","char","char*","float","double" ]
+ split_arg = arg.rsplit(None,1)
+ return (split_arg[0].strip() in basic_types) & (arg.find("[") == -1)
def typedef_append(self, typedefs,this_probe,arg,c):
if (add_typedefs):
split_arg = arg.rsplit(None,1)
+ if (self.basic_type(arg)):
+ return typedefs
type_name = " %s_arg%d" % (this_probe.replace("__","_"),c)
if (len(split_arg) > 1):
typedefs += ("typedef " + arg.replace(" " + split_arg[1].split("[")[0].lstrip("*"),type_name).strip() + "; ")
@@ -28,11 +36,17 @@ class provider:
typedefs += ("typedef " + arg.strip() + type_name + "; ")
typedefs += (type_name + type_name + "_v;\n")
return typedefs
+ def semaphore_def_append(self, this_probe):
+ self.semaphores_def += "__extension__ long %s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % (this_probe)
+ def semaphore_def_write(self, file):
+ file.write(self.semaphores_def)
def generate(self, provider, header, add_typedefs):
have_provider = False
self.f = open(provider)
self.h = open(header,mode='w')
self.h.write("/* Generated by the Systemtap dtrace wrapper */\n")
+ if (build_source):
+ self.h.write("\n#define STAP_HAS_SEMAPHORES 1\n\n")
self.h.write("\n#include <sys/sdt.h>\n\n")
in_comment = False
typedefs = ""
@@ -64,6 +78,7 @@ class provider:
arg = ""
i = 0
c = 0
+ self.semaphore_def_append (this_probe)
while (i < len(args)):
if (args[i:i+1] == ","):
args_string = ('%s %s,' % (args_string, arg.strip()))
@@ -91,7 +106,8 @@ class provider:
stap_str = stap_str + ",arg%s" % (i);
i += 1
self.h.write ('/* %s (%s) */\n' % (this_probe_canon,args_string))
- self.h.write ('#define %s_ENABLED() 1\n' % this_probe_canon)
+ self.h.write ('#define %s_ENABLED() %s_semaphore\n' % (this_probe_canon,this_probe))
+ self.h.write ("__extension__ extern long %s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % (this_probe))
self.h.write (define_str + ") \\\n")
self.h.write (stap_str + ")\n\n")
elif (line.find("}") != -1 and have_provider):
@@ -176,9 +192,17 @@ if (build_header):
elif (build_source):
(basename,ext) = os.path.splitext(s_filename)
basename = os.path.basename(basename)
+
+ # create for semaphore_def_write
+ providers = provider()
+ (d,fn) = mkstemp(suffix=".h",prefix=basename)
+ providers.generate(s_filename, fn, add_typedefs)
+ os.remove(fn)
+
(d,fn) = mkstemp(suffix=".c",prefix=basename)
f = open(fn,mode='w')
f.write("static __dtrace () {}\n")
+ providers.semaphore_def_write(f)
f.close()
call(["gcc", "-fPIC", "-I.", "-I@prefix@/include", "-g", "-c", fn, "-o", os.path.basename(filename) + ".o"], shell=False)
os.remove(fn)
diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h
index f179c2a..6f3aaab 100644
--- a/includes/sys/sdt.h
+++ b/includes/sys/sdt.h
@@ -252,21 +252,31 @@ extern long int syscall (long int __sysno, ...) __THROW;
# define STAP_GUARD 0x33425250
# endif
+#ifdef STAP_HAS_SEMAPHORES
+#define STAP_SEMAPHORE(probe) \
+ if ( probe ## _semaphore )
+#else
+#define STAP_SEMAPHORE(probe) ;
+#endif
+
#include <sys/syscall.h>
#define STAP_PROBE_(probe) \
+STAP_SEMAPHORE(probe) \
do { \
- STAP_PROBE_DATA(probe,STAP_SYSCALL,0); \
+ STAP_PROBE_DATA(probe,STAP_GUARD,0); \
syscall (STAP_SYSCALL, #probe, STAP_GUARD); \
} while (0)
#define STAP_PROBE1_(probe,label,parm1) \
+STAP_SEMAPHORE(probe) \
do { \
STAP_PROBE_DATA(probe,STAP_GUARD,1); \
syscall (STAP_SYSCALL, #probe, STAP_GUARD, (size_t)parm1); \
} while (0)
#define STAP_PROBE2_(probe,label,parm1,parm2) \
+STAP_SEMAPHORE(probe) \
do { \
__extension__ struct {size_t arg1 __attribute__((aligned(8))); \
size_t arg2 __attribute__((aligned(8)));} \
@@ -276,16 +286,18 @@ do { \
} while (0)
#define STAP_PROBE3_(probe,label,parm1,parm2,parm3) \
+STAP_SEMAPHORE(probe) \
do { \
__extension__ struct {size_t arg1 __attribute__((aligned(8))); \
size_t arg2 __attribute__((aligned(8))); \
size_t arg3 __attribute__((aligned(8)));} \
stap_probe3_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3}; \
STAP_PROBE_DATA(probe,STAP_GUARD,3); \
- syscall (STAP_SYSCALL, #probe, STAP_GUARD, &stap_probe3_args); \
+ syscall (STAP_SYSCALL, #probe, STAP_GUARD, &stap_probe3_args); \
} while (0)
#define STAP_PROBE4_(probe,label,parm1,parm2,parm3,parm4) \
+STAP_SEMAPHORE(probe) \
do { \
__extension__ struct {size_t arg1 __attribute__((aligned(8))); \
size_t arg2 __attribute__((aligned(8))); \
@@ -293,10 +305,11 @@ do { \
size_t arg4 __attribute__((aligned(8)));} \
stap_probe4_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4}; \
STAP_PROBE_DATA(probe,STAP_GUARD,4); \
- syscall (STAP_SYSCALL, #probe, STAP_GUARD,&stap_probe4_args); \
+ syscall (STAP_SYSCALL, #probe, STAP_GUARD,&stap_probe4_args); \
} while (0)
#define STAP_PROBE5_(probe,label,parm1,parm2,parm3,parm4,parm5) \
+STAP_SEMAPHORE(probe) \
do { \
__extension__ struct {size_t arg1 __attribute__((aligned(8))); \
size_t arg2 __attribute__((aligned(8))); \
@@ -310,6 +323,7 @@ do { \
} while (0)
#define STAP_PROBE6_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6) \
+STAP_SEMAPHORE(probe) \
do { \
__extension__ struct {size_t arg1 __attribute__((aligned(8))); \
size_t arg2 __attribute__((aligned(8))); \
@@ -324,6 +338,7 @@ do { \
} while (0)
#define STAP_PROBE7_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \
+STAP_SEMAPHORE(probe) \
do { \
__extension__ struct {size_t arg1 __attribute__((aligned(8))); \
size_t arg2 __attribute__((aligned(8))); \
@@ -339,6 +354,7 @@ do { \
} while (0)
#define STAP_PROBE8_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \
+STAP_SEMAPHORE(probe) \
do { \
__extension__ struct {size_t arg1 __attribute__((aligned(8))); \
size_t arg2 __attribute__((aligned(8))); \
@@ -355,6 +371,7 @@ do { \
} while (0)
#define STAP_PROBE9_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \
+STAP_SEMAPHORE(probe) \
do { \
__extension__ struct {size_t arg1 __attribute__((aligned(8))); \
size_t arg2 __attribute__((aligned(8))); \
@@ -372,6 +389,7 @@ do { \
} while (0)
#define STAP_PROBE10_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \
+STAP_SEMAPHORE(probe) \
do { \
__extension__ struct {size_t arg1 __attribute__((aligned(8))); \
size_t arg2 __attribute__((aligned(8))); \
@@ -385,7 +403,7 @@ do { \
size_t arg10 __attribute__((aligned(8)));} \
stap_probe10_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \
(size_t)parm5, (size_t)parm6, (size_t)parm7, (size_t)parm8, (size_t)parm9, (size_t)parm10}; \
- STAP_PROBE_DATA(probe,STAP_GUARD,10); \
+ STAP_PROBE_DATA(probe,STAP_GUARD,10); \
syscall (STAP_SYSCALL, #probe, STAP_GUARD, &stap_probe10_args); \
} while (0)
diff --git a/session.h b/session.h
index ea91442..861f012 100644
--- a/session.h
+++ b/session.h
@@ -221,6 +221,10 @@ struct systemtap_session
void print_error_source (std::ostream&, std::string&, const token* tok);
void print_warning (const std::string& w, const token* tok = 0);
+
+ // 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
// to be cleared in the systemtap_session ctor (elaborate.cxx)
// and/or main.cxx(main).
diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx
index a07e08b..20bd4de 100644
--- a/tapset-utrace.cxx
+++ b/tapset-utrace.cxx
@@ -716,6 +716,15 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
break;
}
s.op->line() << " .engine_attached=0,";
+ map<Dwarf_Addr, derived_probe*>::iterator its;
+ 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,";
+ }
+ s.op->line() << " .tsk=0,";
s.op->line() << " },";
}
@@ -750,6 +759,8 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "struct utrace_engine_ops ops;";
s.op->newline() << "unsigned long events;";
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) << "};";
@@ -872,6 +883,15 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "break;";
s.op->indent(-1);
s.op->newline(-1) << "}";
+
+ s.op->newline() << "{";
+ 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) << "}";
// Since this engine could be attached to multiple threads, don't
@@ -1045,6 +1065,26 @@ utrace_derived_probe_group::emit_module_exit (systemtap_session& s)
s.op->newline() << "stap_utrace_detach_ops(&p->ops);";
s.op->newline(-1) << "}";
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
index f91d15d..2b59b89 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -3350,6 +3350,7 @@ private:
probe * base_probe;
probe_point * base_loc;
+ literal_map_t const & params;
vector<derived_probe *> & results;
string mark_name;
@@ -3365,6 +3366,7 @@ private:
bool get_next_probe();
void convert_probe(probe *base);
+ void record_semaphore(vector<derived_probe *> & results);
void convert_location(probe *base, probe_point *location);
};
@@ -3373,7 +3375,7 @@ sdt_query::sdt_query(probe * base_probe, probe_point * base_loc,
dwflpp & dw, literal_map_t const & params,
vector<derived_probe *> & results):
base_query(dw, params), base_probe(base_probe),
- base_loc(base_loc), results(results)
+ base_loc(base_loc), params(params), results(results)
{
assert(get_string_param(params, TOK_MARK, mark_name));
}
@@ -3415,7 +3417,11 @@ sdt_query::handle_query_module()
unsigned i = results.size();
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
{
literal_map_t params;
@@ -3428,6 +3434,7 @@ sdt_query::handle_query_module()
dwarf_query q(new_base, new_location, dw, params, results);
q.has_mark = true; // enables mid-statement probing
dw.iterate_over_modules(&query_module, &q);
+ record_semaphore(results);
}
if (sess.listing_mode)
@@ -3559,6 +3566,28 @@ 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)
{
block *b = new block;
@@ -3709,7 +3738,6 @@ sdt_query::convert_location (probe *base, probe_point *location)
base->locations.push_back(location);
}
-
void
dwarf_builder::build(systemtap_session & sess,
probe * base,
@@ -4423,6 +4451,8 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "const char *pathname;";
s.op->newline() << "const char *pp;";
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;";
s.op->newline(-1) << "} stap_uprobe_specs [] = {";
s.op->indent(1);
@@ -4442,7 +4472,16 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->line() << " .address=(unsigned long)0x" << hex << p->address << dec << "ULL,";
s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
s.op->line() << " .ph=&" << p->name << ",";
- if (p->return_p) s.op->line() << " .return_p=1,";
+ map<Dwarf_Addr, derived_probe*>::iterator its;
+ 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->address == ((struct uprobe_derived_probe*)(its->second))->address)
+ s.op->line() << " .sdt_sem_address=(unsigned long)0x" << hex << its->first << dec << "ULL,";
+ }
+ if (p->return_p) s.op->line() << " .return_p=1,";
s.op->line() << " },";
}
s.op->newline(-1) << "};";
@@ -4626,6 +4665,16 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline(-1) << "}";
s.op->newline(-1) << "}";
+ //----------
+ s.op->newline() << "{";
+ 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) << "}";
+ //----------
+
s.op->newline() << "return 0;"; // XXX: or rc?
s.op->newline(-1) << "}";
s.op->assert_0_indent();
@@ -4730,6 +4779,16 @@ uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
s.op->newline() << "struct stap_uprobe_spec *sups = &stap_uprobe_specs [sup->spec_index];";
s.op->newline() << "if (sup->spec_index < 0) continue;"; // free slot
+ //----------
+ s.op->newline() << "{";
+ 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) {";
s.op->newline(1) << "#ifdef DEBUG_UPROBES";
s.op->newline() << "printk (KERN_INFO \"-uretprobe spec %d index %d pid %d addr %p\\n\", sup->spec_index, j, sup->up.pid, (void*) sup->up.vaddr);";
diff --git a/translate.cxx b/translate.cxx
index 4a6a10b..3cc4fee 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -5177,6 +5177,8 @@ translate_pass (systemtap_session& s)
s.op->newline() << "#include <linux/version.h>";
// s.op->newline() << "#include <linux/compile.h>";
s.op->newline() << "#include \"loc2c-runtime.h\" ";
+ if (! s.sdt_semaphore_addr.empty())
+ s.op->newline() << "#include \"access_process_vm.h\" ";
// XXX: old 2.6 kernel hack
s.op->newline() << "#ifndef read_trylock";
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Support ENABLED sdt probe macro
[not found] ` <4AAFD754.9080205@redhat.com>
@ 2009-09-16 23:52 ` Stan Cox
0 siblings, 0 replies; 3+ messages in thread
From: Stan Cox @ 2009-09-16 23:52 UTC (permalink / raw)
To: SystemTap List
[-- Attachment #1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: sdt.patch --]
[-- Type: text/plain, Size: 11443 bytes --]
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\" ";
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-09-16 23:52 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-10 21:03 Support ENABLED sdt probe macro Stan Cox
2009-08-17 2:44 ` Stan Cox
[not found] ` <4AAFD754.9080205@redhat.com>
2009-09-16 23:52 ` 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).