2#include <cosmos/error/ApiError.hxx>
3#include <cosmos/error/RuntimeError.hxx>
4#include <cosmos/formatting.hxx>
5#include <cosmos/fs/filesystem.hxx>
6#include <cosmos/io/ILogger.hxx>
7#include <cosmos/proc/ChildCloner.hxx>
10#include <clues/ChildTracee.hxx>
11#include <clues/logger.hxx>
38 if (args.empty() || !cosmos::fs::which(args[0])) {
40 throw cosmos::RuntimeError{
41 cosmos::sprintf(
"%s: does not exist or is not executable",
42 args.empty() ?
"<empty-path>" : args[0].c_str())};
45 cosmos::ChildCloner cloner;
47 cloner.setPostForkCB([](
const cosmos::ChildCloner &){
49 cosmos::signal::raise(cosmos::signal::STOP);
53 m_child.wait(cosmos::WaitFlags{cosmos::WaitFlag::WAIT_FOR_STOPPED});
59ChildTracee::~ChildTracee() {
64 m_child.kill(cosmos::signal::KILL);
69 }
catch (
const cosmos::CosmosError &ce) {
70 LOG_ERROR(
"Error detaching from child process PID "
71 << cosmos::to_integral(
m_child.pid()) <<
":\n\n"
76void ChildTracee::cleanupChild() {
85 }
catch (
const cosmos::ApiError &error) {
86 if (error.errnum() != cosmos::Errno::NO_CHILD) {
ChildTracee(Engine &engine, EventConsumer &consumer)
Create a traced process by creating a new process from prog_args
cosmos::SubProc m_child
the sub-process we're tracing
void create(const cosmos::StringVector &args)
Create the child process with the given parameters.
Callback interface for consumers of tracing events.
void setPID(const cosmos::ProcessID tracee)
Sets the tracee PID.
@ INJECTED_SIGSTOP
whether we've injected a SIGSTOP that needs to be undone.
Tracee(Engine &engine, EventConsumer &consumer, TraceePtr sibling=nullptr)
Flags m_flags
These keep track of various state on the tracer side.
@ DEAD
the tracee no longer exists.