summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--runtime/ChangeLog6
-rw-r--r--runtime/task_finder.c4
-rw-r--r--tapsets.cxx30
4 files changed, 42 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 477f7d1e..6b4ffe32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+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-18 David Smith <dsmith@redhat.com>
* tapsets.cxx (register_standard_tapsets): Add missing
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index 58678de5..796f812c 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,9 @@
+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.
+
2008-08-14 Frank Ch. Eigler <fche@elastic.org>
PR 6842.
diff --git a/runtime/task_finder.c b/runtime/task_finder.c
index 928b7087..d7450a41 100644
--- a/runtime/task_finder.c
+++ b/runtime/task_finder.c
@@ -317,7 +317,7 @@ __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen)
| UTRACE_EVENT(SYSCALL_ENTRY) \
| UTRACE_EVENT(SYSCALL_EXIT))
-#define __STP_ATTACHED_TASK_VM_EVENTS (__STP_ATTACHED_TASK_VM_BASE_EVENTS \
+#define __STP_ATTACHED_TASK_VM_EVENTS (__STP_ATTACHED_TASK_BASE_EVENTS \
| UTRACE_ACTION_QUIESCE \
| UTRACE_EVENT(QUIESCE))
@@ -608,7 +608,7 @@ __stp_utrace_task_finder_target_quiesce(struct utrace_attached_engine *engine,
{
struct stap_task_finder_target *tgt = engine->data;
- // Turn off quiesce handling.
+ // Turn off quiesce handling (and turn on syscall handling).
utrace_set_flags(tsk, engine, __STP_ATTACHED_TASK_VM_BASE_EVENTS);
if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
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;";