Page MenuHomeFreeBSD

Run child processes in a new process group.
AbandonedPublic

Authored by jhb on Jun 3 2017, 3:51 PM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Apr 25, 4:17 PM
Unknown Object (File)
Mar 28 2024, 5:21 AM
Unknown Object (File)
Mar 23 2024, 10:14 PM
Unknown Object (File)
Dec 20 2023, 4:56 AM
Unknown Object (File)
Nov 16 2023, 2:26 PM
Unknown Object (File)
Nov 11 2023, 10:30 AM
Unknown Object (File)
Oct 28 2023, 1:21 AM
Unknown Object (File)
Oct 15 2023, 1:25 PM
Subscribers

Details

Summary

When executing a new command, run the new command in a new process group.
This requires some extra handling for signals since Ctrl-C in a terminal
posts the signal to the session leader's process group (which would be the
process group containing truss). In particular, truss now must forward any
received SIGINT, SIGTERM, or SIGQUIT signals to the child process instead
of ignoring them.

Test Plan
  • use truss -f with the test script from PR 175269

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 9646
Build 10087: arc lint + arc unit

Event Timeline

usr.bin/truss/setup.c
75

I think we should use killpg() here. The old foreground handling wold effectively do that with a SIGINT right?

If at all possible, I think it is best to avoid placing the traced process in a new process group, since this breaks things like terminal access control (the traced process will be in a background process group as far as the tty is concerned). Given that the new process group is removed, forwarding signals may make sense (but will duplicate signals if they were originally sent to the process group).

Wow... this is going back. A PR I filed in 2013? Hah..

truss(1) should really have tests...

usr.bin/truss/setup.c
75

+1

So the other route would be to invert the relationship between truss and the new child process. That is, truss could let the original parent call execve and the child would run as the tracer. This would mean not using PTRACE_ME but instead doing an explicit PT_ATTACH of the parent from the child using a pipe to coordinate (so the parent tries to read from the pipe and the child does the PT_ATTACH which will catch it in the pipe read or before the pipe read then writes to the pipe and PT_CONTINUES until it exits execve.

The reason I did kill instead of killpg was to be cautious since something might explicitly kill() a child rather than the group.

In D11035#228696, @jhb wrote:

So the other route would be to invert the relationship between truss and the new child process. That is, truss could let the original parent call execve and the child would run as the tracer. This would mean not using PTRACE_ME but instead doing an explicit PT_ATTACH of the parent from the child using a pipe to coordinate (so the parent tries to read from the pipe and the child does the PT_ATTACH which will catch it in the pipe read or before the pipe read then writes to the pipe and PT_CONTINUES until it exits execve.

Fun fact, that used to hang the system and drove me nuts for a decade until it was fixed by Kib in rS269656. I kept wanting to have my process "trace itself" via a child to block ptrace attachments otherwise.

Thinking about this a bit more, I'm inclined to just drop this patch. In the original PR, the 'rsleeper.sh' script is arguably buggy as it assumes it runs in a dedicated process group (since it uses 'kill -$$'), but it doesn't explicitly create one. The right fix for the shell script would be if 'kill' had some sort of command line interface that was the equivalent of 'killpg(0, ...)'. In fact, if I modify the 'rsleeper.sh' script to comment out the 'trap' then Ctrl-C of 'truss ./rsleeper.sh' already works. It would be good to verify a real-world use case outside of the sample shell script I think to see if it is still broken or not.

I can. Does this mean also closing the PR? (That is, were you able to test truss on a real-world case like 'truss -f startx'?)