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