Q: drop PTRACE_SEIZE_DEVEL?

Denys Vlasenko dvlasenk at redhat.com
Fri Feb 8 10:56:25 UTC 2013


On 02/08/2013 01:02 AM, Dmitry V. Levin wrote:
> On Wed, Feb 06, 2013 at 01:57:46PM +0100, Denys Vlasenko wrote:
>> On 10/31/2012 04:37 PM, Dmitry V. Levin wrote:
>>> It seems to be working so far, but with annoying addition to the strace
>>> output:
>>>
>>> $ strace true
>>> --- stopped by SIGSTOP ---
>>> --- SIGCONT {si_signo=SIGCONT, si_code=SI_USER, si_pid=4096, si_uid=512} ---
>>> execve("/bin/true", ["true"], [/* 32 vars */]) = 0
>>> exit_group(0)                           = ?
>>> +++ exited with 0 +++
>>>
>>> The child process is actually being stopped and continued, but are these
>>> technical details of USE_SEIZE implementation worth seeing?
>>
>> We did not do any special magic before to hide initial setup.
>> It just so happens that with "good old" PTRACE_TRACEME
>> method of spawning the child we don't have any stray syscalls:
>>
>> Child does
>> 	ptrace(PTRACE_TRACEME);
>> 	kill(pid, SIGSTOP);
>> Then parent goes into tracing waitpid loop,
>> sees SIGSTOP, knows to ignore it, issues PTRACE_SYSCALL(0),
>> which unpauses group-stop.
>> Then child falls into execve, and parent sees it.
>>
>> Result: strace reports no "extra" syscalls before execve.
>>
>> Whereas with SEIZE:
>>
>> Child does
>> 	kill(pid, SIGSTOP);
>> then parent waits for SIGSTOP to take effect on child,
>> then parent does PTRACE_SEIZE and PTRACE_INTERRUPT on child,
>> then parent sends SIGCONT to it,
>> Then parent goes into tracing waitpid loop,
>> then child goes through the motions of waking up from group-stop
>> and then falls into execve.
>>
>> All of the above is done to make sure that child doesn't fall
>> into execve BEFORE we seize it.
>>
>> Better ideas how to achieve that?
>> Basically: how to stop the child "cleanly"?
> 
> No, there seems to be no such way with this new ptrace API.
> We have to block the child process to seize it, and after that we will
> see its unblocking no matter what kind of blocking method is in use.

I tried sigwait'ing for SIGCONT in the child (instead of stopping itself).

Works nicely (no extra syscalls visible to tracer),
but there is no reliable way to parent
to be sure that child entered sigwait syscall and it
is safe to SEIZE, and then send SIGCONT.

I used the "lets sleep 1 second in parent and hope it's enough"
hack when I tested the sigwait idea. That worked, but we wouldn't
use such unclean methods, right?

-- 
vda





More information about the Strace-devel mailing list