After talking with Renzo Davoli we agreed that it makes most sense for SYSCALL_ENTRY events to have engines' callbacks made in the reverse of the normal order (FIFO vs LIFO). This ordering makes it sensical to have "nesting" mutators and examiners as different utrace engines all watching syscall entry on a task. This new DocBook paragraph explains the rationale:
The <constant>UTRACE_EVENT(SYSCALL_ENTRY)</constant> event is a special case. While other events happen in the kernel when it will return to user mode soon, this event happens when entering the kernel before it will proceed with the work requested from user mode. Because of this difference, the <function>report_syscall_entry</function> callback is special in two ways. For this event, engines are called in reverse of the normal order (this includes the <function>report_quiesce</function> call that precedes a <function>report_syscall_entry</function> call). This preserves the semantics that the last engine to attach is called "closest to user mode"--the engine that is first to see a thread's user state when it enters the kernel is also the last to see that state when the thread returns to user mode. For the same reason, if these callbacks use <constant>UTRACE_STOP</constant> (see the next section), the thread stops immediately after callbacks rather than only when it's ready to return to user mode; when allowed to resume, it will actually attempt the system call indicated by the register values at that time. I've made this change in the current code. (It was indeed trivial.) I will follow up later on the nontrivial issues about stopping and resuming at syscall-entry. Renzo and I spoke in more detail about this and I have a sense of what we want to do in the API, but it merits more discussion. The ordering change was the very low-hanging fruit that I had time to do now. I'll post again later (may be a few days) about the stopping issue. Thanks, Roland