|
libclues
Linux C++ Tracing Library
|
Main class for configuring and running libclues. More...
#include <Engine.hxx>
Public Types | |
| enum class | FormatFlag : uint64_t { FD_INFO = 1 } |
| using | FormatFlags = cosmos::BitMask<FormatFlag> |
Public Member Functions | |
| Engine (EventConsumer &consumer) | |
Creates a new Engine that reports events to consumer. | |
| virtual | ~Engine () |
| Tear down any tracees. | |
| TraceePtr | addTracee (const cosmos::ProcessID pid, const FollowChildren follow_children, const AttachThreads attach_threads, const cosmos::ProcessID sibling=cosmos::ProcessID::INVALID) |
Add the given pid as tracee. | |
| TraceePtr | addTracee (const cosmos::StringVector &cmdline, const FollowChildren follow_children) |
| Create a new child process to be traced. | |
| void | trace () |
| Enter the tracing main loop and process tracing events. | |
| void | stop (const std::optional< cosmos::Signal > signal) |
| Stop tracing any active tracees. | |
| FormatFlags | formatFlags () const |
| void | setFormatFlags (const FormatFlags flags) |
| Change formatting behaviour for system calls. | |
Protected Types | |
| enum class | Decision { RETRY , DROP , STORE , DONE } |
| Different decisions what to do with ptrace events. More... | |
| using | TraceeMap = std::map<cosmos::ProcessID, TraceePtr> |
| using | EventMap = std::map<cosmos::ProcessID, cosmos::ChildState> |
Protected Member Functions | |
| void | checkCleanupTracee (TraceeMap::iterator it) |
| void | checkUnknownEvents () |
| Decision | handleEvent (const cosmos::ChildState &data) |
| void | handleNoChildren () |
| Decision | checkUnknownTraceeEvent (const cosmos::ChildState &data) |
| Check the given trace event if we can make sense of it. | |
| bool | tryUpdateTraceePID (const cosmos::ProcessID old_pid, const cosmos::ProcessID new_pid) |
| void | handleAutoAttach (Tracee &parent, const cosmos::ProcessID pid, const cosmos::ptrace::Event event, const SystemCall &sc) |
| Invoked by a Tracee once a new child process is auto-attached. | |
| TraceePtr | handleSubstitution (const cosmos::ProcessID old_pid) |
| Invoked by a Tracee when multi-threaded execve() leads to substitution of a PID by another. | |
Protected Attributes | |
| TraceeMap | m_tracees |
| Currently active tracees. | |
| EventMap | m_unknown_events |
| Unknown ptrace events stored for later processing. | |
| cosmos::ProcessID | m_newly_attached_pid = cosmos::ProcessID::INVALID |
| The PID of a newly auto-attached Tracee, if any. | |
| EventConsumer & | m_consumer |
| FormatFlags | m_format_flags |
| Format settings for all tracees attached to this engine. | |
Friends | |
| class | Tracee |
Main class for configuring and running libclues.
This is the main class for configuring Tracee's and actually performing tracing. The tracing main loop is implemented here and callbacks are delivered to the EventConsumer interface.
Note that this class uses the wait() family of system calls to keep track of trace events. This API consumes process-global events, which means that there will be problems if other components in the same process deal with child processes, like:
For this reason it is simply not sensibly possible to create regular child process in parallel to tracing.
Definition at line 45 of file Engine.hxx.
|
protected |
Definition at line 171 of file Engine.hxx.
| using clues::Engine::FormatFlags = cosmos::BitMask<FormatFlag> |
Definition at line 53 of file Engine.hxx.
|
protected |
Definition at line 169 of file Engine.hxx.
|
strongprotected |
Different decisions what to do with ptrace events.
| Enumerator | |
|---|---|
| RETRY | retry processing the event. |
| DROP | ignore/drop the event. |
| STORE | store the event for later. |
| DONE | the event has been successfully processed. |
Definition at line 174 of file Engine.hxx.
|
strong |
| Enumerator | |
|---|---|
| FD_INFO | print detailed file descriptor information |
Definition at line 49 of file Engine.hxx.
|
inlineexplicit |
Creates a new Engine that reports events to consumer.
Definition at line 58 of file Engine.hxx.
|
virtual |
Tear down any tracees.
If tracees are still present then they will be detached from via stop(cosmos::signal::KILL).
Definition at line 18 of file Engine.cxx.
| TraceePtr clues::Engine::addTracee | ( | const cosmos::ProcessID | pid, |
| const FollowChildren | follow_children, | ||
| const AttachThreads | attach_threads, | ||
| const cosmos::ProcessID | sibling = cosmos::ProcessID::INVALID ) |
Add the given pid as tracee.
For tracing unrelated processes the current process needs to have sufficient privileges. This is usually the case if you are root or if the target process has the same credentials as the current process.
The Linux Yama kernel security module can further restrict tracing of unrelated processes. Check the /proc/sys/kernel/yama/ptrace_scope file for more information.
If attaching fails then this call immediately throws an exception.
On success the target process will be interrupted to determine its current state. Any state can be encountered and the caller needs to be prepared for any kind of tracing event (signal, system call, process exit, ...) to occur as a result.
follow_children determines whether newly created child processes will automatically be attached.
attach_threads determines whether other threads of the target process should automatically be attached, too.
sibling“, if set, refers to an existing Tracee that belongs to the same process aspid`. The tracees will then share the same ProcessData.
Definition at line 38 of file Engine.cxx.
| TraceePtr clues::Engine::addTracee | ( | const cosmos::StringVector & | cmdline, |
| const FollowChildren | follow_children ) |
Create a new child process to be traced.
Use this function to create a new child process which will be traced from the very beginning. The first tracing event observed will typically be a system call entry.
follow_children determines whether newly created child processes will automatically be attached.
The library will perform an initial check whether the executable specified in cmdline exists and is executable. If this is not the case, then a RuntimeError is thrown. There can be other errors trying to execute the new process that cannot be caught before the new process is forked. To catch these situations, it is best to observe the tracee's system calls: If it exits before a successful initial execve() system call occurred, then a pre execution error happened.
Definition at line 51 of file Engine.cxx.
|
protected |
Definition at line 59 of file Engine.cxx.
|
protected |
Definition at line 72 of file Engine.cxx.
|
protected |
Check the given trace event if we can make sense of it.
If the function was able to adjust internal state for being able to properly handle data, then it returns true and a retry should be performed. Otherwise false is returned and the event should be discarded.
Definition at line 192 of file Engine.cxx.
|
inline |
Definition at line 154 of file Engine.hxx.
|
protected |
Invoked by a Tracee once a new child process is auto-attached.
pid provides the process ID of the new child process and event describes the event that triggered the creation of the new child. sc refers to the system call that lead to the creation of the new child, providing additional details of child properties.
Definition at line 263 of file Engine.cxx.
|
protected |
Definition at line 157 of file Engine.cxx.
|
protected |
Definition at line 88 of file Engine.cxx.
|
protected |
Invoked by a Tracee when multi-threaded execve() leads to substitution of a PID by another.
Definition at line 304 of file Engine.cxx.
|
inline |
Change formatting behaviour for system calls.
These flags influences the implementation of SystemCallItem::str(). See FormatFlag for details.
Definition at line 163 of file Engine.hxx.
| void clues::Engine::stop | ( | const std::optional< cosmos::Signal > | signal | ) |
Stop tracing any active tracees.
If you want to stop a running trace then you can call this function to initiate detach from all active tracees. Each tracee will either be immediately be detached from, if its current state allows this, or it will be interrupted to detach from it during the next ptrace event.
If new child processes have been created for tracing then signal determines how they will be dealt with:
signal denotes the signal that will be sent to direct children to have them terminate in a timely fashion. cosmos::signal::KILL will be the safest way to tear down any remaining child processes.After calling this function an active trace() invocation should be returning soon. Further trace events may be reported to the EventConsumer interface until the detachment process is complete.
Definition at line 249 of file Engine.cxx.
| void clues::Engine::trace | ( | ) |
Enter the tracing main loop and process tracing events.
At least one tracee must have been added via addTracee() for this call to do anything. The call will block and deliver tracing events to the given consumer interface until all of the tracees have exited or have been detached from.
Definition at line 119 of file Engine.cxx.
|
protected |
Definition at line 234 of file Engine.cxx.
|
friend |
Definition at line 46 of file Engine.hxx.
|
protected |
Definition at line 223 of file Engine.hxx.
|
protected |
Format settings for all tracees attached to this engine.
Definition at line 225 of file Engine.hxx.
|
protected |
The PID of a newly auto-attached Tracee, if any.
Definition at line 222 of file Engine.hxx.
|
protected |
Currently active tracees.
Definition at line 218 of file Engine.hxx.
|
protected |
Unknown ptrace events stored for later processing.
Definition at line 220 of file Engine.hxx.