Hi, Stephane,
As you may recall, about a month ago, I posted a question to the utrace
mailing list, asking about a compile failure I was seeing in
perfmon/perfmon_syscalls.c because it's trying to use the function
ptrace_check_attach (removed by the utrace patch). I've attached a
patch that we've been using that fixes the compile failure and seems to
functionally work. Feel free to use it if you wish. Please let me know
if it seems correct to you.
Thanks.
Maynard Johnson
IBM POWER Toolchain Team
--- linux-2.6.24+perfmon2/perfmon/perfmon_syscalls.c 2008-02-15 14:31:42.000000000 -0600
+++ linux-2.6.24+perfmon2+utrace/perfmon/perfmon_syscalls.c 2008-03-12 21:06:02.000000000 -0500
@@ -109,6 +109,66 @@ static int pfm_task_incompatible(struct
return 0;
}
+static int check_attach(struct task_struct *p)
+{
+ int ret = -1;
+ struct utrace_attached_engine *engine;
+ struct sighand_struct *sighand;
+ unsigned long flags = 0ULL, sig_flags;
+ int stopped = 0;
+
+ /* Get existing engine. */
+ engine = utrace_attach(p, 0, NULL, NULL);
+ if (IS_ERR(engine) || engine == NULL) {
+ printk(KERN_WARNING "utrace_attach failed!\n");
+ goto error;
+ }
+ ret = 0;
+ if (!(engine->flags & UTRACE_ACTION_QUIESCE)) {
+ /* FIXME: Not sure if we really should try to quiesce
+ * the task here if it isn't already. If user
+ * has done ptrace(PTRACE_ATTACH) followed by
+ * pfm_load_context(), the task will be quiesced.
+ * should we return an error instead of attempting
+ * to quiesce the task?
+ */
+ /*
+ * These events are always reported.
+ */
+ flags |= (UTRACE_EVENT(DEATH) | UTRACE_EVENT(EXEC)
+ | UTRACE_EVENT_SIGNAL_ALL | UTRACE_EVENT(JCTL));
+
+ /*
+ * We always have to examine clone events to check for
+ * CLONE_PTRACE.
+ */
+ flags |= UTRACE_EVENT(CLONE);
+
+ flags |= UTRACE_ACTION_QUIESCE;
+ /*
+ * If task is in job control stop, quiesce it.
+ */
+ sighand = lock_task_sighand(p, &sig_flags);
+ if (likely(sighand != NULL)) {
+ if (p->state == TASK_STOPPED)
+ stopped = 1;
+ unlock_task_sighand(p, &sig_flags);
+ }
+ if (stopped) {
+ ret = utrace_set_flags(p, engine, flags);
+ }
+
+ if (ret) {
+ PFM_DBG("Possible problem with process %d, state %lu. "
+ "Process stopped? %s. ret val=%d\n",
+ p->pid, p->state,
+ stopped ? "yes" : "no", ret);
+ goto error;
+ }
+ }
+ error:
+ return ret;
+}
/*
* This function is used in per-thread mode only AND when not
* self-monitoring. It finds the task to monitor and checks
@@ -155,15 +215,12 @@ int pfm_get_task(struct pfm_context *ctx
* returns 0 if cannot attach
*/
ret1 = ptrace_may_attach(p);
- if (ret1)
- ret = ptrace_check_attach(p, 0);
-
- PFM_DBG("may_attach=%d check_attach=%d", ret1, ret);
-
- if (ret || !ret1)
+ if (!ret1)
goto error;
- ret = pfm_task_incompatible(ctx, p);
+ ret = check_attach(p);
+ if (!ret)
+ ret = pfm_task_incompatible(ctx, p);
if (ret)
goto error;
@@ -275,7 +332,7 @@ recheck:
/*
* check that the thread is ptraced AND STOPPED
*/
- ret = ptrace_check_attach(task, 0);
+ ret = check_attach(task);
pfm_spin_lock_irqsave(&ctx->lock, new_flags);
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
perfmon2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel