diff --git a/src/bin/debug/strace/Jamfile b/src/bin/debug/strace/Jamfile index f32b00bf73..d5d37a1ee7 100644 --- a/src/bin/debug/strace/Jamfile +++ b/src/bin/debug/strace/Jamfile @@ -27,6 +27,7 @@ local straceSources = ioctl.cpp mutex.cpp network.cpp + rlimit.cpp signals.cpp ; diff --git a/src/bin/debug/strace/TypeHandler.h b/src/bin/debug/strace/TypeHandler.h index 3119792bf2..bcf6016d44 100644 --- a/src/bin/debug/strace/TypeHandler.h +++ b/src/bin/debug/strace/TypeHandler.h @@ -150,6 +150,8 @@ struct pollfd; struct object_wait_info; struct event_wait_info; +struct rlimit; + DEFINE_FACTORY(flock_ptr, flock *); DEFINE_FACTORY(ifconf_ptr, ifconf *); DEFINE_FACTORY(ifreq_ptr, ifreq *); @@ -164,6 +166,9 @@ DEFINE_FACTORY(sockaddr_args_ptr, sockaddr_args *); DEFINE_FACTORY(socket_args_ptr, socket_args *); DEFINE_FACTORY(sockopt_args_ptr, sockopt_args *); +DEFINE_FACTORY(rlimit_ptr, rlimit *); +DEFINE_FACTORY(rlimit_ptr, const rlimit *); + DEFINE_FACTORY(fdset_ptr, fd_set *); DEFINE_FACTORY(pollfd_ptr, pollfd *); DEFINE_FACTORY(object_wait_infos_ptr, object_wait_info *); diff --git a/src/bin/debug/strace/rlimit.cpp b/src/bin/debug/strace/rlimit.cpp new file mode 100644 index 0000000000..fbffb8fdc2 --- /dev/null +++ b/src/bin/debug/strace/rlimit.cpp @@ -0,0 +1,128 @@ +/* + * Copyright 2025, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Copyright 2025, Jérôme Duval, jerome.duval@gmail.com + */ + + +#include + +#include "strace.h" +#include "Syscall.h" +#include "Context.h" +#include "MemoryReader.h" +#include "TypeHandler.h" + + + +static EnumTypeHandler::EnumMap kResourceNames; + +struct enum_info { + unsigned int index; + const char *name; +}; + +#define ENUM_INFO_ENTRY(name) \ + { name, #name } + +static const enum_info kResources[] = { + ENUM_INFO_ENTRY(RLIMIT_CORE), + ENUM_INFO_ENTRY(RLIMIT_CPU), + ENUM_INFO_ENTRY(RLIMIT_DATA), + ENUM_INFO_ENTRY(RLIMIT_FSIZE), + ENUM_INFO_ENTRY(RLIMIT_NOFILE), + ENUM_INFO_ENTRY(RLIMIT_STACK), + ENUM_INFO_ENTRY(RLIMIT_AS), + ENUM_INFO_ENTRY(RLIMIT_NOVMON), + + { 0, NULL } +}; + +static EnumTypeHandler::EnumMap kResourcesMap; + + +static string +format_number(rlim_t value) +{ + char tmp[32]; + if (value == RLIM_INFINITY) { + strlcpy(tmp, "RLIM_INFINITY", sizeof(tmp)); + } else if ((value % 1024) == 0) { + snprintf(tmp, sizeof(tmp), "%lu*1024", value / 1024); + } else { + snprintf(tmp, sizeof(tmp), "%lu", value); + } + return tmp; +} + + +static string +format_pointer(Context &context, struct rlimit *addr) +{ + string r; + + r += "rlim_cur=" + format_number(addr->rlim_cur) + ", "; + r += "rlim_max=" + format_number(addr->rlim_max); + + return r; +} + +static string +read_rlimit(Context &context, Parameter *param, void *address) +{ + struct rlimit data; + + if (param->Out()) { + int status = context.GetReturnValue(); + if (status < 0) + return string(); + } + + int32 bytesRead; + status_t err = context.Reader().Read(address, &data, sizeof(struct rlimit), bytesRead); + if (err != B_OK) + return context.FormatPointer(address); + + return "{" + format_pointer(context, &data) + "}"; +} + + +template<> +string +TypeHandlerImpl::GetParameterValue(Context &context, Parameter *param, + const void *address) +{ + void *data = *(void **)address; + if (data != NULL && context.GetContents(Context::SIMPLE_STRUCTS)) + return read_rlimit(context, param, data); + return context.FormatPointer(data); +} + + +template<> +string +TypeHandlerImpl::GetReturnValue(Context &context, uint64 value) +{ + return context.FormatPointer((void *)value); +} + + +DEFINE_TYPE(rlimit_ptr, rlimit *) + + +void +patch_rlimit() +{ + for (int i = 0; kResources[i].name != NULL; i++) { + kResourcesMap[kResources[i].index] = kResources[i].name; + } + + Syscall *getrlimit = get_syscall("_kern_getrlimit"); + getrlimit->GetParameter("resource")->SetHandler(new EnumTypeHandler(kResourcesMap)); + getrlimit->ParameterAt(1)->SetOut(true); + Syscall *setrlimit = get_syscall("_kern_setrlimit"); + setrlimit->GetParameter("resource")->SetHandler(new EnumTypeHandler(kResourcesMap)); +} + diff --git a/src/bin/debug/strace/strace.cpp b/src/bin/debug/strace/strace.cpp index 8df9c9c4f9..cf4fed58de 100644 --- a/src/bin/debug/strace/strace.cpp +++ b/src/bin/debug/strace/strace.cpp @@ -236,6 +236,7 @@ patch_syscalls() extern void patch_ioctl(); extern void patch_mutex(); extern void patch_network(); + extern void patch_rlimit(); for (size_t i = 0; i < sSyscallVector.size(); i++) { Syscall *syscall = sSyscallVector[i]; @@ -255,6 +256,7 @@ patch_syscalls() patch_ioctl(); patch_mutex(); patch_network(); + patch_rlimit(); }