summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS21
-rw-r--r--elaborate.cxx14
-rw-r--r--runtime/unwind.c8
-rw-r--r--tapsets.cxx60
-rw-r--r--testsuite/systemtap.base/alias-condition.exp5
-rw-r--r--testsuite/systemtap.base/alias-condition.stp26
-rw-r--r--translate.cxx10
7 files changed, 98 insertions, 46 deletions
diff --git a/NEWS b/NEWS
index 664753d3..6388cc9f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,12 +1,19 @@
* What's new
-- Module signing: If the appropriate nss libraries are available on your system,
- stap will sign each compiled module using a self-generated certificate.
- This is the first step toward extending authority to load certain modules to
- unprivileged users. For now, if the system administrator adds a certificate
- to a database of trusted signers (stap-authorize-signing-cert), modules signed
- using that certificate will be verified by staprun against tampering.
- Otherwise, you should notice no difference in the operation of stap or staprun.
+- Dwarfless syscalls: The nd_syscalls tapset is now available to probe
+ system calls without requiring kernel debugging information. All of
+ the same probepoints in the normal syscalls tapset are available with
+ an "nd_" prefix, e.g. syscall.open becomes nd_syscall.open. Most
+ syscall arguments are also available by name in nd_syscalls.
+
+- Module signing: If the appropriate nss libraries are available on your
+ system, stap will sign each compiled module using a self-generated
+ certificate. This is the first step toward extending authority to
+ load certain modules to unprivileged users. For now, if the system
+ administrator adds a certificate to a database of trusted signers
+ (stap-authorize-signing-cert), modules signed using that certificate
+ will be verified by staprun against tampering. Otherwise, you should
+ notice no difference in the operation of stap or staprun.
* What's new in version 0.9.7
diff --git a/elaborate.cxx b/elaborate.cxx
index 5cfb2bb0..f0c6c5a9 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -509,11 +509,15 @@ alias_expansion_builder
alias_derived_probe * n = new alias_derived_probe (use, location /* soon overwritten */, this->alias);
n->body = new block();
- // The new probe gets the location list of the alias (with incoming condition joined)
- n->locations = alias->locations;
- for (unsigned i=0; i<n->locations.size(); i++)
- n->locations[i]->condition = add_condition (n->locations[i]->condition,
- location->condition);
+ // The new probe gets a deep copy of the location list of
+ // the alias (with incoming condition joined)
+ n->locations.clear();
+ for (unsigned i=0; i<alias->locations.size(); i++)
+ {
+ probe_point *pp = new probe_point(*alias->locations[i]);
+ pp->condition = add_condition (pp->condition, location->condition);
+ n->locations.push_back(pp);
+ }
// the token location of the alias,
n->tok = location->tok;
diff --git a/runtime/unwind.c b/runtime/unwind.c
index 43bda717..cf0bc2f3 100644
--- a/runtime/unwind.c
+++ b/runtime/unwind.c
@@ -563,7 +563,7 @@ static u32 *_stp_search_unwind_hdr(unsigned long pc,
do {
const u8 *cur = ptr + (num / 2) * (2 * tableSize);
startLoc = read_pointer(&cur, cur + tableSize, hdr[3]);
- startLoc = adjustStartLoc(startLoc, m, s, hdr[3], true);
+ startLoc = adjustStartLoc(startLoc, m, s, hdr[3], 1);
if (pc < startLoc)
num /= 2;
else {
@@ -572,7 +572,7 @@ static u32 *_stp_search_unwind_hdr(unsigned long pc,
}
} while (startLoc && num > 1);
- if (num == 1 && (startLoc = adjustStartLoc(read_pointer(&ptr, ptr + tableSize, hdr[3]), m, s, hdr[3], true)) != 0 && pc >= startLoc)
+ if (num == 1 && (startLoc = adjustStartLoc(read_pointer(&ptr, ptr + tableSize, hdr[3]), m, s, hdr[3], 1)) != 0 && pc >= startLoc)
fde = (void *)read_pointer(&ptr, ptr + tableSize, hdr[3]);
dbug_unwind(1, "returning fde=%lx startLoc=%lx", fde, startLoc);
@@ -879,11 +879,11 @@ static int unwind(struct unwind_frame_info *frame, struct task_struct *tsk)
dbug_unwind(1, "trying debug_frame\n");
res = unwind_frame (frame, m, s, m->debug_frame,
- m->debug_frame_len, false);
+ m->debug_frame_len, 0);
if (res != 0) {
dbug_unwind(1, "debug_frame failed: %d, trying eh_frame\n", res);
res = unwind_frame (frame, m, s, m->eh_frame,
- m->eh_frame_len, true);
+ m->eh_frame_len, 1);
}
return res;
diff --git a/tapsets.cxx b/tapsets.cxx
index 265fe939..76c3c370 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -673,26 +673,25 @@ struct dwarf_builder: public derived_probe_builder
__uint64_t probe_arg;
string & mark_name;
string probe_name;
- probe_table(string & mark_name, systemtap_session & sess, dwflpp * dw, probe_point * location);
+ probe_table(string & mark_name, systemtap_session & sess, dwflpp * dw);
bool get_next_probe();
private:
bool have_probes;
systemtap_session & sess;
dwflpp* dw;
- probe_point* location;
Elf_Data *pdata;
size_t probe_scn_offset;
size_t probe_scn_addr;
};
};
-dwarf_builder::probe_table::probe_table(string& mark_name, systemtap_session & sess, dwflpp* dw, probe_point* location):
- mark_name(mark_name), sess(sess), dw(dw), location(location)
+dwarf_builder::probe_table::probe_table(string& mark_name, systemtap_session & sess, dwflpp* dw):
+ mark_name(mark_name), sess(sess), dw(dw)
{
Elf* elf;
GElf_Shdr shdr_mem;
- GElf_Shdr *shdr;
+ GElf_Shdr *shdr = NULL;
Dwarf_Addr bias;
size_t shstrndx;
@@ -716,6 +715,9 @@ dwarf_builder::probe_table::probe_table(string& mark_name, systemtap_session & s
break;
}
}
+
+ if (!have_probes)
+ return;
// Older versions put .probes section in the debuginfo dwarf file,
// so check if it actually exists, if not take the main elf file
@@ -724,6 +726,7 @@ dwarf_builder::probe_table::probe_table(string& mark_name, systemtap_session & s
elf = dwfl_module_getelf (dw->module, &bias);
dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
probe_scn = NULL;
+ have_probes = false;
while ((probe_scn = elf_nextscn (elf, probe_scn)))
{
shdr = gelf_getshdr (probe_scn, &shdr_mem);
@@ -734,6 +737,9 @@ dwarf_builder::probe_table::probe_table(string& mark_name, systemtap_session & s
}
}
+ if (!have_probes)
+ return;
+
pdata = elf_getdata_rawchunk (elf, shdr->sh_offset, shdr->sh_size, ELF_T_BYTE);
probe_scn_offset = 0;
probe_scn_addr = shdr->sh_addr;
@@ -3193,12 +3199,15 @@ dwarf_derived_probe_group::emit_module_exit (systemtap_session& s)
struct sdt_var_expanding_visitor: public var_expanding_visitor
{
- sdt_var_expanding_visitor(dwflpp& dw, string& probe_name,
+ sdt_var_expanding_visitor(string & process_name, string & probe_name,
int arg_count, bool have_reg_args):
- dw (dw), probe_name (probe_name), have_reg_args (have_reg_args),
- arg_count (arg_count) {}
- dwflpp& dw;
- string probe_name;
+ process_name (process_name), probe_name (probe_name),
+ have_reg_args (have_reg_args), arg_count (arg_count)
+ {
+ assert(!have_reg_args || (arg_count >= 0 && arg_count <= 10));
+ }
+ string & process_name;
+ string & probe_name;
bool have_reg_args;
int arg_count;
@@ -3220,13 +3229,14 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e)
provide(e);
return;
}
-
+
+ int argno = lex_cast<int>(e->base_name.substr(4));
+ if (argno < 1 || argno > arg_count)
+ throw semantic_error ("invalid argument number", e->tok);
+
bool lvalue = is_active_lvalue(e);
- string argname = e->base_name.substr(1);
functioncall *fc = new functioncall;
- int argno = lex_cast<int>(argname.substr(3));
-
if (arg_count < 6)
{
fc->function = "ulong_arg";
@@ -3270,14 +3280,7 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e)
cast->operand = fc;
cast->components = e->components;
cast->type = probe_name + "_arg" + lex_cast<string>(argno);
- string sdt_include_path = "";
- for (unsigned int i = 0; i < dw.sess.args.size(); i++)
- if (dw.sess.args[i].find("isdt=") == 0)
- sdt_include_path = dw.sess.args[i].substr(5);
- cast->module = "<" + sdt_include_path + ">";
- dwarf_builder *db = new dwarf_builder();
- dwarf_cast_expanding_visitor *v = new dwarf_cast_expanding_visitor(this->dw.sess, *db);
- v->visit_cast_op(cast);
+ cast->module = process_name;
provide(cast);
}
@@ -3314,11 +3317,10 @@ dwarf_builder::build(systemtap_session & sess,
if (sess.verbose > 3)
clog << "dwarf_builder::build for " << module_name << endl;
- if (((probe_point::component*)(location->components[1]))->functor == TOK_MARK)
+ string mark_name;
+ if (get_param(parameters, TOK_MARK, mark_name))
{
- string mark_name;
- assert (get_param(parameters, TOK_MARK, mark_name));
- probe_table probe_table(mark_name, sess, dw, location);
+ probe_table probe_table(mark_name, sess, dw);
if (! probe_table.get_next_probe())
return;
@@ -3349,7 +3351,7 @@ dwarf_builder::build(systemtap_session & sess,
<< hex << probe_table.probe_arg << dec << endl;
// Now expand the local variables in the probe body
- sdt_var_expanding_visitor svv (*dw, probe_table.mark_name,
+ sdt_var_expanding_visitor svv (module_name, probe_table.mark_name,
probe_table.probe_arg, false);
new_base->body = svv.require (new_base->body);
@@ -3406,7 +3408,7 @@ dwarf_builder::build(systemtap_session & sess,
b->statements.insert(b->statements.begin(),(statement*) is);
// Now expand the local variables in the probe body
- sdt_var_expanding_visitor svv (*dw, probe_table.mark_name,
+ sdt_var_expanding_visitor svv (module_name, probe_table.mark_name,
probe_table.probe_arg, true);
new_base->body = svv.require (new_base->body);
new_location->components[0]->functor = "kernel";
@@ -3481,7 +3483,7 @@ dwarf_builder::build(systemtap_session & sess,
b->statements.insert(b->statements.begin(),(statement*) is);
// Now expand the local variables in the probe body
- sdt_var_expanding_visitor svv (*dw, probe_table.mark_name,
+ sdt_var_expanding_visitor svv (module_name, probe_table.mark_name,
probe_table.probe_arg, true);
new_base->body = svv.require (new_base->body);
diff --git a/testsuite/systemtap.base/alias-condition.exp b/testsuite/systemtap.base/alias-condition.exp
new file mode 100644
index 00000000..58438340
--- /dev/null
+++ b/testsuite/systemtap.base/alias-condition.exp
@@ -0,0 +1,5 @@
+# Check that conditions are copied correctly across aliases
+
+set test "alias-condition"
+
+stap_run $srcdir/$subdir/$test.stp no_load $all_pass_string
diff --git a/testsuite/systemtap.base/alias-condition.stp b/testsuite/systemtap.base/alias-condition.stp
new file mode 100644
index 00000000..89708886
--- /dev/null
+++ b/testsuite/systemtap.base/alias-condition.stp
@@ -0,0 +1,26 @@
+/*
+ * alias-condition.stp
+ *
+ * Check that conditions are copied correctly across aliases
+ */
+
+/* x should be incremented exactly once */
+global x = 0
+probe foo = begin { }
+probe foo if (x < 0), foo { ++x }
+
+probe begin(1)
+{
+ println("systemtap starting probe")
+ exit()
+}
+
+probe end
+{
+ println("systemtap ending probe")
+ if ( x != 1 ) {
+ println("systemtap test failure")
+ } else {
+ println("systemtap test success")
+ }
+}
diff --git a/translate.cxx b/translate.cxx
index 060013bb..d9d99507 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -1249,6 +1249,14 @@ c_unparser::emit_module_init ()
o->newline() << "synchronize_sched();";
o->newline() << "#endif";
+ // In case gettimeofday was started, it needs to be stopped
+ o->newline() << "#ifdef STAP_NEED_GETTIMEOFDAY";
+ o->newline() << " _stp_kill_time();"; // An error is no cause to hurry...
+ o->newline() << "#endif";
+
+ // Free up the context memory after an error too
+ o->newline() << "free_percpu (contexts);";
+
o->newline() << "return rc;";
o->newline(-1) << "}\n";
}
@@ -4903,7 +4911,7 @@ emit_symbol_data (systemtap_session& s)
ofstream kallsyms_out ((s.tmpdir + "/" + symfile).c_str());
- unwindsym_dump_context ctx = { s, kallsyms_out, 0, -1, s.unwindsym_modules };
+ unwindsym_dump_context ctx = { s, kallsyms_out, 0, ~0, s.unwindsym_modules };
// Micro optimization, mainly to speed up tiny regression tests
// using just begin probe.