tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

ptrace(2) thoughts and design



In short we are already in a good position with the existing ptrace(2)
interfaces, as most necessary functions in LLDB are representable by
existing NetBSD specific interfaces.

I didn't want to implement (commit) new interfaces prior matching them
with real-life software like LLDB in a real and testable code-path.


1. fork(2) events are implementable with EVENT_MASK (PT_SET_EVENT_MASK,
PT_GET_EVENT_MASK, PT_GET_PROCESS_STATE). Event name is PTRACE_FORK.

2. vfork(2) events should be implemented with EVENT_MASK and event name
PTRACE_VFORK using the same ptrace(2) functions and structures like fork(2).

I'm holding on, as there is additional event used in the FreeBSD and
Linux world to report vfork(2) parent's continuation after child's
termination. Both events can be combined with the same PTRACE_VFORK
type, just set pe_other_pid to an invalid number when child exits to
distinguish them.

3. New interfaces for PT_LWPINFO are not needed, as this call already
can iterate over a list of all lwps. This ptrace(2) call has different
meaning to the FreeBSD one, as in FreeBSD it returns the lwp that
stopped the process (and the one that switched to debugger), in NetBSD
it retrieves the next lwp with the following rule:

pl_lwpid contains a thread LWP ID.  Information is
returned for the thread following the one with the
specified ID in the process thread list, or for the first
thread if pl_lwpid is 0.  Upon return pl_lwpid contains the
LWP ID of the thread that was found, or 0 if there is no
thread after the one whose LWP ID was supplied in the call.

This interface is planned to be used once pthread_dbg will be
unavailable, as there are dedicated functions for the same purpose
(namely td_thr_iter()).

4. There is no need to extend struct ptrace_lwpinfo to size of
FreeBSD... as there is pthread_dbg that takes this job to inspect thread
(like thread name, sigmask, ...).

5. I want to use pthread_dbg for the following operations:
 - inspect threads (retrieve its name, sigmask, whether there are
waiters etc)
 - set/get registers per lwp
 - suspend/resume thread

6. Implementation of the thread resume/suspend operation in thread_dbg
is trivial (I keep it locally) and it's based on new callback functions
SUSPEND() and RESUME():
 - for local process just call there _lwp_continue(2) and _lwp_suspend(2),
 - for remote ptrace(2) call with PT_CONTINUE and [temporarily missing]
PT_SUSPEND.

7. For non-pthread world keep fallback to native ptrace(2) interfaces
with the same features like in pthread_dbg minus inspection of threads.
Keep suspension, resume capability, get/set regs.. skip investigation of
sigmask, name of a process etc.

Usage of pthread_dbg largely simplifies interface between kernel and
user-space and deduplicates information, no need to pass it via the
ptrace_lwpinfo structure... just access it in pthread_t via pthread_dbg.

The main benefit of pthread_dbg is that we are in direct control of
pthread_t state and can read waiters for a thread, thread specific data etc.

8. If there will be need to retrieve more information on lwp, especially
in a single-threaded program (or one using lwp interface directly) I
would extend ptrace(2) with retrieving struct lwp in PT_LWPINFO in a new
field, next to pl_lwpid and pl_event... but I want to skip it for later
to match real-life needs in real debuggers first.

9. To achieve thread suspension and continuation in 5. and 6., I need to
add PT_SUSPEND - as a counterpart to PT_CONTINUE. I want to add there
two modes analogously to PT_SUSPEND:
 - for positive values, suspend the whole process with pid "value"
 - for negative values, suspend lwp with identity "-value"

10. I'm evaluating addition of new types of pl_event (in ptrace_lwpinfo)
- it describes what stopped a thread. Next to PL_EVENT_NONE and
PL_EVENT_SIGNAL, I would add:
 - PL_EVENT_TRACER thread suspended by a debugger calling PT_SUSPEND
 - PL_EVENT_LWP thread suspended by _lwp_suspend(2) from user-space

Like previously, I'm not sure whether these new PT_EVENT types will be
used and useful at all in real-application so I will hold on with them.

11. Add support for CPU debug registers. Unlike the above parts, this
one could be clearly ported as is from FreeBSD right now. It's also very
useful and needed to set watchpoints in memory.

These are currently used by all supported LLDB targets but NetBSD, so:
Linux, Android, MacOSX, Windows, FreeBSD.

12. There are code paths for the SIGINFO event in LLDB, I haven't been
evaluating it so far, as it looks like a low priority for now. In worst
scenario there will be need to add new EVENT_TYPE for SIGINFO and pass
siginfo struct there, but it's not certain and I delayed it for later
(if ever). For the first look we can just capture regular signal,
compare it with regular functions and handle ksiginfo struct with..
perhaps wait6(2)-like function. It's not researched and for now skipped.

My plan for the coming days:

A. Add introductory man-pages for pthread_dbg, currently just for the
used functions in the existing ATF tests, as other interfaces might be
altered later... or just dropped as unneeded. This library keeps having
dept from Scheduler Activation times, and that shall be just revamped.

B. Implement debug registers, base this code on FreeBSD. Add ATF tests,
commit to master repository.

C. Implement locally PT_SUSPEND and keep it on a local branch.

D. Implement locally PTRACE_VFORK (right now just for calling vfork(2)
and for creating a child) and keep it on a local branch.

... switch to LLDB

Attachment: signature.asc
Description: OpenPGP digital signature



Home | Main Index | Thread Index | Old Index