⛏️ index : haiku.git

author Jérôme Duval <jerome.duval@gmail.com> 2025-11-15 16:16:41.0 +01:00:00
committer Jérôme Duval <jerome.duval@gmail.com> 2025-11-23 14:02:58.0 +00:00:00
commit
c5481367487c42c2085efd48a40f0f7613c2d378 [patch]
tree
1b9adc8fc2c01308b047983b71e72ae868852d27
parent
b5f59c2d1c086a13e638c19f13083932be9ec30f
download
c5481367487c42c2085efd48a40f0f7613c2d378.tar.gz

strace: dump sigset_t, sigprocmask

Change-Id: Idbe11f05b5a254054b2d50091fefeaf43be8dd08
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9881
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>

Diff

 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 <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 @@
};


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();
}