diff --git a/src/bin/debug/strace/Jamfile b/src/bin/debug/strace/Jamfile index cf557990a5..f32b00bf73 100644 --- a/src/bin/debug/strace/Jamfile +++ b/src/bin/debug/strace/Jamfile @@ -21,6 +21,7 @@ local straceSources = MemoryReader.cpp area.cpp + events.cpp exec.cpp fcntl.cpp ioctl.cpp diff --git a/src/bin/debug/strace/NetworkTypes.cpp b/src/bin/debug/strace/NetworkTypes.cpp index 2129ed040a..06e7bbb562 100644 --- a/src/bin/debug/strace/NetworkTypes.cpp +++ b/src/bin/debug/strace/NetworkTypes.cpp @@ -101,68 +101,6 @@ TypeHandlerImpl::GetReturnValue(Context &context, uint64 value) } -static string -read_fdset(Context &context, void *data) -{ - // default FD_SETSIZE is 1024 - unsigned long tmp[1024 / (sizeof(unsigned long) * 8)]; - int32 bytesRead; - - status_t err = context.Reader().Read(data, &tmp, sizeof(tmp), bytesRead); - if (err != B_OK) - return context.FormatPointer(data); - - /* implicitly align to unsigned long lower boundary */ - int count = bytesRead / sizeof(unsigned long); - int added = 0; - - string r; - r.reserve(16); - - r = "["; - - for (int i = 0; i < count && added < 8; i++) { - for (int j = 0; - j < (int)(sizeof(unsigned long) * 8) && added < 8; j++) { - if (tmp[i] & (1UL << j)) { - if (added > 0) - r += " "; - unsigned int fd = i * sizeof(unsigned long) * 8 + j; - r += format_number(fd); - added++; - } - } - } - - if (added >= 8) - r += " ..."; - - r += "]"; - - return r; -} - - -template<> -string -TypeHandlerImpl::GetParameterValue(Context &context, Parameter *, - const void *address) -{ - void *data = *(void **)address; - if (data != NULL && context.GetContents(Context::SIMPLE_STRUCTS)) - return read_fdset(context, data); - return context.FormatPointer(data); -} - - -template<> -string -TypeHandlerImpl::GetReturnValue(Context &context, uint64 value) -{ - return context.FormatPointer((void *)value); -} - - static string format_ltype(Context &context, int ltype) { @@ -219,127 +157,6 @@ format_pointer(Context &context, flock *lock) -static string -format_signed_number(int32 value) -{ - char tmp[32]; - snprintf(tmp, sizeof(tmp), "%d", (signed int)value); - return tmp; -} - - -static string -read_pollfd(Context &context, void *data) -{ - nfds_t numfds = context.ReadValue(context.GetSibling(1)); - if ((int64)numfds <= 0) - return string(); - - pollfd tmp[numfds]; - int32 bytesRead; - - status_t err = context.Reader().Read(data, &tmp, sizeof(tmp), bytesRead); - if (err != B_OK) - return context.FormatPointer(data); - - int added = 0; - - string r; - r.reserve(16); - - r = "["; - - for (nfds_t i = 0; i < numfds && added < 8; i++) { - if ((tmp[i].fd == -1 || tmp[i].revents == 0) - && context.GetContents(Context::OUTPUT_VALUES)) { - continue; - } - if (added > 0) - r += ", "; - r += "{fd=" + format_signed_number(tmp[i].fd); - if (tmp[i].fd != -1 && context.GetContents(Context::INPUT_VALUES)) { - r += ", events="; - int flags = 0; - if ((tmp[i].events & POLLIN) != 0) { - if (flags > 0) - r += "|"; - r += "POLLIN"; - flags++; - } - if ((tmp[i].events & POLLOUT) != 0) { - if (flags > 0) - r += "|"; - r += "POLLOUT"; - flags++; - } - } - if (context.GetContents(Context::OUTPUT_VALUES)) { - r += ", revents="; - int flags = 0; - if ((tmp[i].revents & POLLIN) != 0) { - if (flags > 0) - r += "|"; - r += "POLLIN"; - flags++; - } - if ((tmp[i].revents & POLLOUT) != 0) { - if (flags > 0) - r += "|"; - r += "POLLOUT"; - flags++; - } - if ((tmp[i].revents & POLLERR) != 0) { - if (flags > 0) - r += "|"; - r += "POLLERR"; - flags++; - } - if ((tmp[i].revents & POLLHUP) != 0) { - if (flags > 0) - r += "|"; - r += "POLLHUP"; - flags++; - } - if ((tmp[i].revents & POLLNVAL) != 0) { - if (flags > 0) - r += "|"; - r += "POLLNVAL"; - flags++; - } - } - added++; - r += "}"; - } - - if (added >= 8) - r += " ..."; - - r += "]"; - - return r; -} - - -template<> -string -TypeHandlerImpl::GetParameterValue(Context &context, Parameter *, - const void *address) -{ - void *data = *(void **)address; - if (data != NULL && context.GetContents(Context::SIMPLE_STRUCTS)) - return read_pollfd(context, data); - return context.FormatPointer(data); -} - - -template<> -string -TypeHandlerImpl::GetReturnValue(Context &context, uint64 value) -{ - return context.FormatPointer((void *)value); -} - - template static string format_pointer_value(Context &context, void *address) @@ -769,12 +586,6 @@ class SpecializedPointerTypeHandler : public TypeHandler { } }; -#define DEFINE_TYPE(name, type) \ - TypeHandler *create_##name##_type_handler() \ - { \ - return new TypeHandlerImpl(); \ - } - #define POINTER_TYPE(name, type) \ TypeHandler *create_##name##_type_handler() \ { \ @@ -782,11 +593,9 @@ class SpecializedPointerTypeHandler : public TypeHandler { } DEFINE_TYPE(iovec_ptr, iovec *); -DEFINE_TYPE(fdset_ptr, fd_set *); POINTER_TYPE(flock_ptr, flock); POINTER_TYPE(ifconf_ptr, ifconf); POINTER_TYPE(ifreq_ptr, ifreq); -DEFINE_TYPE(pollfd_ptr, pollfd *); POINTER_TYPE(siginfo_t_ptr, siginfo_t); POINTER_TYPE(msghdr_ptr, msghdr); DEFINE_TYPE(sockaddr_ptr, sockaddr *); @@ -796,4 +605,3 @@ POINTER_TYPE(sockaddr_args_ptr, sockaddr_args); POINTER_TYPE(sockopt_args_ptr, sockopt_args); POINTER_TYPE(socket_args_ptr, socket_args); #endif - diff --git a/src/bin/debug/strace/TypeHandler.h b/src/bin/debug/strace/TypeHandler.h index 15057b179b..e2535c2144 100644 --- a/src/bin/debug/strace/TypeHandler.h +++ b/src/bin/debug/strace/TypeHandler.h @@ -44,9 +44,9 @@ public: string GetParameterValue(Context &c, Parameter *, const void *); string GetReturnValue(Context &, uint64 value); -private: string RenderValue(Context &, unsigned int value) const; +private: const EnumMap &fMap; }; @@ -63,7 +63,6 @@ public: string GetParameterValue(Context &c, Parameter *, const void *); string GetReturnValue(Context &, uint64 value); -protected: string RenderValue(Context &, unsigned int value) const; private: @@ -119,6 +118,12 @@ struct TypeHandlerFactory { } \ } \ +#define DEFINE_TYPE(name, type) \ + TypeHandler *create_##name##_type_handler() \ + { \ + return new TypeHandlerImpl(); \ + } + struct fd_set; struct flock; struct ifconf; diff --git a/src/bin/debug/strace/events.cpp b/src/bin/debug/strace/events.cpp new file mode 100644 index 0000000000..072abe75b1 --- /dev/null +++ b/src/bin/debug/strace/events.cpp @@ -0,0 +1,209 @@ +/* + * Copyright 2023-2024, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include +#include + +#include "strace.h" +#include "Syscall.h" +#include "Context.h" +#include "MemoryReader.h" +#include "TypeHandler.h" + + +// #pragma mark - enums & flags handlers + + +struct enum_info { + unsigned int index; + const char *name; +}; + +#define ENUM_INFO_ENTRY(name) \ + { name, #name } + + +#define FLAG_INFO_ENTRY(name) \ + { name, #name } + + +static const FlagsTypeHandler::FlagInfo kPollFlagInfos[] = { + FLAG_INFO_ENTRY(POLLIN), + FLAG_INFO_ENTRY(POLLOUT), + FLAG_INFO_ENTRY(POLLRDBAND), + FLAG_INFO_ENTRY(POLLWRBAND), + FLAG_INFO_ENTRY(POLLPRI), + + FLAG_INFO_ENTRY(POLLERR), + FLAG_INFO_ENTRY(POLLHUP), + FLAG_INFO_ENTRY(POLLNVAL), + + { 0, NULL } +}; + + +static FlagsTypeHandler::FlagsList kPollFlags; +static FlagsTypeHandler sPollFlagsHandler(kPollFlags); + + +// #pragma mark - specialized type handlers + + +static string +read_fdset(Context &context, void *data) +{ + // default FD_SETSIZE is 1024 + unsigned long tmp[1024 / (sizeof(unsigned long) * 8)]; + int32 bytesRead; + + status_t err = context.Reader().Read(data, &tmp, sizeof(tmp), bytesRead); + if (err != B_OK) + return context.FormatPointer(data); + + /* implicitly align to unsigned long lower boundary */ + int count = bytesRead / sizeof(unsigned long); + int added = 0; + + string r; + r.reserve(16); + + r = "["; + + for (int i = 0; i < count && added < 8; i++) { + for (int j = 0; + j < (int)(sizeof(unsigned long) * 8) && added < 8; j++) { + if (tmp[i] & (1UL << j)) { + if (added > 0) + r += " "; + unsigned int fd = i * sizeof(unsigned long) * 8 + j; + r += context.FormatUnsigned(fd); + added++; + } + } + } + + if (added >= 8) + r += " ..."; + + r += "]"; + + return r; +} + + +template<> +string +TypeHandlerImpl::GetParameterValue(Context &context, Parameter *, + const void *address) +{ + void *data = *(void **)address; + if (data != NULL && context.GetContents(Context::SIMPLE_STRUCTS)) + return read_fdset(context, data); + return context.FormatPointer(data); +} + + +template<> +string +TypeHandlerImpl::GetReturnValue(Context &context, uint64 value) +{ + return context.FormatPointer((void *)value); +} + + +static string +read_pollfd(Context &context, void *data) +{ + nfds_t numfds = context.ReadValue(context.GetSibling(1)); + if ((int64)numfds <= 0) + return string(); + + pollfd tmp[numfds]; + int32 bytesRead; + + status_t err = context.Reader().Read(data, &tmp, sizeof(tmp), bytesRead); + if (err != B_OK) + return context.FormatPointer(data); + + string r; + r.reserve(16); + + r = "["; + + int added = 0; + for (nfds_t i = 0; i < numfds && added < 8; i++) { + if ((tmp[i].fd == -1 || tmp[i].revents == 0) + && context.GetContents(Context::OUTPUT_VALUES)) { + continue; + } + if (added > 0) + r += ", "; + r += "{fd=" + context.FormatSigned(tmp[i].fd); + if (tmp[i].fd != -1 && context.GetContents(Context::INPUT_VALUES)) { + r += ", events="; + r += sPollFlagsHandler.RenderValue(context, tmp[i].events); + } + if (context.GetContents(Context::OUTPUT_VALUES)) { + r += ", revents="; + r += sPollFlagsHandler.RenderValue(context, tmp[i].revents); + } + added++; + r += "}"; + } + + if (added >= 8) + r += " ..."; + + r += "]"; + return r; +} + + +template<> +string +TypeHandlerImpl::GetParameterValue(Context &context, Parameter *, + const void *address) +{ + void *data = *(void **)address; + if (data != NULL && context.GetContents(Context::SIMPLE_STRUCTS)) + return read_pollfd(context, data); + return context.FormatPointer(data); +} + + +template<> +string +TypeHandlerImpl::GetReturnValue(Context &context, uint64 value) +{ + return context.FormatPointer((void *)value); +} + + +DEFINE_TYPE(fdset_ptr, fd_set *) +DEFINE_TYPE(pollfd_ptr, pollfd *) + + +// #pragma mark - patch function + + +void +patch_events() +{ + for (int i = 0; kPollFlagInfos[i].name != NULL; i++) + kPollFlags.push_back(kPollFlagInfos[i]); + + Syscall *poll = get_syscall("_kern_poll"); + poll->ParameterAt(0)->SetInOut(true); + + Syscall *select = get_syscall("_kern_select"); + select->ParameterAt(1)->SetInOut(true); + select->ParameterAt(2)->SetInOut(true); + select->ParameterAt(3)->SetInOut(true); + + Syscall *wait = get_syscall("_kern_wait_for_child"); + wait->ParameterAt(2)->SetOut(true); + wait->ParameterAt(3)->SetOut(true); +} diff --git a/src/bin/debug/strace/network.cpp b/src/bin/debug/strace/network.cpp index 33eaad89ea..80022189f7 100644 --- a/src/bin/debug/strace/network.cpp +++ b/src/bin/debug/strace/network.cpp @@ -124,18 +124,6 @@ patch_network() shutdown->GetParameter("how")->SetHandler( new EnumTypeHandler(kShutdownHowMap)); - Syscall *poll = get_syscall("_kern_poll"); - poll->ParameterAt(0)->SetInOut(true); - - Syscall *select = get_syscall("_kern_select"); - select->ParameterAt(1)->SetInOut(true); - select->ParameterAt(2)->SetInOut(true); - select->ParameterAt(3)->SetInOut(true); - - Syscall *wait = get_syscall("_kern_wait_for_child"); - wait->ParameterAt(2)->SetOut(true); - wait->ParameterAt(3)->SetOut(true); - Syscall *createPipe = get_syscall("_kern_create_pipe"); createPipe->ParameterAt(0)->SetOut(true); createPipe->ParameterAt(0)->SetCount(2); @@ -147,5 +135,4 @@ patch_network() new EnumTypeHandler(kSocketFamilyMap)); socketPair->GetParameter("type")->SetHandler( new EnumTypeHandler(kSocketTypeMap)); - } diff --git a/src/bin/debug/strace/strace.cpp b/src/bin/debug/strace/strace.cpp index 9f66509475..1c5ac6b440 100644 --- a/src/bin/debug/strace/strace.cpp +++ b/src/bin/debug/strace/strace.cpp @@ -230,6 +230,7 @@ patch_syscalls() // kernel/syscalls.h and have it parsed automatically extern void patch_area(); + extern void patch_events(); extern void patch_exec(); extern void patch_fcntl(); extern void patch_ioctl(); @@ -248,6 +249,7 @@ patch_syscalls() } patch_area(); + patch_events(); patch_exec(); patch_fcntl(); patch_ioctl();