From c5481367487c42c2085efd48a40f0f7613c2d378 Mon Sep 17 00:00:00 2001 From: Jérôme Duval Date: Sat, 15 Nov 2025 16:16:41 +0100 Subject: [PATCH] strace: dump sigset_t, sigprocmask Change-Id: Idbe11f05b5a254054b2d50091fefeaf43be8dd08 Reviewed-on: https://review.haiku-os.org/c/haiku/+/9881 Tested-by: Commit checker robot Reviewed-by: waddlesplash Reviewed-by: Jérôme Duval --- src/bin/debug/strace/signals.cpp | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/bin/debug/strace/strace.cpp | 2 ++ 2 files changed, 153 insertions(+) diff --git a/src/bin/debug/strace/signals.cpp b/src/bin/debug/strace/signals.cpp index d517178..3a2165d 100644 --- a/src/bin/debug/strace/signals.cpp +++ b/src/bin/debug/strace/signals.cpp @@ -9,6 +9,11 @@ #include #include "signals.h" +#include "strace.h" +#include "Context.h" +#include "MemoryReader.h" +#include "Syscall.h" +#include "TypeHandler.h" // signal names @@ -49,6 +54,67 @@ }; +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) { @@ -198,4 +264,89 @@ string += "}"; 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); + } diff --git a/src/bin/debug/strace/strace.cpp b/src/bin/debug/strace/strace.cpp index 9577263..11531ad 100644 --- a/src/bin/debug/strace/strace.cpp +++ b/src/bin/debug/strace/strace.cpp @@ -238,6 +238,7 @@ 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_mutex(); patch_network(); patch_rlimit(); + patch_signal(); } -- gitore 0.2.3