strace: dump sigset_t, sigprocmask

Change-Id: Idbe11f05b5a254054b2d50091fefeaf43be8dd08
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9881
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
Reviewed-by: Jérôme Duval <[email protected]>
This commit is contained in:
Jérôme Duval
2025-11-23 14:02:58 +00:00
parent b5f59c2d1c
commit c548136748
2 changed files with 153 additions and 0 deletions
+151
View File
@@ -9,6 +9,11 @@
#include <string>
#include "signals.h"
#include "strace.h"
#include "Context.h"
#include "MemoryReader.h"
#include "Syscall.h"
#include "TypeHandler.h"
// signal names
@@ -49,6 +54,67 @@ static const char *kSignalName[] = {
};
struct enum_info {
int index;
const char *name;
};
#define ENUM_INFO_ENTRY(name) \
{ name, #name }
static const enum_info kSigmaskHow[] = {
ENUM_INFO_ENTRY(SIG_BLOCK),
ENUM_INFO_ENTRY(SIG_UNBLOCK),
ENUM_INFO_ENTRY(SIG_SETMASK),
{ 0, NULL }
};
#define sigmask(sig) (1 << ((sig) - 1))
#define FLAG_INFO_ENTRY(name) \
{ sigmask( SIG##name ), #name }
static const FlagsTypeHandler::FlagInfo kSigmaskFlagsInfo[] = {
FLAG_INFO_ENTRY(HUP),
FLAG_INFO_ENTRY(INT),
FLAG_INFO_ENTRY(QUIT),
FLAG_INFO_ENTRY(ILL),
FLAG_INFO_ENTRY(CHLD),
FLAG_INFO_ENTRY(ABRT),
FLAG_INFO_ENTRY(PIPE),
FLAG_INFO_ENTRY(FPE),
FLAG_INFO_ENTRY(KILL),
FLAG_INFO_ENTRY(STOP),
FLAG_INFO_ENTRY(SEGV),
FLAG_INFO_ENTRY(CONT),
FLAG_INFO_ENTRY(TSTP),
FLAG_INFO_ENTRY(ALRM),
FLAG_INFO_ENTRY(TERM),
FLAG_INFO_ENTRY(TTIN),
FLAG_INFO_ENTRY(TTOU),
FLAG_INFO_ENTRY(USR1),
FLAG_INFO_ENTRY(USR2),
FLAG_INFO_ENTRY(WINCH),
FLAG_INFO_ENTRY(KILLTHR),
FLAG_INFO_ENTRY(TRAP),
FLAG_INFO_ENTRY(POLL),
FLAG_INFO_ENTRY(PROF),
FLAG_INFO_ENTRY(SYS),
FLAG_INFO_ENTRY(URG),
FLAG_INFO_ENTRY(VTALRM),
FLAG_INFO_ENTRY(XCPU),
FLAG_INFO_ENTRY(XFSZ),
FLAG_INFO_ENTRY(BUS),
{ 0, NULL }
};
static FlagsTypeHandler::FlagsList kSigmaskFlags;
static EnumTypeHandler::EnumMap kSigmaskHowMap;
std::string
signal_name(int signal)
{
@@ -199,3 +265,88 @@ signal_info(siginfo_t& info)
return string;
}
class SigsetTypeHandler : public FlagsTypeHandler {
public:
SigsetTypeHandler()
:
FlagsTypeHandler(kSigmaskFlags)
{
}
string GetParameterValue(Context &context, Parameter *param,
const void *address)
{
void *data = *(void **)address;
if (context.GetContents(Context::POINTER_VALUES)) {
int32 bytesRead;
sigset_t value;
status_t err = context.Reader().Read(data, &value, sizeof(value), bytesRead);
if (err != B_OK)
return context.FormatPointer(data);
uint32 count = 0;
#if __GNUC__ > 2
count += __builtin_popcount(value);
#else
{
sigset_t mask = value;
while (mask > 0) {
if ((mask & 1) == 1)
count++;
mask >>= 1;
}
}
#endif
string r;
// when more than 2/3 of the signals are set, inverse
if (count > SIGRESERVED2 * 2 / 3) {
value = ~value;
r += "~";
}
value &= (((sigset_t)1 << SIGRESERVED2) - 1);
r += "[";
r += RenderValue(context, value);
r += "]";
return r;
}
return context.FormatPointer(data);
}
string GetReturnValue(Context &context, uint64 value)
{
return context.FormatPointer((void *)value);
}
};
void
patch_signal()
{
for (int i = 0; kSigmaskFlagsInfo[i].name != NULL; i++)
kSigmaskFlags.push_back(kSigmaskFlagsInfo[i]);
for (int i = 0; kSigmaskHow[i].name != NULL; i++) {
kSigmaskHowMap[kSigmaskHow[i].index] = kSigmaskHow[i].name;
}
Syscall *setSignalMask = get_syscall("_kern_set_signal_mask");
setSignalMask->GetParameter("how")->SetHandler(new EnumTypeHandler(kSigmaskHowMap));
setSignalMask->GetParameter("set")->SetHandler(new SigsetTypeHandler());
setSignalMask->GetParameter("oldSet")->SetHandler(new SigsetTypeHandler());
setSignalMask->GetParameter("oldSet")->SetOut(true);
Syscall *sigwait = get_syscall("_kern_sigwait");
sigwait->GetParameter("set")->SetHandler(new SigsetTypeHandler());
sigwait->GetParameter("info")->SetOut(true);
Syscall *sigsuspend = get_syscall("_kern_sigsuspend");
sigsuspend->GetParameter("mask")->SetHandler(new SigsetTypeHandler());
Syscall *sigpending = get_syscall("_kern_sigpending");
sigpending->GetParameter("set")->SetHandler(new SigsetTypeHandler());
sigpending->GetParameter("set")->SetOut(true);
}
+2
View File
@@ -238,6 +238,7 @@ patch_syscalls()
extern void patch_mutex();
extern void patch_network();
extern void patch_rlimit();
extern void patch_signal();
for (size_t i = 0; i < sSyscallVector.size(); i++) {
Syscall *syscall = sSyscallVector[i];
@@ -261,6 +262,7 @@ patch_syscalls()
patch_mutex();
patch_network();
patch_rlimit();
patch_signal();
}