summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
authorDavid Smith <dsmith@redhat.com>2008-08-19 12:12:06 -0500
committerDavid Smith <dsmith@redhat.com>2008-08-19 12:12:06 -0500
commit930a1798154b9c1caf27009825b2b165ef577a1e (patch)
tree492977cab280f2b805bf760ec4108955a9af23d4 /tapsets.cxx
parent480f38d3275c87ac5b58a95dd127633babfc7374 (diff)
downloadsystemtap-steved-930a1798154b9c1caf27009825b2b165ef577a1e.tar.gz
systemtap-steved-930a1798154b9c1caf27009825b2b165ef577a1e.tar.xz
systemtap-steved-930a1798154b9c1caf27009825b2b165ef577a1e.zip
PR 6841 fix.
2008-08-19 David Smith <dsmith@redhat.com> PR 6841 * tapsets.cxx (utrace_derived_probe_group::emit_probe_decl): Workaround utrace bug by quiescing threads before attaching a utrace syscall engine to them. (utrace_derived_probe_group::emit_module_decls): Emit quiesce handler. 2008-08-19 David Smith <dsmith@redhat.com> PR 6841 * task_finder.c (__stp_utrace_task_finder_target_quiesce): Quiesces thread before turning on syscall tracing.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx30
1 files changed, 25 insertions, 5 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 39fc0074..36601b01 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -6096,17 +6096,19 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
// For UDPF_SYSCALL/UDPF_SYSCALL_RETURN probes, the .report_death
// handler isn't strictly necessary. However, it helps to keep
- // our attaches/detaches symmetrical.
+ // our attaches/detaches symmetrical. Notice we're using quiesce
+ // as a workaround for bug 6841.
case UDPF_SYSCALL:
s.op->line() << " .flags=(UDPF_SYSCALL),";
- s.op->line() << " .ops={ .report_syscall_entry=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death },";
- s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(DEATH)),";
+ s.op->line() << " .ops={ .report_syscall_entry=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death, .report_quiesce=stap_utrace_probe_syscall_quiesce },";
+ s.op->line() << " .events=(UTRACE_ACTION_QUIESCE|UTRACE_EVENT(QUIESCE)|UTRACE_EVENT(DEATH)),";
break;
case UDPF_SYSCALL_RETURN:
s.op->line() << " .flags=(UDPF_SYSCALL_RETURN),";
- s.op->line() << " .ops={ .report_syscall_exit=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death },";
- s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(DEATH)),";
+ s.op->line() << " .ops={ .report_syscall_exit=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death, .report_quiesce=stap_utrace_probe_syscall_quiesce },";
+ s.op->line() << " .events=(UTRACE_ACTION_QUIESCE|UTRACE_EVENT(QUIESCE)|UTRACE_EVENT(DEATH)),";
break;
+
case UDPF_NONE:
s.op->line() << " .flags=(UDPF_NONE),";
s.op->line() << " .ops={ },";
@@ -6228,6 +6230,24 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
// Output handler function for SYSCALL_ENTRY and SYSCALL_EXIT events
if (flags_seen[UDPF_SYSCALL] || flags_seen[UDPF_SYSCALL_RETURN])
{
+ s.op->newline() << "static u32 stap_utrace_probe_syscall_quiesce(struct utrace_attached_engine *engine, struct task_struct *tsk) {";
+ s.op->indent(1);
+ s.op->newline() << "struct stap_utrace_probe *p = (struct stap_utrace_probe *)engine->data;";
+
+ // Turn off quiesce handling and turn on either syscall entry
+ // or exit events.
+ s.op->newline() << "if (p->flags == UDPF_SYSCALL)";
+ s.op->indent(1);
+ s.op->newline() << "utrace_set_flags(tsk, engine, UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(DEATH));";
+ s.op->indent(-1);
+ s.op->newline() << "else if (p->flags == UDPF_SYSCALL_RETURN)";
+ s.op->indent(1);
+ s.op->newline() << "utrace_set_flags(tsk, engine, UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(DEATH));";
+ s.op->indent(-1);
+
+ s.op->newline() << "return (UTRACE_ACTION_NEWSTATE | UTRACE_ACTION_RESUME);";
+ s.op->newline(-1) << "}";
+
s.op->newline() << "static u32 stap_utrace_probe_syscall(struct utrace_attached_engine *engine, struct task_struct *tsk, struct pt_regs *regs) {";
s.op->indent(1);
s.op->newline() << "struct stap_utrace_probe *p = (struct stap_utrace_probe *)engine->data;";