11#include <cosmos/BitMask.hxx>
12#include <cosmos/proc/process.hxx>
13#include <cosmos/proc/ptrace.hxx>
14#include <cosmos/proc/signal.hxx>
15#include <cosmos/proc/Tracee.hxx>
18#include <clues/ProcessData.hxx>
19#include <clues/RegisterSet.hxx>
20#include <clues/SystemCallInfo.hxx>
21#include <clues/SystemCallDB.hxx>
22#include <clues/types.hxx>
41 friend class SystemCall;
72 using Flags = cosmos::BitMask<Flag>;
78 const std::string& executable()
const {
79 return m_process_data->executable;
82 const cosmos::StringVector& cmdLine()
const {
83 return m_process_data->cmdline;
91 cosmos::ProcessID pid()
const {
92 return m_ptrace.pid();
96 return pid() != cosmos::ProcessID::INVALID;
99 size_t maxBufferPrefetch()
const {
100 return m_max_buffer_prefetch;
141 static const char* getStateLabel(
const State state);
143 State state()
const {
147 State prevState()
const {
151 bool isEnterStop()
const {
152 return state() == State::SYSCALL_ENTER_STOP;
155 bool isExitStop()
const {
156 return state() == State::SYSCALL_EXIT_STOP;
159 Flags flags()
const {
169 std::optional<cosmos::ChildState>
exitData()
const {
203 long getData(
const ForeignPtr addr)
const;
210 void readString(
const ForeignPtr addr, std::string &out)
const;
213 void readBlob(
const ForeignPtr addr,
char *buffer,
const size_t bytes)
const;
220 template <
typename T,
bool CHECK_TRIVIAL=true>
223 if (addr == ForeignPtr::NO_POINTER)
227 if constexpr (CHECK_TRIVIAL) {
228 static_assert(std::is_trivial_v<T> ==
true);
231 readBlob(addr,
reinterpret_cast<char*
>(&out),
sizeof(T));
236 template <
typename VECTOR>
237 void readVector(
const ForeignPtr pointer, VECTOR &out)
const;
262 bool isThreadGroupLeader()
const;
274 std::optional<SystemCallNr> currentSystemCallNr()
const;
276 const std::optional<SystemCallInfo>& currentSystemCallInfo()
const {
277 return m_syscall_info;
280 const Engine& engine()
const {
293 cosmos::signal::STOP, cosmos::signal::TERM_STOP,
294 cosmos::signal::TERM_INPUT, cosmos::signal::TERM_OUTPUT
305 TraceePtr sibling =
nullptr);
312 void processEvent(
const cosmos::ChildState &data);
314 void updateExecutable();
316 void updateCmdLine();
318 void updateExecInfo() {
323 void syncFDsAfterExec();
325 void changeState(
const State new_state);
333 void restart(
const cosmos::Tracee::RestartMode mode = cosmos::Tracee::RestartMode::CONT,
334 const std::optional<cosmos::Signal> signal = {}) {
335 m_ptrace.restart(mode, signal);
344 void seize(
const cosmos::ptrace::Opts opts) {
349 void setPID(
const cosmos::ProcessID tracee);
358 void handleSystemCall();
360 void handleSystemCallEntry();
362 void handleSystemCallExit();
364 void handleStateMismatch();
366 void handleSignal(
const cosmos::SigInfo &info);
368 void handleEvent(
const cosmos::ChildState &data,
369 const cosmos::ptrace::Event event,
370 const cosmos::Signal signal);
372 void handleStopEvent(
const cosmos::Signal signal);
374 void handleExitEvent();
376 void handleExecEvent(
const cosmos::ProcessID main_pid);
378 void handleNewChildEvent(
const cosmos::ptrace::Event event);
380 void handleAttached();
382 void syncState(
Tracee &other);
387 void attachThreads();
390 template <
typename FILLER>
391 void fillData(
ForeignPtr addr, FILLER &filler)
const;
393 virtual void cleanupChild() {}
399 std::optional<SystemCallNr> getInitialSyscallNr(
const ABI abi)
const;
401 void getInitialRegisters();
403 void unshareProcessData();
416 void handleError(
const cosmos::ApiError &error);
419 bool hasClonedThread()
const;
426 void trackFD(FDInfo &&info)
const;
429 void dropFD(
const cosmos::FileNum fd)
const;
Main class for configuring and running libclues.
Callback interface for consumers of tracing events.
Holds a set of registers for the given ABI.
Stores information about each system call number in form of SystemCall objects.
Access to System Call Data.
Base class for traced processes.
bool isInitiallyAttachedThread() const
Indicates whether this Tracee is an automatically attached thread.
cosmos::ptrace::Opts m_ptrace_opts
The options we've set for ptrace().
ProcessDataPtr m_process_data
Shared process data.
Flag
Different flags reflecting the tracer status.
@ INJECTED_SIGSTOP
whether we've injected a SIGSTOP that needs to be undone.
@ SYSCALL_ENTERED
we've seen a syscall-enter-stop and are waiting for the corresponding exit-stop.
@ SEEN_SIGRETURN
a sigreturn with a pending interrupted system call has been observed.
@ INJECTED_SIGCONT
whether we've injected a SIGCONT that needs to be ignored.
@ DETACH_AT_NEXT_STOP
as soon as the tracee reaches a stop stace, detach from it.
@ WAIT_FOR_ATTACH_STOP
we're still waiting for the PTRACE_INTERRUPT event stop.
@ WAIT_FOR_EXITED
we've already seen PTHREAD_EVENT_EXIT but are still waiting for CLD_EXITED.
@ ATTACH_THREADS_PENDING
attach all threads of the process as soon as the initial event stop happens.
void setMaxBufferPrefetch(const size_t bytes)
Sets an upper limit for the retrieval of variable-length buffer parameters in system calls.
size_t m_max_buffer_prefetch
Number of bytes system calls will fetch for variable-length data buffers.
std::optional< cosmos::Signal > m_stop_signal
For State::GROUP_STOP this contains the signal that caused it.
Tracee(Engine &engine, EventConsumer &consumer, TraceePtr sibling=nullptr)
void seize(const cosmos::ptrace::Opts opts)
Makes the tracee a tracee.
size_t m_syscall_ctr
Number of system calls observed.
SystemCall * m_current_syscall
Holds state for the currently executing system call.
Engine & m_engine
The engine that manages this tracee.
void setOptions(const cosmos::ptrace::Opts opts)
Applies the given trace flags.
std::optional< cosmos::ChildState > m_exit_data
If tracee exit was observed then this contains the final exit data.
Flags m_flags
These keep track of various state on the tracer side.
size_t syscallCtr() const
Returns the number of system calls observed so far.
cosmos::Tracee m_ptrace
libcosmos API for the Tracee.
bool readStruct(const ForeignPtr addr, T &out) const
Reads a system call struct from the tracee's address space into out.
const FDInfoMap & fdInfoMap() const
Provides access to the current knowledge about file descriptors in the tracee.
std::optional< SystemCallInfo > m_syscall_info
The current system call information, if any.
static constexpr std::array< cosmos::Signal, 4 > STOPPING_SIGNALS
Array of signals that cause tracee stop.
State
Current tracing state for a single tracee.
@ DETACHED
we already detached from the tracee
@ SYSCALL_ENTER_STOP
system call started.
@ SYSCALL_EXIT_STOP
system call finished.
@ RUNNING
tracee is running normally / not in a special trace state.
@ SIGNAL_DELIVERY_STOP
signal was delivered.
@ UNKNOWN
initial PTRACE_SIZE / PTRACE_INTERRUPT.
@ EVENT_STOP
special ptrace event occurred.
@ DEAD
the tracee no longer exists.
@ GROUP_STOP
SIGSTOP executed, the tracee is stopped.
void readBlob(const ForeignPtr addr, char *buffer, const size_t bytes) const
Reads an arbitrary binary blob of fixed length from the tracee.
std::optional< cosmos::ChildState > exitData() const
Returns possible tracee exit data.
SystemCall * m_interrupted_syscall
Previous system call, if it has been interrupted.
State m_state
The current state the tracee is in.
std::optional< cosmos::Signal > m_inject_sig
signal to inject upon next restart of the tracee.
std::optional< cosmos::ProcessID > m_initial_attacher
If this Tracee was automatically attached due to AttachThreads{true} then this contains the ProcessID...
virtual bool isChildProcess() const
Returns whether the tracee is a child process created by us.
cosmos::Tracee::RestartMode m_restart_mode
current RestartMode to use.
EventConsumer & m_consumer
Callback interface receiving our information.
std::optional< cosmos::Signal > stopSignal() const
For state() == State::GROUP_STOP this returns the stopping signal that caused it.
void interrupt()
Forces the traced process to stop.
void restart(const cosmos::Tracee::RestartMode mode=cosmos::Tracee::RestartMode::CONT, const std::optional< cosmos::Signal > signal={})
Restarts the traced process, optionally delivering signal.
AnyRegisterSet m_initial_regset
Register set observed during initial attach event stop.
State m_prev_state
The previous Tracee state we've seen (except RUNNING).
SystemCallDB m_syscall_db
Reusable database object for tracing system calls.
cosmos::NamedBool< struct attach_threads_t, true > AttachThreads
A strong boolean type denoting whether to automatically all other threads of a process.
std::variant< RegisterSet< ABI::I386 >, RegisterSet< ABI::X86_64 >, RegisterSet< ABI::X32 >, RegisterSet< ABI::AARCH64 > > AnyRegisterSet
A variant to hold any of the ABI-specific RegisterSet types.
std::map< cosmos::FileNum, FDInfo > FDInfoMap
A mapping of file descriptor numbers to their file system paths or other human readable description o...
cosmos::NamedBool< struct follow_children_t, true > FollowChildren
A strong boolean type denoting whether to automatically attach to newly created child processes.
ForeignPtr
Strongly typed opaque pointer to tracee memory.