From 29f8da76d725d38998854d2fb7c8e0cc9498407d Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Fri, 9 Jun 2023 20:21:35 +1000 Subject: [PATCH] strace: Add mutex type Added a dedicated mutex type handler that can print mutex status flags while still showing the mutex address. Change-Id: Ie028e5c0a336063a4c03a4f9adf955ffa6911837 Reviewed-on: https://review.haiku-os.org/c/haiku/+/6557 Reviewed-by: waddlesplash --- src/bin/debug/strace/Jamfile | 1 + src/bin/debug/strace/TypeHandler.h | 3 +- src/bin/debug/strace/mutex.cpp | 83 ++++++++++++++++++++++++++++++ src/bin/debug/strace/strace.cpp | 2 + 4 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/bin/debug/strace/mutex.cpp diff --git a/src/bin/debug/strace/Jamfile b/src/bin/debug/strace/Jamfile index 382f60853d..cf557990a5 100644 --- a/src/bin/debug/strace/Jamfile +++ b/src/bin/debug/strace/Jamfile @@ -24,6 +24,7 @@ local straceSources = exec.cpp fcntl.cpp ioctl.cpp + mutex.cpp network.cpp signals.cpp ; diff --git a/src/bin/debug/strace/TypeHandler.h b/src/bin/debug/strace/TypeHandler.h index 6e803e8db0..4943d5df94 100644 --- a/src/bin/debug/strace/TypeHandler.h +++ b/src/bin/debug/strace/TypeHandler.h @@ -63,9 +63,10 @@ public: string GetParameterValue(Context &c, Parameter *, const void *); string GetReturnValue(Context &, uint64 value); -private: +protected: string RenderValue(Context &, unsigned int value) const; +private: const FlagsList &fList; }; diff --git a/src/bin/debug/strace/mutex.cpp b/src/bin/debug/strace/mutex.cpp new file mode 100644 index 0000000000..519e80fec9 --- /dev/null +++ b/src/bin/debug/strace/mutex.cpp @@ -0,0 +1,83 @@ +/* + * Copyright 2023, Trung Nguyen, trungnt282910@gmail.com. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include + +#include "strace.h" +#include "Context.h" +#include "MemoryReader.h" +#include "TypeHandler.h" + + +#define FLAG_INFO_ENTRY(name) \ + { name, #name } + +static const FlagsTypeHandler::FlagInfo kMutexFlagsInfo[] = { + FLAG_INFO_ENTRY(B_USER_MUTEX_LOCKED), + FLAG_INFO_ENTRY(B_USER_MUTEX_WAITING), + FLAG_INFO_ENTRY(B_USER_MUTEX_DISABLED), + + { 0, NULL } +}; + +static FlagsTypeHandler::FlagsList kMutexFlags; + + +class MutexTypeHandler : public FlagsTypeHandler { +public: + MutexTypeHandler() + : + FlagsTypeHandler(kMutexFlags) + { + } + + string GetParameterValue(Context &context, Parameter *param, + const void *address) + { + void *data = *(void **)address; + + if (context.GetContents(Context::POINTER_VALUES)) { + int32 value, bytesRead; + status_t err = context.Reader().Read(data, &value, sizeof(value), bytesRead); + if (err != B_OK) + return context.FormatPointer(data); + + string r = context.FormatPointer(data); + r += " ["; + r += RenderValue(context, (unsigned int)value); + r += "]"; + return r; + } + + return context.FormatPointer(data); + } + + string GetReturnValue(Context &context, uint64 value) + { + return context.FormatPointer((void *)value); + } +}; + + +void +patch_mutex() +{ + for (int i = 0; kMutexFlagsInfo[i].name != NULL; i++) { + kMutexFlags.push_back(kMutexFlagsInfo[i]); + } + + Syscall *mutex_lock = get_syscall("_kern_mutex_lock"); + mutex_lock->GetParameter("mutex")->SetHandler(new MutexTypeHandler()); + + Syscall *mutex_unlock = get_syscall("_kern_mutex_unblock"); + mutex_unlock->GetParameter("mutex")->SetHandler(new MutexTypeHandler()); + + Syscall *mutex_switch_lock = get_syscall("_kern_mutex_switch_lock"); + mutex_switch_lock->GetParameter("fromMutex")->SetHandler(new MutexTypeHandler()); + mutex_switch_lock->GetParameter("toMutex")->SetHandler(new MutexTypeHandler()); +} diff --git a/src/bin/debug/strace/strace.cpp b/src/bin/debug/strace/strace.cpp index dd9b4de90a..876ca6ec5b 100644 --- a/src/bin/debug/strace/strace.cpp +++ b/src/bin/debug/strace/strace.cpp @@ -233,6 +233,7 @@ patch_syscalls() extern void patch_exec(); extern void patch_fcntl(); extern void patch_ioctl(); + extern void patch_mutex(); extern void patch_network(); for (size_t i = 0; i < sSyscallVector.size(); i++) { @@ -250,6 +251,7 @@ patch_syscalls() patch_exec(); patch_fcntl(); patch_ioctl(); + patch_mutex(); patch_network(); }