libclues
Linux C++ Tracing Library
Loading...
Searching...
No Matches
signal.cxx
1// clues
2#include <clues/format.hxx>
3#include <clues/items/signal.hxx>
4#include <clues/logger.hxx>
5#include <clues/macros.h>
6#include <clues/private/kernel/sigaction.hxx>
7#include <clues/sysnrs/generic.hxx>
8#include <clues/Tracee.hxx>
9
10// cosmos
11#include <cosmos/formatting.hxx>
12#include <cosmos/proc/signal.hxx>
13
14namespace clues::item {
15
16std::string SigSetOperation::str() const {
17 switch (cosmos::to_integral(m_op)) {
18 CASE_ENUM_TO_STR(SIG_BLOCK);
19 CASE_ENUM_TO_STR(SIG_UNBLOCK);
20 CASE_ENUM_TO_STR(SIG_SETMASK);
21 default: return cosmos::sprintf("unknown (%d)", valueAs<int>());
22 }
23}
24
25std::string SignalNumber::str() const {
26 if (m_val == Word::ZERO && m_call->callNr() == SystemCallNr::FCNTL) {
27 /*
28 * this is a special case for fcntl(fd, GETSIG), a zero value
29 * means that SIGIO without extended information is delivered.
30 */
31 return "0 (default SIGIO)";
32 }
33 return format::signal(valueAs<cosmos::SignalNr>());
34}
35
36std::string SigActionParameter::str() const {
37 if (!m_sigaction)
38 return "NULL";
39
40 const auto raw = m_sigaction->raw();
41
42 std::stringstream ss;
43
44 ss
45 << "{"
46 << "handler=";
47
48 if (m_sigaction->getFlags()[cosmos::SigAction::Flag::SIGINFO]) {
49 ss << format::pointer(ForeignPtr{reinterpret_cast<uintptr_t>(raw->sa_sigaction)});
50 } else {
51 if (raw->sa_handler == SIG_IGN)
52 ss << "SIG_IGN";
53 else if (raw->sa_handler == SIG_DFL)
54 ss << "SIG_DFL";
55 else
56 ss << format::pointer(ForeignPtr{reinterpret_cast<uintptr_t>(raw->sa_handler)});
57 }
58
59 ss << ", mask=" << format::signal_set(m_sigaction->mask()) << ", flags="
60 << format::saflags(m_sigaction->getFlags().raw()) << ", restorer="
61 << format::pointer(ForeignPtr{reinterpret_cast<uintptr_t>(raw->sa_restorer)}) << "}";
62
63 return ss.str();
64}
65
66namespace {
67
68template <typename KERN_SIGACTION>
69void convert_to(const KERN_SIGACTION &kern_act, cosmos::SigAction &action) {
70 auto raw_act = const_cast<struct sigaction*>(static_cast<const cosmos::SigAction&>(action).raw());
71 auto &mask = action.mask();
72 mask.clear();
73
74 if constexpr (sizeof(kern_act.mask) > 4) {
75 *mask.raw() = kern_act.mask;
76 }
77
78 if constexpr (sizeof(kern_act.mask) == 4) {
79 /*
80 * old sigaction struct, only assign the first word of the
81 * sigset. For this we need to fiddle in the private data
82 * portion of libc's sigset_t...
83 */
84 mask.raw()->__val[0] = kern_act.mask;
85 }
86
87 using RestorerPtr = void (*)();
88 using HandlerPtr = void (*)(int);
89
90 /*
91 * TODO: the cosmos::SigAction object is applying some magic to the
92 * signal handler callback which doesn't fit our tracing scenario
93 * well.
94 *
95 * The type assumes that the information is always for the current
96 * process, thus it won't reflect properly our situation. We'd need a
97 * dedicated, maybe at least derived type to fix this.
98 */
99 raw_act->sa_restorer = (RestorerPtr)(uintptr_t)kern_act.restorer;
100 raw_act->sa_handler = (HandlerPtr)(uintptr_t)kern_act.handler;
101 raw_act->sa_flags = static_cast<int>(kern_act.flags);
102
103}
104
105template <typename KERN_SIGACTION>
106void fetch_sigaction(const ForeignPtr ptr, const Tracee &proc, std::optional<cosmos::SigAction> &action) {
107 KERN_SIGACTION kern_act;
108
109 if (!proc.readStruct(ptr, kern_act)) {
110 action.reset();
111 return;
112 }
113
114 convert_to(kern_act, *action);
115}
116
117} // end anon ns
118
120
121 if (isOut() && proc.isEnterStop()) {
122 m_sigaction.reset();
123 return;
124 }
125
126 if (!m_sigaction) {
127 m_sigaction = cosmos::SigAction{};
128 }
129
130 switch (m_call->callNr()) {
131 case SystemCallNr::RT_SIGACTION: {
132 if (m_call->is32BitEmulationABI()) {
133 fetch_sigaction<kernel_sigaction32>(asPtr(), proc, m_sigaction);
134 } else {
135 fetch_sigaction<kernel_sigaction>(asPtr(), proc, m_sigaction);
136 }
137 break;
138 } case SystemCallNr::SIGACTION: {
139 fetch_sigaction<kernel_old_sigaction>(asPtr(), proc, m_sigaction);
140 break;
141 } default: {
142 m_sigaction.reset();
143 LOG_WARN("Unexpected system call encountered in SigActionParameter");
144 break;
145 }
146 }
147}
148
150 if (proc.isEnterStop() && isOut()) {
151 m_sigset.reset();
152 return;
153 }
154
155 if (!m_sigset) {
156 m_sigset = cosmos::SigSet{};
157 }
158
159 if (m_call->callNr() == SystemCallNr::SIGPROCMASK) {
160 uint32_t mask;
161 /* legacy i386 sigprocmask() using a 32-bit sigset_t */
162 if (!proc.readStruct(asPtr(), mask)) {
163 m_sigset.reset();
164 return;
165 }
166
167 m_sigset->raw()->__val[0] = mask;
168 } else {
169 if (!proc.readStruct(asPtr(), *m_sigset->raw())) {
170 m_sigset.reset();
171 return;
172 }
173 }
174}
175
176std::string SigSetParameter::str() const {
177 if (m_sigset) {
178 return format::signal_set(*m_sigset);
179 } else {
180 return "NULL";
181 }
182}
183
184} // end ns
const SystemCall * m_call
The system call context this item part of.
OTHER valueAs() const
Helper to cast the strongly typed Word m_val to other strong enum types.
Word m_val
The raw register value for the item.
Base class for traced processes.
Definition Tracee.hxx:39
bool readStruct(const ForeignPtr addr, T &out) const
Reads a system call struct from the tracee's address space into out.
Definition Tracee.hxx:221
std::string str() const override
Returns a human readable string representation of the item.
Definition signal.cxx:36
void processValue(const Tracee &proc) override
Processes the value stored in m_val acc. to the actual item type.
Definition signal.cxx:119
std::string str() const override
Returns a human readable string representation of the item.
Definition signal.cxx:16
std::string str() const override
Returns a human readable string representation of the item.
Definition signal.cxx:176
void processValue(const Tracee &proc) override
Processes the value stored in m_val acc. to the actual item type.
Definition signal.cxx:149
std::string str() const override
Returns a human readable string representation of the item.
Definition signal.cxx:25
ForeignPtr
Strongly typed opaque pointer to tracee memory.
Definition types.hxx:140