Page MenuHomeFreeBSD

linuxulator: Some ptrace fixes..
Needs ReviewPublic

Authored by pitwuu_gmail.com on May 25 2021, 5:36 PM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Nov 8, 8:08 AM
Unknown Object (File)
Fri, Nov 1, 12:03 PM
Unknown Object (File)
Fri, Nov 1, 9:33 AM
Unknown Object (File)
Oct 6 2024, 10:27 PM
Unknown Object (File)
Oct 3 2024, 7:16 AM
Unknown Object (File)
Oct 2 2024, 7:24 PM
Unknown Object (File)
Oct 2 2024, 5:14 PM
Unknown Object (File)
Oct 1 2024, 3:40 AM
Subscribers

Details

Reviewers
jhb
kib
Group Reviewers
Linux Emulation
Summary

This is not a patch ready for inclusion yet, but rather to get the ball rolling on some changes to ptrace.
Once the patch is cleaned up I'd like to see it pulled in.

Discussion: strace doesn't always run right now because it hangs up on lack of SEIZE support. SEIZE is like ATTACH, but it doesn't leave the process stopped after attaching. Rather a follow up INTERRUPT is issued to actually stop the process and wait for events.
Unlike ATTACH, in SEIZE we immediately get ptrace options and can set them right away.

With this patch, strace reliably runs on my end whereas the previous effect was a 'nothing happening' strace.

Test Plan

You can run strace and test that way.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

Ah yes I forgot. There's a second point of failure in our current ptrace. Currently all signals emit an event for ptrace to consume, which is not the behaviour on Linux, where all signals emit a signal except SIGKILL which behaves normally.
From the man page:

While being traced, the tracee will stop each time a signal is

delivered, even if the signal is being ignored.  (An exception is
SIGKILL, which has its usual effect.)  The tracer will be
notified at its next call to waitpid(2) (or one of the related
"wait" system calls);

So the effect is that strace checks this and hangs up. My patch attempts to correct this situation. But AFAIK it shouldn't be done in the "normal" freebsd mode.

This looks really interesting, thanks for working on it!

Which version of strace(1) are you testing with? I kind of hoped this would fix the one from Ubuntu Focal (the one from Bionic already worked fine), but this doesn't seem to be the case.

This looks really interesting, thanks for working on it!

Which version of strace(1) are you testing with? I kind of hoped this would fix the one from Ubuntu Focal (the one from Bionic already worked fine), but this doesn't seem to be the case.

As of today strace 4.25 is at least in working status.
I have git master almost working. I added GET_SYSCALL_INFO support in my local branch. One tiny issue I can't resolve is that the thread dies when receiving some initial signal. I can't figure it out :( The signals stuff is very hacky in Unix and this is at the edge of my ability I think. If I comment out this line in src/syscall.c then the process starts and traces.

652   │                 /*
653   │                  * First exec* syscall makes the log visible.
654   │                  */
655   │                 tcp->flags &= ~TCB_HIDE_LOG;
656   │                 /*
657   │                  * Check whether this exec* syscall succeeds.
658   │                  */
659   │         /// XXX this one        tcp->flags |= TCB_CHECK_EXEC_SYSCALL;
660   │                 break;
661   │         }
662   │     }

Trace git master will also work if you recompile it manually after modifying NOMMU_SYSTEM in the src/defs.h. This will use the old non-SEIZED-based method of tracing and then all is well. Do you want to try my changes?

Nice! Regarding GET_SYSCALL_INFO - this reminded me that I also had a patch for this, https://reviews.freebsd.org/D28212; I guess we should try merging our changes.

There's some activity right now regarding Linuxulator signal delivery, https://reviews.freebsd.org/D30675; I wonder if it's related?

Nice! Regarding GET_SYSCALL_INFO - this reminded me that I also had a patch for this, https://reviews.freebsd.org/D28212; I guess we should try merging our changes.

There's some activity right now regarding Linuxulator signal delivery, https://reviews.freebsd.org/D30675; I wonder if it's related?

Great! Your GET_SYSCALL_INFO work looks really similar to mine, I think that would work if you have no objection.
Regarding the Linuxulator signal delivery, I think this is work in the right direction, but instead of messing with wait() it's clear that SIGKILL should behave as normal regardless of a wait or not, so it looks to be tangential to this.?

What does tinderboxed mean?

Sorry for delay. I've just finished dusting off https://reviews.freebsd.org/D28212; hopefully it will hit the tree soon.

As for signals - I'm not sure, to be honest; I've only touched that code briefly.

As for tinderbox: "make tinderbox" builds both kernel and world, for all supported architectures. It's good habit to make sure it passes before pushing changes.

John, Konstantin, this extends our native ptrace(2), so I'd like to know what do you think. There should be documentation, but for now the new requests are described in https://man7.org/linux/man-pages/man2/ptrace.2.html.

Are these ops of any use for the FreeBSD native ptrace(2)?

sys/kern/sys_process.c
717

Why?

I'm not sure if these make as much sense on FreeBSD unless we want to support non-stop debugging vs all-stop debugging. non-stop debugging requires many more structural changes than just seize however. Right now we generally don't permit ptrace operations like examining memory on a running process, but non-stop debugging does permit process-wide queries.

The other thing I have not quite fathomed about the desire to support Linux strace on Linux binaries is that truss already supports Linux binaries. A native port of strace could also support both native and Linux binaries without too much work.

Similarly, a native gdb can debug Linux binaries (I've used it to test that things like 'info auxv' have the right split between gdbarch and target in gdb itself so that it uses the native FreeBSD ptrace op to fetch the AUXV vector but uses a linux-tdep.c method to parse the auxv entries).

Can you say some more about what's missing for non-stop debugging?

As for motivation: there are two. First, yes, truss and ktrace can trace Linux processes, kind of. However, they don't decode constants and structures, while the Linux strace does. Second, using them would require using both Linux and FreeBSD binaries, which is rather user-unfriendly compared to typical Linux chroot.

Ah, one more thing: we can't really have a (modern) strace(1) port for both native and Linux binaries; strace has removed support for everything not Linux several years ago.

This comment was removed by trasz.

Can you say some more about what's missing for non-stop debugging?

Redoing the entire way we handle ptrace stops to not stop the entire process, just the relevant thread. I have some WIP that might make this more possible, but it is a very large and invasive change.

Advertising incomplete support for this in the native ABI would seem to possibly confuse software that sees it and thinks it work when it doesn't.

See also https://reviews.freebsd.org/D32367, which takes a slightly different route.