summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
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 /tapsets.cxx
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.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx36
1 files changed, 31 insertions, 5 deletions
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;";