-
Notifications
You must be signed in to change notification settings - Fork 194
Live userspace process support for the Threads API #142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
4a162a4 to
a405278
Compare
dd03f12 to
df716f4
Compare
6d933a6 to
9ee902e
Compare
|
@osandov Presently this is now a MVP of the feature. The core interface works well, has test cases, and is passing all of the existing tests. Due to the complexity and subtly of |
Previously, `fork_and_pause` was only used in the Linux helper tests cases. However, as many of the test cases for the upcoming live userspace process support for the Threads API will likely need this same utility, I've moved it to the root of the tests module. Signed-off-by: Kevin Svetlitski <[email protected]>
PR osandov#129 introduced the Threads API to drgn, but did not include support for live userspace processes. This commit changes that, both adding support for the existing Threads API, as well as extending it with a few additional methods which only make sense in the context of a live process, most notably `Thread.pause()` and `Thread.resume()` At present, only x86 is supported, but the plan is to support other architectures in the near future. Signed-off-by: Kevin Svetlitski <[email protected]>
9ee902e to
eea2566
Compare
|
Sorry for the delay. I've been busy with other work, but this has been in the back of my head for awhile while I though about what the interface should look like. Thanks to your experimentation and MVP, I think we uncovered a few issues that we should consider:
This is a rough sketch of what I'm picturing: class Program:
def attach_all_threads(self) -> None:
"""
Attach to all threads in this program as well as any new threads that
are created.
"""
...
def detach_all_threads(self) -> None:
"""Detach from all threads in this program."""
...
def get_thread_event(self, block: bool = True) -> ThreadEvent:
"""
Get the next event for any thread in this program. If *block* is
``True``, wait for the next event. If *block* is ``False``, raises an
exception if no event is available (TODO: which one? Non-blocking
sockets seem to return an OSError with errno set appropriately).
"""
...
class Thread:
def attach(self) -> bool:
"""
Attach to this thread.
:return: ``True`` on success, ``False`` if the thread was already attached
"""
...
def detach(self) -> bool:
"""
Detach from this thread.
:return: ``True`` on success, ``False`` if the thread was not attached
"""
...
def interrupt(self) -> None:
"""
"""
...
def continue(self) -> bool:
"""
If this thread is currently stopped, resume it.
:return: ``True`` on success, ``False`` if the thread was not stopped
"""
...
def get_event(self, block: bool = True) -> ThreadEvent:
"""
Get the next event for this thread.
"""
...Then, we can have a dumb ThreadEvent = Union[ThreadEventSignal, ThreadEventExit, etc...]
class ThreadEventSignal:
signal: int
class ThreadEventExit:
status: int
etc...The above (along with the equivalent libdrgn interfaces) is more or less what I'd consider the MVP for this design. There are obviously lots of finer details to consider, as well as complications with ptrace that I may not have considered. There are some "extras" that we should implement eventually, possibly in follow-up PRs:
def pause(self):
self.interrupt()
while True:
event = self.get_event()
if isinstance(event, ThreadEventStop):
return
# TODO: should we have a distinction between "stopping" events that
# require a continue and "non-stopping" events?
self.continue()
This is definitely larger in scope than the basic |
This implements the existing thread API methods for live processes other than drgn_thread_stack_trace(). It also doesn't yet add support for full-blown tracing, but it at least brings live processes to feature parity. This is taken from the non-ptrace parts of Kevin Svetlitski's PR #142, with some modifications. Signed-off-by: Omar Sandoval <[email protected]>
|
I wrote this project up as an issue, so I'm closing this one. Thanks again for getting this started! |
Building off of the work of #129, this PR (when completed) will implement and extend the Threads API outlined in #92 for live userspace processes. This will bring
drgnone step closer to fulfilling the traditional role of a userspace debugger, most notably adding the ability to pause and resume threads at will during the execution of the program.As this is still a work in progress, this PR is in draft mode.