summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfche <fche>2005-09-06 01:15:24 +0000
committerfche <fche>2005-09-06 01:15:24 +0000
commit499cf740abe8d6102f887d7b7d1cd6750bc83d44 (patch)
tree6c4fad2dcea6fbc5061061abcb19fd6d3b160ef5
parentcc9ee6059e4d3fb51c0695a8a57f75eb988a1786 (diff)
downloadsystemtap-steved-499cf740abe8d6102f887d7b7d1cd6750bc83d44.tar.gz
systemtap-steved-499cf740abe8d6102f887d7b7d1cd6750bc83d44.tar.xz
systemtap-steved-499cf740abe8d6102f887d7b7d1cd6750bc83d44.zip
2005-09-05 Frank Ch. Eigler <fche@elastic.org>
PR 1289 * translate.cxx (lex_cast_qstring): Correct "cast" of object to string containing more than one word. * tapset.cxx (lex_cast_qstring): Ditto. (dwarf_derived_module::emit_probe_entries): Emit and use a generic fault_handler.
-rw-r--r--ChangeLog11
-rw-r--r--tapsets.cxx36
-rw-r--r--translate.cxx4
3 files changed, 43 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 71bf11ea..93ea8fe2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2005-09-05 Frank Ch. Eigler <fche@elastic.org>
+ PR 1289
+ * translate.cxx (lex_cast_qstring): Correct "cast" of object
+ to string containing more than one word.
+ * tapset.cxx (lex_cast_qstring): Ditto.
+ (dwarf_derived_module::emit_probe_entries): Emit and use
+ a generic fault_handler.
+
+2005-09-05 Frank Ch. Eigler <fche@elastic.org>
+
PR 1172.
* staptree.h, staptree.cxx: Make all ::print*(), operator<<
functions take const staptree objects.
@@ -8,7 +17,7 @@
Switch to atomic_t busy flags.
(emit_module_exit): Use atomic operations for busy flag.
(visit_*): Use lex_cast_qstring for last_stmt strings.
- * tapsets.cxx (lex_cast_quoted): \-prefix double-quotes too.
+ * tapsets.cxx (lex_cast_qstring): New function.
(*::emit_probe_entries): Populate probe_point. Use atomic operations
for busy flag.
* tapset/context.stp (pp): New function.
diff --git a/tapsets.cxx b/tapsets.cxx
index de80d3a2..85e4b513 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -68,9 +68,9 @@ lex_cast_qstring(IN const & in)
{
stringstream ss;
string out, out2;
- if (!(ss << in && ss >> out))
+ if (!(ss << in))
throw runtime_error("bad lexical cast");
-
+ out = ss.str();
out2 += '"';
for (unsigned i=0; i<out.length(); i++)
{
@@ -158,7 +158,7 @@ be_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
else o->line() << "STAP_SESSION_STOPPING)";
o->newline(1) << "return;";
o->newline(-1) << "if (atomic_inc_return (&c->busy) != 1) {";
- o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\", "
+ o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\\n\", "
<< "c->probe_point, probe_point);";
o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
o->newline() << "return;";
@@ -1998,6 +1998,30 @@ dwarf_derived_probe::emit_deregistrations (translator_output* o, unsigned proben
void
dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum)
{
+ static unsigned already_emitted_fault_handler = 0;
+
+ if (! already_emitted_fault_handler)
+ {
+ o->newline() << "int stap_kprobe_fault_handler (struct kprobe* kp, "
+ << "struct pt_regs* regs, int trapnr) {";
+ o->newline(1) << "struct context *c = & contexts [smp_processor_id()];";
+ o->newline() << "printk (KERN_ERR \"systemtap probe fault\\n\");";
+ o->newline() << "printk (KERN_ERR \"cpu %d, probe %s, near %s\\n\", ";
+ o->newline(1) << "smp_processor_id(), ";
+ o->newline() << "c->probe_point ? c->probe_point : \"unknown\", ";
+ o->newline() << "c->last_stmt ? c->last_stmt : \"unknown\");";
+ o->newline() << "c->last_error = \"probe faulted\";";
+ o->newline(-1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
+
+ o->newline() << "return 0;"; // defer to kernel fault handler
+ // NB: We might prefer to use "return 1" instead, to consider
+ // the fault "handled". But we may get into an infinite loop
+ // of traps if the faulting instruction is simply restarted.
+
+ o->newline(-1) << "}";
+ already_emitted_fault_handler ++;
+ }
+
// Construct a single entry function, and a struct kprobe pointing into
// the entry function. The entry function will call the probe function.
o->newline();
@@ -2017,7 +2041,7 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum
o->newline() << "if (atomic_read (&session_state) != STAP_SESSION_RUNNING)";
o->newline(1) << "return 0;";
o->newline(-1) << "if (atomic_inc_return (&c->busy) != 1) {";
- o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\", "
+ o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\\n\", "
<< "c->probe_point, probe_point);";
o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
o->newline() << "return 0;";
@@ -2051,6 +2075,7 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum
o->newline(1) << ".kp.addr = 0," ;
o->newline() << ".handler = &"
<< probe_entry_function_name(probenum) << ",";
+ o->newline() << ".kp.fault_handler = &stap_kprobe_fault_handler,";
o->newline() << ".maxactive = 1";
o->newline(-1) << "};";
}
@@ -2060,6 +2085,7 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum
<< probe_entry_struct_kprobe_name(probenum)
<< "= {";
o->newline(1) << ".addr = 0," ;
+ o->newline() << ".fault_handler = &stap_kprobe_fault_handler,";
o->newline() << ".pre_handler = &" << probe_entry_function_name(probenum);
o->newline(-1) << "};";
}
@@ -2174,7 +2200,7 @@ timer_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
o->newline(1) << "return;";
o->newline(-1) << "if (atomic_inc_return (&c->busy) != 1) {";
- o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\", "
+ o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\\n\", "
<< "c->probe_point, probe_point);";
o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
o->newline() << "return;";
diff --git a/translate.cxx b/translate.cxx
index b71ef379..cca6cad6 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -36,9 +36,9 @@ lex_cast_qstring(IN const & in)
{
stringstream ss;
string out, out2;
- if (!(ss << in && ss >> out))
+ if (!(ss << in))
throw runtime_error("bad lexical cast");
-
+ out = ss.str();
out2 += '"';
for (unsigned i=0; i<out.length(); i++)
{