summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xdtrace.in19
-rw-r--r--includes/sys/sdt.h2
-rw-r--r--tapset-utrace.cxx102
-rw-r--r--tapsets.cxx179
-rw-r--r--testsuite/lib/systemtap.exp4
-rw-r--r--testsuite/systemtap.base/dtrace.exp72
-rw-r--r--testsuite/systemtap.base/sdt_misc.exp101
-rw-r--r--util.cxx4
-rw-r--r--util.h3
9 files changed, 344 insertions, 142 deletions
diff --git a/dtrace.in b/dtrace.in
index 74d70e77..3be05038 100755
--- a/dtrace.in
+++ b/dtrace.in
@@ -46,7 +46,7 @@ class provider:
self.f = open(provider)
self.h = open(header,mode='w')
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")
in_comment = False
typedefs = ""
@@ -107,7 +107,7 @@ class provider:
i += 1
self.h.write ('/* %s (%s) */\n' % (this_probe_canon,args_string))
# 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
self.h.write ("__extension__ extern unsigned short %s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % (this_probe))
self.h.write (define_str + ") \\\n")
@@ -120,13 +120,15 @@ class provider:
def usage ():
- print "Usage " + sys.argv[0] + " [--help] [-h | -G] -s File.d [-o File]"
+ print "Usage " + sys.argv[0] + " [--help] [-h | -G] [-C [-I<Path>]] -s File.d [-o <File>]"
def help ():
usage()
print "Where -h builds a systemtap header file from the .d file"
+ print " -C when used with -h, also run cpp preprocessor"
print " -o specifies an explicit output file name,"
- print " The default for -G is file.o and -h is file.h"
+ print " the default for -G is file.o and -h is file.h"
+ print " -I when running cpp pass through this -I include Path"
print " -s specifies the name of the .d input file"
print " -G builds a stub file.o from file.d,"
print " which is required by some packages that use dtrace."
@@ -159,6 +161,8 @@ keep_temps = False
use_cpp = False
h_ext = '.h'
filename = ""
+s_filename = ""
+includes = []
while (i < len (sys.argv)):
if (sys.argv[i] == "-o"):
i += 1
@@ -170,6 +174,8 @@ while (i < len (sys.argv)):
use_cpp = True
elif (sys.argv[i] == "-h"):
build_header = True
+ elif (sys.argv[i].startswith("-I")):
+ includes.append(sys.argv[i])
elif (sys.argv[i] == "-G"):
build_source = True
elif (sys.argv[i] == "-k"):
@@ -185,9 +191,10 @@ if (build_header == False and build_source == False):
if (s_filename != "" and use_cpp):
(d,fn) = mkstemp(suffix=".d")
- retcode = call(["cpp", s_filename, fn])
+ args = ['cpp'] + includes + [s_filename, fn]
+ retcode = call(args)
if (retcode != 0):
- print "\"cpp s_filename\" failed"
+ print "\"cpp includes s_filename\" failed"
usage()
sys.exit(1)
s_filename = fn
diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h
index 3847c497..d85d8e2e 100644
--- a/includes/sys/sdt.h
+++ b/includes/sys/sdt.h
@@ -40,7 +40,7 @@
#define STAP_PROBE_DATA(probe, guard, arg) \
STAP_PROBE_DATA_(#probe,guard,arg)
-#if defined STAP_HAS_SEMAPHORES && defined EXPERIMENTAL_UTRACE_SDT
+#if defined STAP_HAS_SEMAPHORES && ! defined EXPERIMENTAL_KPROBE_SDT
#define STAP_SEMAPHORE(probe) \
if (__builtin_expect ( probe ## _semaphore , 0))
#else
diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx
index 795d88b7..bd668a2b 100644
--- a/tapset-utrace.cxx
+++ b/tapset-utrace.cxx
@@ -29,6 +29,7 @@ static const string TOK_END("end");
static const string TOK_THREAD("thread");
static const string TOK_SYSCALL("syscall");
static const string TOK_RETURN("return");
+static const string TOK_LIBRARY("library");
// ------------------------------------------------------------------------
@@ -52,13 +53,15 @@ struct utrace_derived_probe: public derived_probe
{
bool has_path;
string path;
+ bool has_library;
+ string library;
int64_t pid;
enum utrace_derived_probe_flags flags;
bool target_symbol_seen;
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);
void emit_unprivileged_assertion (translator_output*);
@@ -115,10 +118,10 @@ struct utrace_var_expanding_visitor: public var_expanding_visitor
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)
{
if (s.kernel_config["CONFIG_UTRACE"] != string("y"))
@@ -599,9 +602,11 @@ struct utrace_builder: public derived_probe_builder
vector<derived_probe *> & finished_results)
{
string path;
+ string lib;
int64_t pid;
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);
enum utrace_derived_probe_flags flags = UDPF_NONE;
@@ -647,9 +652,11 @@ struct utrace_builder: public derived_probe_builder
// XXX: could we use /proc/$pid/exe in unwindsym_modules and elsewhere?
}
+ if (has_lib)
+ lib = find_executable (lib, "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));
}
@@ -750,11 +757,25 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
s.op->line() << " .engine_attached=0,";
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->has_library && 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() << " },";
+ }
}
@@ -789,7 +810,11 @@ 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() << "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) << "};";
@@ -913,15 +938,23 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->indent(-1);
s.op->newline(-1) << "}";
+ s.op->newline() << "if (p->sdt_sem_offset && 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() << "p->sdt_sem_address = p->sdt_sem_offset;";
+ s.op->newline(-1) << "}";
+
+ // Before writing to the semaphore, we need to check for VM_WRITE access.
s.op->newline() << "if (p->sdt_sem_address != 0) {";
s.op->newline(1) << "size_t sdt_semaphore;";
// XXX p could get registered to more than one task!
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(-1) << "}";
s.op->newline(-1) << "}";
// Since this engine could be attached to multiple threads, don't
@@ -985,6 +1018,44 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "return rc;";
s.op->newline(-1) << "}";
+ // 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() << "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 = addr + 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(-1) << "}";
+
+ s.op->newline() << "if (p->sdt_sem_address) {";
+ s.op->newline(1) << "unsigned short sdt_semaphore = 0;"; // NB: fixed size
+ 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[] = {";
s.op->indent(1);
@@ -1055,14 +1126,15 @@ utrace_derived_probe_group::emit_module_exit (systemtap_session& s)
s.op->newline() << "if (p->engine_attached) {";
s.op->newline(1) << "stap_utrace_detach_ops(&p->ops);";
+ // Before writing to the semaphore, we need to check for VM_WRITE access.
s.op->newline() << "if (p->sdt_sem_address) {";
s.op->newline(1) << "size_t sdt_semaphore;";
// 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 --;";
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) << "}";
s.op->newline(-1) << "}";
s.op->newline(-1) << "}";
@@ -1094,6 +1166,8 @@ register_tapset_utrace(systemtap_session& s)
->bind(builder);
roots[i]->bind(TOK_SYSCALL)->bind(TOK_RETURN)
->bind(builder);
+ roots[i]->bind_str(TOK_LIBRARY)->bind(TOK_SYSCALL)
+ ->bind(builder);
}
}
diff --git a/tapsets.cxx b/tapsets.cxx
index 51f1ccc9..bad72091 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -260,6 +260,7 @@ static const string TOK_PROCESS("process");
static const string TOK_MARK("mark");
static const string TOK_TRACE("trace");
static const string TOK_LABEL("label");
+static const string TOK_LIBRARY("library");
static int query_cu (Dwarf_Die * cudie, void * arg);
static void query_addr(Dwarf_Addr addr, dwarf_query *q);
@@ -349,8 +350,10 @@ struct dwarf_derived_probe: public derived_probe
string module;
string section;
Dwarf_Addr addr;
+ string path;
bool has_return;
bool has_maxactive;
+ bool has_library;
long maxactive_val;
bool access_vars;
@@ -460,7 +463,9 @@ struct base_query
bool has_kernel;
bool has_module;
bool has_process;
+ bool has_library;
string module_val; // has_kernel => module_val = "kernel"
+ string path; // executable path if module is a .so
virtual void handle_query_module() = 0;
};
@@ -478,8 +483,15 @@ base_query::base_query(dwflpp & dw, literal_map_t const & params):
has_process = false;
else
{
+ string library_name;
has_process = get_string_param(params, TOK_PROCESS, module_val);
- if (has_process)
+ has_library = get_string_param (params, TOK_LIBRARY, library_name);
+ if (has_library)
+ {
+ path = find_executable (module_val);
+ module_val = find_executable (library_name, "LD_LIBRARY_PATH");
+ }
+ else if (has_process)
module_val = find_executable (module_val);
}
@@ -2840,11 +2852,13 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
Dwarf_Die* scope_die /* may be null */)
: derived_probe (q.base_probe, new probe_point(*q.base_loc) /* .components soon rewritten */ ),
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)
{
if (q.has_process)
@@ -3140,6 +3154,8 @@ dwarf_derived_probe::register_patterns(systemtap_session& s)
register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw);
root->bind_str(TOK_PROCESS)->bind_str(TOK_FUNCTION)->bind_str(TOK_LABEL)
->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)
->bind(dw);
root->bind_str(TOK_PROCESS)->bind_num(TOK_MARK)
@@ -3983,46 +3999,52 @@ sdt_query::convert_probe (probe *base)
void
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;
+ }
base->locations.clear();
base->locations.push_back(location);
@@ -4053,7 +4075,11 @@ dwarf_builder::build(systemtap_session & sess,
}
else if (get_param (parameters, TOK_PROCESS, module_name))
{
- module_name = find_executable (module_name); // canonicalize it
+ string library_name;
+ if (get_param (parameters, TOK_LIBRARY, library_name))
+ module_name = find_executable (library_name, "LD_LIBRARY_PATH");
+ else
+ module_name = find_executable (module_name); // canonicalize it
if (sess.kernel_config["CONFIG_UTRACE"] != string("y"))
throw semantic_error ("process probes not available without kernel CONFIG_UTRACE");
@@ -4557,7 +4583,6 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
// too big to embed in the initialized .data stap_uprobe_spec array.
s.op->newline() << "static struct stap_uprobe {";
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
s.op->newline(-1) << "} stap_uprobes [MAXUPROBES];"; // XXX: consider a slab cache or somesuch
s.op->newline() << "DEFINE_MUTEX(stap_uprobes_lock);"; // protects against concurrent registration/unregistration
@@ -4600,6 +4625,8 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
}
if (p->section != ".absolute") // ET_DYN
{
+ if (p->has_library && p->sdt_semaphore_addr != 0)
+ s.op->line() << " .procname=\"" << p->path << "\", ";
s.op->line() << " .mmap_callback=&stap_uprobe_mmap_found, ";
s.op->line() << " .munmap_callback=&stap_uprobe_munmap_found, ";
}
@@ -4615,13 +4642,17 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->assert_0_indent();
+ 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
s.op->newline(1) << "unsigned tfi;"; // index into stap_uprobe_finders[]
s.op->newline() << "unsigned return_p:1;";
s.op->newline() << "unsigned long address;";
s.op->newline() << "const char *pp;";
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
s.op->indent(1);
for (unsigned i =0; i<probes.size(); i++)
@@ -4637,7 +4668,7 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->line() << " .ph=&" << p->name << ",";
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,";
if (p->has_return)
@@ -4706,7 +4737,7 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
// unregistration.
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);";
s.op->newline() << "int spec_index;";
@@ -4757,6 +4788,20 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
// was full (registration; MAXUPROBES) or that no matching entry was
// found (unregistration; should not happen).
+ 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] = relocation + 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) {";
s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[i];";
s.op->newline() << "if (sups->return_p) {";
@@ -4770,23 +4815,23 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "sup->up.handler = &enter_uprobe_probe;";
s.op->newline() << "rc = register_uprobe (& sup->up);";
- // 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)) {";
+ // We have an executable or a writeable segment of a .so
+ s.op->newline(1) << "if (vm_flags == 0 || 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(-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) << "}";
s.op->newline(-1) << "}";
- s.op->newline() << "if (rc) {"; // failed to register
+
+ s.op->newline() << "if (rc && !(vm_flags & VM_WRITE)) {"; // failed to register
s.op->newline(1) << "_stp_warn (\"u*probe failed %s[%d] '%s' addr %p rc %d\\n\", tsk->comm, tsk->tgid, sups->pp, (void*)(relocation + sups->address), rc);";
// NB: we need to release this slot, so we need to borrow the mutex temporarily.
s.op->newline() << "mutex_lock (& stap_uprobes_lock);";
@@ -4919,7 +4964,7 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
// ET_EXEC events are modeled as if shlib events, but with 0 relocation bases
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";
s.op->newline(1) << "return stap_uprobe_change_minus (tsk, 0, TASK_SIZE, stf);";
s.op->indent(-1);
@@ -4932,18 +4977,19 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "static int stap_uprobe_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) << "const struct stap_uprobe_tf *stf = container_of(tgt, struct stap_uprobe_tf, finder);";
// 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;";
s.op->newline() << "#ifdef DEBUG_TASK_FINDER_VMA";
s.op->newline() << "_stp_dbug (__FUNCTION__,__LINE__, \"+mmap pid %d path %s addr %p length %u offset %p stf %p %p path %s\\n\", "
<< "tsk->tgid, path, (void *) addr, (unsigned)length, (void*) offset, tgt, stf, stf->pathname);";
s.op->newline() << "#endif";
- 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) << "}";
s.op->assert_0_indent();
@@ -5021,7 +5067,7 @@ uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
s.op->newline() << "if (sup->spec_index < 0) continue;"; // free slot
// 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
s.op->newline() << "pid_t pid = (sups->return_p ? sup->urp.u.pid : sup->up.pid);";
s.op->newline() << "struct task_struct *tsk;";
@@ -5041,12 +5087,13 @@ uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
s.op->newline() << "#endif /* 2.6.31 */";
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!
// XXX: need to analyze possibility of race condition
s.op->newline(-1) << "}";
diff --git a/testsuite/lib/systemtap.exp b/testsuite/lib/systemtap.exp
index f16facc2..13e6d1a2 100644
--- a/testsuite/lib/systemtap.exp
+++ b/testsuite/lib/systemtap.exp
@@ -175,7 +175,9 @@ proc shutdown_server {} {
}
# Remove the temporary stap script
- exec /bin/rm -fr $net_path
+ if [file exists $net_path] {
+ exec /bin/rm -fr $net_path
+ }
}
proc get_system_info {} {
diff --git a/testsuite/systemtap.base/dtrace.exp b/testsuite/systemtap.base/dtrace.exp
index f4cac5aa..f68af4f5 100644
--- a/testsuite/systemtap.base/dtrace.exp
+++ b/testsuite/systemtap.base/dtrace.exp
@@ -8,7 +8,7 @@ if {[installtest_p]} {
set dtrace ../dtrace
}
-exec mkdir /tmp/dtrace
+exec mkdir -p /tmp/dtrace
set dpath "/tmp/dtrace/test.d"
set fp [open $dpath "w"]
@@ -23,11 +23,34 @@ provider tstsyscall
"
close $fp
+exec mkdir -p /tmp/dtrace_inc
+set ipath "/tmp/dtrace_inc/dtest.h"
+set $fp [open $ipath "w"]
+puts $fp "
+#define INT16 short
+#define INT32 int
+"
+close $fp
+
+set idpath "/tmp/dtrace/itest.d"
+set $fp [open $idpath "w"]
+puts $fp "
+#include <dtest.h>
+
+provider tstsyscall
+{
+ probe test(INT16 arg1, INT32 arg2, INT32 arg3, INT32 arg4, struct astruct arg5)
+}
+"
+close $fp
+
+set incpath "/tmp/dtrace_inc"
+
# -----------------------------------------------------------------
# test command line option and file handling
verbose -log "$dtrace -G -s $dpath -o XXX.o"
-exec $dtrace -G -s $dpath -o XXX.o
+catch {exec $dtrace -G -s $dpath -o XXX.o}
if {[file exists XXX.o]} then {
pass "dtrace -G -o XXX.o"
} else {
@@ -36,7 +59,7 @@ if {[file exists XXX.o]} then {
exec rm -f XXX.o
verbose -log "$dtrace -G -s $dpath -o XXX"
-exec $dtrace -G -s $dpath -o XXX
+catch {exec $dtrace -G -s $dpath -o XXX}
if {[file exists XXX.o]} then {
pass "dtrace -G -o XXX"
} else {
@@ -45,7 +68,7 @@ if {[file exists XXX.o]} then {
exec rm -f XXX.o
verbose -log "$dtrace -h -s $dpath -o XXX.h"
-exec $dtrace -h -s $dpath -o XXX.h
+catch {exec $dtrace -h -s $dpath -o XXX.h}
if {[file exists XXX.h]} then {
pass "dtrace -h -o XXX.h"
} else {
@@ -54,7 +77,7 @@ if {[file exists XXX.h]} then {
exec rm -f XXX.h
verbose -log "$dtrace -h -s $dpath -o XXX"
-exec $dtrace -h -s $dpath -o XXX
+catch {exec $dtrace -h -s $dpath -o XXX}
if {[file exists XXX]} then {
pass "dtrace -h -o XXX"
} else {
@@ -63,7 +86,7 @@ if {[file exists XXX]} then {
exec rm -f XXX
verbose -log "$dtrace -G -s $dpath -o /tmp/XXX.o"
-exec $dtrace -G -s $dpath -o /tmp/XXX.o
+catch {exec $dtrace -G -s $dpath -o /tmp/XXX.o}
if {[file exists /tmp/XXX.o]} then {
pass "dtrace -G -o /tmp/XXX.o"
} else {
@@ -72,7 +95,7 @@ if {[file exists /tmp/XXX.o]} then {
exec rm -f /tmp/XXX.o
verbose -log "$dtrace -G -s $dpath -o /tmp/XXX"
-exec $dtrace -G -s $dpath -o /tmp/XXX
+catch {exec $dtrace -G -s $dpath -o /tmp/XXX}
if {[file exists /tmp/XXX.o]} then {
pass "dtrace -G -o /tmp/XXX.o"
} else {
@@ -81,7 +104,7 @@ if {[file exists /tmp/XXX.o]} then {
exec rm -f /tmp/XXX.o
verbose -log "$dtrace -h -s $dpath -o /tmp/XXX.h"
-exec $dtrace -h -s $dpath -o /tmp/XXX.h
+catch {exec $dtrace -h -s $dpath -o /tmp/XXX.h}
if {[file exists /tmp/XXX.h]} then {
pass "dtrace -h -o /tmp/XXX.h"
} else {
@@ -90,7 +113,7 @@ if {[file exists /tmp/XXX.h]} then {
exec rm -f /tmp/XXX.h
verbose -log "$dtrace -h -s $dpath -o /tmp/XXX"
-exec $dtrace -h -s $dpath -o /tmp/XXX
+catch {exec $dtrace -h -s $dpath -o /tmp/XXX}
if {[file exists /tmp/XXX]} then {
pass "dtrace -h -o /tmp/XXX"
} else {
@@ -99,7 +122,7 @@ if {[file exists /tmp/XXX]} then {
exec rm -f /tmp/XXX
verbose -log "$dtrace -G -s $dpath"
-exec $dtrace -G -s $dpath
+catch {exec $dtrace -G -s $dpath}
if {[file exists test.o]} then {
pass "dtrace -G"
} else {
@@ -108,7 +131,7 @@ if {[file exists test.o]} then {
exec rm -f test.o
verbose -log "$dtrace -h -s $dpath"
-exec $dtrace -h -s $dpath
+catch {exec $dtrace -h -s $dpath}
if {[file exists test.h]} then {
pass "dtrace -h"
} else {
@@ -118,7 +141,7 @@ exec rm -f test.o
set ok 0
verbose -log "$dtrace -C -h -s $dpath -o XXX.h"
-exec $dtrace -C -h -s $dpath -o XXX.h
+catch {exec $dtrace -C -h -s $dpath -o XXX.h}
spawn cat XXX.h
expect {
"short arg1, int arg2, int arg3, int arg4" {incr ok}
@@ -130,5 +153,28 @@ if { $ok != 0} {
}
exec rm -f XXX.h
-exec /bin/rm -r /tmp/dtrace
+set ok 0
+verbose -log "$dtrace -C -I$incpath -h -s $idpath -o XXX.h"
+catch {exec $dtrace -C -I$incpath -h -s $idpath -o XXX.h}
+spawn cat XXX.h
+expect {
+ "short arg1, int arg2, int arg3, int arg4" {incr ok}
+}
+if { $ok != 0} {
+ pass "dtrace -C -Iincpath -h -o XXX.h"
+} else {
+ fail "dtrace -C -Iincpath -h -o XXX.h"
+}
+exec rm -f XXX.h
+
+verbose -log "$dtrace -I$incpath -G -s $idpath"
+catch {exec $dtrace -G -s $dpath}
+if {[file exists test.o]} then {
+ pass "dtrace -Iincpath -G"
+} else {
+ fail "dtrace -Iincpath -G"
+}
+exec rm -f test.o
+
+exec /bin/rm -r /tmp/dtrace /tmp/dtrace_inc
# -----------------------------------------------------------------
diff --git a/testsuite/systemtap.base/sdt_misc.exp b/testsuite/systemtap.base/sdt_misc.exp
index 4e6f953f..062181a5 100644
--- a/testsuite/systemtap.base/sdt_misc.exp
+++ b/testsuite/systemtap.base/sdt_misc.exp
@@ -3,20 +3,17 @@ set test "sdt_misc"
# Test miscellaneous features of .mark probes
# Compile a C program to use as the user-space probing target
-set sup_srcpath "[pwd]/static_user_markers.c"
-set sup_exepath "[pwd]/static_user_markers.x"
-set sup_sopath "[pwd]/libsdt.so"
-set supcplus_exepath "[pwd]/static_user_markers_cplus.x"
+set sup_srcpath "[pwd]/sdt_misc.c"
+set supcplus_exepath "[pwd]/sdt_misc_cplus.x"
set fp [open $sup_srcpath "w"]
puts $fp "
#include <stdlib.h>
-#define USE_STAP_PROBE 1
-#include \"static_user_markers_.h\"
+#include \"sdt_misc_.h\"
void
bar (int i)
{
- STATIC_USER_MARKERS_TEST_PROBE_2(i);
+ SDT_MISC_TEST_PROBE_2(i);
if (i == 0)
i = 1000;
STAP_PROBE1(static_uprobes,test_probe_2,i);
@@ -28,7 +25,7 @@ baz (int i, char* s)
STAP_PROBE1(static_uprobes,test_probe_0,i);
if (i == 0)
i = 1000;
- STATIC_USER_MARKERS_TEST_PROBE_3(i,s);
+ SDT_MISC_TEST_PROBE_3(i,s);
}
void
@@ -42,7 +39,7 @@ buz (int parm)
struct astruct bstruct = {parm, parm + 1};
if (parm == 0)
parm = 1000;
- DTRACE_PROBE1(static_user_markers,test_probe_4,&bstruct);
+ DTRACE_PROBE1(sdt_misc,test_probe_4,&bstruct);
}
#ifndef NO_MAIN
@@ -57,34 +54,50 @@ main ()
"
close $fp
-set sup_stppath "[pwd]/static_user_markers.stp"
+set sup_stppath "[pwd]/sdt_misc.stp"
set fp [open $sup_stppath "w"]
puts $fp "
-probe process(\"static_user_markers.x\").mark(\"test_probe_0\")
+%( \$# > 1 %?
+probe process(@1).library(@2).mark(\"test_probe_0\")
+%:
+probe process(@1).mark(\"test_probe_0\")
+%)
{
printf(\"In %s probe %#x\\n\", \$\$name, \$arg1)
}
-probe process(\"static_user_markers.x\").mark(\"test_probe_2\")
+%( \$# > 1 %?
+probe process(@1).library(@2).mark(\"test_probe_2\")
+%:
+probe process(@1).mark(\"test_probe_2\")
+%)
{
printf(\"In %s probe %#x\\n\", \$\$name, \$arg1)
}
-probe process(\"static_user_markers.x\").mark(\"test_probe_3\")
+%( \$# > 1 %?
+probe process(@1).library(@2).mark(\"test_probe_3\")
+%:
+probe process(@1).mark(\"test_probe_3\")
+%)
{
printf(\"In %s probe %#x %#x\\n\", \$\$name, \$arg1, \$arg2)
}
-probe process(\"static_user_markers.x\").mark(\"test_probe_4\")
+%( \$# > 1 %?
+probe process(@1).library(@2).mark(\"test_probe_4\")
+%:
+probe process(@1).mark(\"test_probe_4\")
+%)
{
printf(\"In %s dtrace probe %#x %#x\\n\", \$\$name, \$arg1->a, \$arg1->b)
}
"
close $fp
-set sup_dpath "[pwd]/static_user_markers_.d"
-set sup_hpath "[pwd]/static_user_markers_.h"
-set sup_opath "[pwd]/static_user_markers_.o"
+set sup_dpath "[pwd]/sdt_misc_.d"
+set sup_hpath "[pwd]/sdt_misc_.h"
+set sup_opath "[pwd]/sdt_misc_.o"
set fp [open $sup_dpath "w"]
puts $fp "
-provider static_user_markers {
+provider sdt_misc {
probe test_probe_0 ();
probe test_probe_2 (int i);
probe test_probe_3 (int i, char* x);
@@ -130,7 +143,7 @@ set pbtype_mssgs {{uprobe} {utrace} {kprobe}}
for {set i 0} {$i < [llength $pbtype_flags]} {incr i} {
set pbtype_flag [lindex $pbtype_flags $i]
set pbtype_mssg [lindex $pbtype_mssgs $i]
-set testprog "sdt.c.exe.$i"
+set sup_exepath "[pwd]/sdt_misc-$pbtype_mssg.x"
set sup_flags "additional_flags=-I$srcdir/../includes/sys"
set sup_flags "$sup_flags additional_flags=-I$sdtdir"
@@ -163,7 +176,7 @@ if {![utrace_p]} {
set ok 0
verbose -log "spawn stap -c $sup_exepath $sup_stppath"
-spawn stap -c $sup_exepath $sup_stppath
+spawn stap -c $sup_exepath $sup_stppath $sup_exepath
expect {
-timeout 180
-re {In test_probe_2 probe 0x2} { incr ok; exp_continue }
@@ -198,17 +211,17 @@ set ok 0
set fail "types"
verbose -log "spawn stap -c ./sdt_types.x $srcdir/$subdir/sdt_types.stp ./sdt_types.x"
spawn stap -c ./sdt_types.x $srcdir/$subdir/sdt_types.stp ./sdt_types.x
+
expect {
-timeout 180
-re {FAIL: [a-z_]+var} { regexp " .*$" $expect_out(0,string) s;
incr ok; set fail "$fail $s"; exp_continue }
- timeout { fail "$test (timeout) }
+ timeout { fail "$test (timeout)" }
eof { }
}
wait
-set pbtype_mssgs {{uprobe} {utrace} {kprobe}}
if { $ok != 0} {
if { $pbtype_mssg == "uprobe" } {
fail "$test $fail $pbtype_mssg"
@@ -222,7 +235,7 @@ if { $ok != 0} {
# Test probe in shared object
-set sup_srcmainpath "[pwd]/static_user_markers_.c"
+set sup_srcmainpath "[pwd]/sdt_misc_.c"
set fp [open $sup_srcmainpath "w"]
puts $fp "
int
@@ -238,9 +251,11 @@ close $fp
set sup_flags "$sup_flags additional_flags=-shared"
set sup_flags "$sup_flags additional_flags=-fPIC"
set sup_flags "$sup_flags additional_flags=-DNO_MAIN"
+set sup_sopath "[pwd]/libsdt-$pbtype_mssg.so"
+set sup_exepath "[pwd]/sdt_misc-$pbtype_mssg-shared.x"
set res0 [target_compile $sup_srcpath $sup_sopath executable $sup_flags ]
set sup0_flags "additional_flags=-g additional_flags=-Wl,-rpath,[pwd]"
-set sup0_flags "$sup0_flags additional_flags=-L[pwd] additional_flags=-lsdt"
+set sup0_flags "$sup0_flags additional_flags=-L[pwd] additional_flags=-lsdt-$pbtype_mssg"
set res [target_compile $sup_srcmainpath $sup_exepath executable $sup0_flags ]
if { $res0 != "" || $res != "" } {
verbose "target_compile failed: $res0 $res" 2
@@ -254,21 +269,28 @@ if { $res0 != "" || $res != "" } {
}
set ok 0
-# verbose -log "stap -c $sup_exepath -e probe process(\"$sup_sopath\").mark(\"test_probe_2\") {printf(\"In %s probe %#x\\n\", \$\$name, \$arg1)}"
-# spawn stap -c $sup_exepath -e "probe process(\"$sup_sopath\").mark(\"test_probe_2\") {printf(\"In %s probe %#x\\n\", \$\$name, \$arg1)}"
-# expect {
-# -timeout 180
-# -re {In test_probe_2 probe 0x2} { incr ok; exp_continue }
-# timeout { fail "$test (timeout)" }
-# eof { }
-# }
-# wait
-
-if {$ok == 2} {
+verbose -log "spawn stap -c $sup_exepath $sup_stppath $sup_exepath $sup_sopath"
+if { $pbtype_mssg != "kprobe" } {
+ spawn stap -c $sup_exepath $sup_stppath $sup_exepath $sup_sopath
+} else {
+ spawn stap -c $sup_exepath $sup_stppath $sup_sopath
+}
+expect {
+ -timeout 180
+ -re {In test_probe_2 probe 0x2} { incr ok; exp_continue }
+ -re {In test_probe_0 probe 0x3} { incr ok; exp_continue }
+ -re {In test_probe_3 probe 0x3 0x[0-9a-f][0-9a-f]} { incr ok; exp_continue }
+ -re {In test_probe_4 dtrace probe 0x4 0x5} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+
+wait
+
+if {$ok == 5} {
pass "$test shared $pbtype_mssg"
} else {
-# fail "$test shared ($ok) $pbtype_mssg"
- xfail "$test shared ($ok) $pbtype_mssg"
+ fail "$test ($ok) shared $pbtype_mssg"
}
# Test .mark probe wildcard matching
@@ -288,9 +310,12 @@ if { $ok == 45 } {
fail "$test wildcard ($ok) $pbtype_mssg"
}
+if { $verbose == 0 } {
+ catch {exec rm -f libsdt-$pbtype_mssg.so sdt_misc-$pbtype_mssg.x sdt_misc-$pbtype_mssg-shared.x }
+}
# for {set i 0}
}
if { $verbose == 0 } {
-catch {exec rm -f $sup_srcpath $sup_exepath $sup_sopath $supcplus_exepath $sup_dpath $sup_hpath $sup_opath $sup_stppath $sdt_types.x $sup_srcmainpath}
+ catch {exec rm -f sdt_misc_.c sdt_misc.c sdt_misc_.d sdt_misc_.h sdt_misc_.o sdt_misc.stp sdt_types.x}
}
diff --git a/util.cxx b/util.cxx
index bffeb04e..736e5a30 100644
--- a/util.cxx
+++ b/util.cxx
@@ -244,7 +244,7 @@ tokenize(const string& str, vector<string>& tokens,
// same policy as execvp(). A program name not containing a slash
// will be searched along the $PATH.
-string find_executable(const string& name)
+string find_executable(const string& name, const string& env_path)
{
string retpath;
@@ -259,7 +259,7 @@ string find_executable(const string& name)
}
else // Nope, search $PATH.
{
- char *path = getenv("PATH");
+ char *path = getenv(env_path.c_str());
if (path)
{
// Split PATH up.
diff --git a/util.h b/util.h
index bb6c71bc..8fc64cbd 100644
--- a/util.h
+++ b/util.h
@@ -15,7 +15,8 @@ int remove_file_or_dir(const char *dir);
bool in_group_id (gid_t target_gid);
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);
std::string git_revision(const std::string& path);
int stap_system(int verbose, const std::string& command);