From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3922 invoked by alias); 28 Apr 2009 15:18:19 -0000 Received: (qmail 3910 invoked by uid 22791); 28 Apr 2009 15:18:18 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_64,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 28 Apr 2009 15:18:02 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n3SFI043030831 for ; Tue, 28 Apr 2009 11:18:00 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n3SFI0sM006164 for ; Tue, 28 Apr 2009 11:18:00 -0400 Received: from localhost.localdomain (dst61.hsv.redhat.com [172.16.16.175]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n3SFHwX9003602; Tue, 28 Apr 2009 11:17:59 -0400 Message-ID: <49F71E26.7000303@redhat.com> Date: Tue, 28 Apr 2009 15:18:00 -0000 From: David Smith User-Agent: Thunderbird 2.0.0.21 (X11/20090320) MIME-Version: 1.0 To: Roland McGrath CC: utrace-devel@redhat.com, Systemtap List Subject: Re: resuming after stop at syscall_entry References: <20090418042722.5B584FC35F@magilla.sf.frob.com> <49EF81AA.3060306@redhat.com> <20090425005837.44FB8FC262@magilla.sf.frob.com> In-Reply-To: <20090425005837.44FB8FC262@magilla.sf.frob.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org X-SW-Source: 2009-q2/txt/msg00457.txt.bz2 Roland McGrath wrote: >> This processing makes sense I think. It is a bit complicated of course, >> but not unnecessarily so. > > Glad to hear it! > >>> A tracing-only engine that just wants to see the syscall that is going >>> to be done can just do: >>> >>> if (utrace_resume_action(action) == UTRACE_STOP) >>> return UTRACE_REPORT; >>> >>> at the top of report_syscall_entry, so it just doesn't think about it >>> until it thinks the call will go now through. >> Systemtap currently doesn't support changing syscall arguments, if it >> does, obviously a few things would need to change. >> >> But, I think systemtap would probably fall here - only see the syscall >> that is actually going to be done. So systemtap could possibly get >> multiple callbacks for the same syscall, but only pay attention to the >> last one, correct? > > Correct. The advice quoted above is what its callbacks would do to ignore > the callbacks before the last one. > > Note that you'll only be sure you're seeing "actually going to be done" > state if yours is the "first" engine attached. (Thus, by the new special > case calling order, its will be the last report_syscall_entry callback to > run.) This is just the general "engine priority" thing, not anything new. > > In cases like ptrace and kmview (Renzo's thing), even if these engines are > first (i.e. called after yours), you will still be seeing the "final" state > because they did their changes asynchronously before resuming. But some > other engine might do its changes directly in its own callback instead > (whether it used UTRACE_STOP and got a repeat callback, or just on the > first time through without stopping), so those changes would happen only > after your "last" callback. > > In the same vein, "earlier" engines (i.e. here called after yours) might > use UTRACE_STOP after your first callback had every reason to believe it > was the "last" one (i.e. that if did not hit). In that case, you will get > a repeat call (with UTRACE_SYSCALL_RESUMED flag). On that call, you need > to cope with the fact that you already did your entry tracing work before > (but now things may have changed). > > If the theory is that you want to respect your place in the engine order, > whatever that is (i.e., if your tracing just reported a lie, it was the lie > you were supposed to believe), then "coping" just means ignoring the > repeat. (This is no different in kind from an "earlier" engine/later > callback changing the registers after your callback and never stopping.) > > For that you need to keep track of whether you already handled it or not. > (Depending on your relative order and the actions of the other engines, you > might get either UTRACE_STOP or UTRACE_SYSCALL_RESUMED either before or > after "you handled it". So you can't use those alone.) You can do this in > two ways. One is to use your own per-thread state (engine->data, etc.). > The other is to disable the SYSCALL_ENTRY event when you've handled it, so > you won't get more callbacks. Then you can re-enable the event in your > report_syscall_exit callback (or report_quiesce/report_signal, or whatever > is most convenient to be sure you'll run before it goes back to user mode). > i.e., use utrace_set_events() from the callbacks. It sounds like disabling SYSCALL_ENTRY then re-enabling it in the report_syscall_exit() callback is a reasonable way to go. >> This is understandable, but does hurt my head a *little* bit. I think >> if you put the above full text somewhere and provided some examples this >> would make sense to people. > > The utrace-syscall-resumed branch puts this in the kerneldoc text for > struct utrace_engine_ops (where callback return values and common arguments > are described): > > * When %UTRACE_STOP is used in @report_syscall_entry, then @task > + * stops before attempting the system call. In this case, another > + * @report_syscall_entry callback follows after @task resumes; in a > + * second or later callback, %UTRACE_SYSCALL_RESUMED is set in the > + * @action argument to indicate a repeat callback still waiting to > + * attempt the same system call invocation. This repeat callback > + * gives each engine an opportunity to reexamine registers another > + * engine might have changed while @task was held in %UTRACE_STOP. > + * > + * In other cases, the resume action does not take effect until @task > + * is ready to check for signals and return to user mode. If there > + * are more callbacks to be made, the last round of calls determines > + * the final action. A @report_quiesce callback with @event zero, or > + * a @report_signal callback, will always be the last one made before > + * @task resumes. Only %UTRACE_STOP is "sticky"--if @engine returned > + * %UTRACE_STOP then @task stays stopped unless @engine returns > + * different from a following callback. > > I don't know where the longer explanation and/or examples belong. > Perhaps in a new section in utrace.tmpl? We could start with putting > together some text on the wiki. Another idea is to add a few example > modules in samples/utrace/. Those can illustrate things with good > comments, and also could be built verbatim to load multiple > ones/instances in different orders and demonstrate what happens, etc. The wiki would be fine - just somewhere that people could see this stuff. > It would be nice to have folks like you and Renzo work up this text > and/or examples. What's needed is stuff that makes sense to you guys > as users of the API, rather than what makes sense to me who has > thought too much already about all this stuff. We should probably just dump your email into the wiki. -- David Smith dsmith@redhat.com Red Hat http://www.redhat.com 256.217.0141 (direct) 256.837.0057 (fax)