mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:38:11 +00:00
Kernel: Add 'ptrace' syscall
This commit adds a basic implementation of the ptrace syscall, which allows one process (the tracer) to control another process (the tracee). While a process is being traced, it is stopped whenever a signal is received (other than SIGCONT). The tracer can start tracing another thread with PT_ATTACH, which causes the tracee to stop. From there, the tracer can use PT_CONTINUE to continue the execution of the tracee, or use other request codes (which haven't been implemented yet) to modify the state of the tracee. Additional request codes are PT_SYSCALL, which causes the tracee to continue exection but stop at the next entry or exit from a syscall, and PT_GETREGS which fethces the last saved register set of the tracee (can be used to inspect syscall arguments and return value). A special request code is PT_TRACE_ME, which is issued by the tracee and causes it to stop when it calls execve and wait for the tracer to attach.
This commit is contained in:
parent
c9396be83f
commit
6b74d38aab
13 changed files with 300 additions and 102 deletions
|
@ -122,6 +122,7 @@ public:
|
|||
virtual ~Blocker() {}
|
||||
virtual bool should_unblock(Thread&, time_t now_s, long us) = 0;
|
||||
virtual const char* state_string() const = 0;
|
||||
virtual bool is_reason_signal() const { return false; }
|
||||
void set_interrupted_by_death() { m_was_interrupted_by_death = true; }
|
||||
bool was_interrupted_by_death() const { return m_was_interrupted_by_death; }
|
||||
void set_interrupted_by_signal() { m_was_interrupted_while_blocked = true; }
|
||||
|
@ -253,6 +254,7 @@ public:
|
|||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
virtual bool is_reason_signal() const override { return m_reason == Reason::Signal; }
|
||||
|
||||
private:
|
||||
Reason m_reason;
|
||||
|
@ -356,6 +358,7 @@ public:
|
|||
void terminate_due_to_signal(u8 signal);
|
||||
bool should_ignore_signal(u8 signal) const;
|
||||
bool has_signal_handler(u8 signal) const;
|
||||
bool has_pending_signal(u8 signal) const { return m_pending_signals & (1 << (signal - 1)); }
|
||||
|
||||
FPUState& fpu_state() { return *m_fpu_state; }
|
||||
|
||||
|
@ -431,6 +434,11 @@ public:
|
|||
static constexpr u32 default_kernel_stack_size = 65536;
|
||||
static constexpr u32 default_userspace_stack_size = 4 * MB;
|
||||
|
||||
ThreadTracer* tracer() { return m_tracer.ptr(); }
|
||||
void start_tracing_from(pid_t tracer);
|
||||
void stop_tracing();
|
||||
void tracer_trap(const RegisterState&);
|
||||
|
||||
private:
|
||||
IntrusiveListNode m_runnable_list_node;
|
||||
IntrusiveListNode m_wait_queue_node;
|
||||
|
@ -491,6 +499,8 @@ private:
|
|||
bool m_dump_backtrace_on_finalization { false };
|
||||
bool m_should_die { false };
|
||||
|
||||
OwnPtr<ThreadTracer> m_tracer;
|
||||
|
||||
void yield_without_holding_big_lock();
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue