I added code to use PTRACE_SEIZE in strace and in the processhad tasted how API looks like from userspace POV.

It is usable, but API feels somewhat quirky.

Consider the following: one of reasons why we added PTRACE_SEIZEis that existing ptrace API has unnecessary complications(quirks) such as SIGSTOP on attach, SIGTRAP after execve.

But whoever designed strace did not deliberately designed these quirks in,he thought it was a good, reasonable design. Only after a second, third,tenth look it became obvious in retrospect that some things arenot exactly right.

Thankfully, quirks in new PTRACE_SEIZE code mostly have the nature of"unnecessarily invented entities" as opposed to problemsin trying to use API in real world tasks, but I still think they areannoying enough to be looked at.

We already have a mechanism how to modify ptrace behavior: ptrace options.But now we introduce a different mechnism to do the same: by using SEIZEinstead of ATTACH, we magically change some aspects of ptrace.In effect, SEIZE sets some options. And these "SEIZE options" can't beset or cleared by SETOPTIONS. This is stupid. Why can't we just addmore options instead of inventing new entities? Why we overloadedSEIZE with two functions: "attach to, but don't SIGSTOP the tracee"and "change behaviour of ptrace on this tracee"?

If the argument is that we want to set options immediately at attach,then I completely agree: yes, we do! Moreover, we want to set some_ordinary_ options too, such as PTRACE_O_TRACEEXEC, and we can'tdo that even now, in improved API! It needs more improving.

So my proposal is:(a) make SEIZE take a parameter "immediately set these options on attach"(b) without any options, make SEIZE just do "ATTACH sans SIGSTOP" thing, nothing more.(c) make the following new PTRACE_O_foo options: (1) "flag stops with PTRACE_EVENT_STOP event value in waitpid status" (2) "enable PTRACE_INTERRUPT. It either causes PTRACE_EVENT_STOP with sig=SIGTRAP if (1) is enabled, or creates a group-stop with sig=SIGTRAP otherwise" [if the second part is too weird to implement, make (2) require (1)] (3) "enable PTRACE_LISTEN. Works on group-stops even without any other options" (4) "make auto-attached children stop a-la INTERRUPT, not with SIGSTOP" (5) "enable saner error codes"(d) Remove magic hidden 'I was SEIZEd, not ATTACHed' bit in kernel code. Use bits 1,2,3,4 instead of it.(e) Make these bits settable with SETOPTIONS too, to keep API complete.In strace, I already implicitly use 1,2,3,4. With this proposal, I'd useall five, *explicitly*, and also use at least PTRACE_O_TRACEEXEC,to avoid the possibility SEIZE races with execve and we get that pesky SIGTRAP.Something along the lines:

This will remove the asymmetry we just introduced in current SEIZE code:PTRACE_EVENT_STOP is the only event code which has no correspondingPTRACE_O_TRACESTOP option - situation which Occam disapproves.

In fact, I am unsure why the new ops (points 2 and 3 above) need enabling.Maybe they can be simply be always allowed? Let's see...

Re PTRACE_INTERRUPT: "old-style" check for group-stop,namely, "if ptrace(PTRACE_GETSIGINFO) fails, then it's group-stop",works just fine, therefore, from userspace POV there is no apparent reasonwhy PTRACE_INTERRUPT can't work without "flag stops with PTRACE_EVENT_STOP"thingy: in this case it can create an"WIFSTOPPED(status) = true, ptrace(PTRACE_GETSIGINFO) fails"event which is detectable in userspace. PTRACE_EVENT_STOP is not needed for this,it's just a "nice to have" thing (it saves one ptrace call).

Re PTRACE_LISTEN: similarly to above, we _do_ know when we are ingroup-stop, even without (1) "flag stops with PTRACE_EVENT_STOP" thingy.Therefore we do know when PTRACE_LISTEN makes sense.Moreover, we can make it so that kernel errors out if PTRACE_LISTENis used in a ptrace stop of a wrong kind.

Just to let you see the relevant userspace code which made me think aboutthe above issues, here is abridged version of main waitpid loop in strace.Note that it is coded in a way that it works both on SEIZE-enabledkernels and on old kernels, which have no SEIZE and friends."use_seize" variable is set if we are on a SEIZE-enabled kernel: