strace: Move poll/select syscall handling to an "event" file.

Also bring along the type handlers, and use FlagsTypeHandler.
This commit is contained in:
Augustin Cavalier
2024-07-16 18:43:50 -04:00
parent ef62eb6117
commit 96fb940571
6 changed files with 219 additions and 207 deletions
+1
View File
@@ -21,6 +21,7 @@ local straceSources =
MemoryReader.cpp
area.cpp
events.cpp
exec.cpp
fcntl.cpp
ioctl.cpp
-192
View File
@@ -101,68 +101,6 @@ TypeHandlerImpl<iovec *>::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<fd_set *>::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<fd_set *>::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<nfds_t>(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<pollfd *>::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<pollfd *>::GetReturnValue(Context &context, uint64 value)
{
return context.FormatPointer((void *)value);
}
template<typename Type>
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<type>(); \
}
#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
+7 -2
View File
@@ -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<const char*> {
} \
} \
#define DEFINE_TYPE(name, type) \
TypeHandler *create_##name##_type_handler() \
{ \
return new TypeHandlerImpl<type>(); \
}
struct fd_set;
struct flock;
struct ifconf;
+209
View File
@@ -0,0 +1,209 @@
/*
* Copyright 2023-2024, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <OS.h>
#include <poll.h>
#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<fd_set *>::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<fd_set *>::GetReturnValue(Context &context, uint64 value)
{
return context.FormatPointer((void *)value);
}
static string
read_pollfd(Context &context, void *data)
{
nfds_t numfds = context.ReadValue<nfds_t>(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<pollfd *>::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<pollfd *>::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);
}
-13
View File
@@ -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));
}
+2
View File
@@ -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();