mirror of
https://review.haiku-os.org/haiku
synced 2025-02-23 05:58:31 +01:00
strace: Add tracing for rlimit syscalls.
Change-Id: I1e99622027f04fb93d00ebd94b45e05f7142fbec Reviewed-on: https://review.haiku-os.org/c/haiku/+/8965 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
3953c0e7cd
commit
46dd344bdd
@ -27,6 +27,7 @@ local straceSources =
|
||||
ioctl.cpp
|
||||
mutex.cpp
|
||||
network.cpp
|
||||
rlimit.cpp
|
||||
signals.cpp
|
||||
;
|
||||
|
||||
|
@ -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 *);
|
||||
|
128
src/bin/debug/strace/rlimit.cpp
Normal file
128
src/bin/debug/strace/rlimit.cpp
Normal file
@ -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 <sys/resource.h>
|
||||
|
||||
#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<struct rlimit *>::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<struct rlimit *>::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));
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user