strace: trace fcntl and wait_for_child syscalls parameters

Change-Id: I774e8343139a2bdb3c2f60f37cab3a7207739c7c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5251
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
Jérôme Duval 2022-04-26 14:50:17 +02:00
parent 68d1b97e4f
commit 1d2cf139a8
6 changed files with 154 additions and 3 deletions

View File

@ -13,7 +13,7 @@ SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ;
SubDirHdrs $(TARGET_COMMON_DEBUG_LOCATE_TARGET) ;
local straceSources =
Context.cpp ioctl.cpp MemoryReader.cpp NetworkTypes.cpp
Context.cpp fcntl.cpp ioctl.cpp MemoryReader.cpp NetworkTypes.cpp
strace.cpp TypeHandler.cpp
;

View File

@ -8,6 +8,7 @@
*/
#include <arpa/inet.h>
#include <signal.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <netinet/in.h>
@ -111,6 +112,62 @@ TypeHandlerImpl<fd_set *>::GetReturnValue(Context &context, uint64 value)
}
static string
format_ltype(Context &context, int ltype)
{
if (context.GetContents(Context::ENUMERATIONS)) {
#define LTYPE(type) \
case type: \
return #type
switch (ltype) {
LTYPE(F_RDLCK);
LTYPE(F_UNLCK);
LTYPE(F_WRLCK);
}
}
return context.FormatSigned(ltype);
}
static string
format_lwhence(Context &context, int lwhence)
{
if (context.GetContents(Context::ENUMERATIONS)) {
#define LWHENCE(whence) \
case whence: \
return #whence
switch (lwhence) {
LWHENCE(SEEK_SET);
LWHENCE(SEEK_CUR);
LWHENCE(SEEK_END);
LWHENCE(SEEK_DATA);
LWHENCE(SEEK_HOLE);
}
}
return context.FormatSigned(lwhence);
}
static string
format_pointer(Context &context, flock *lock)
{
string r;
r = "l_type=" + format_ltype(context, lock->l_type) + ", ";
r += "l_whence=" + format_lwhence(context, lock->l_whence) + ", ";
r += "l_start=" + context.FormatSigned(lock->l_start) + ", ";
r += "l_len=" + context.FormatSigned(lock->l_len);
return r;
}
template<typename value_t>
static inline value_t
get_value(const void *address)
@ -606,6 +663,21 @@ format_pointer(Context &context, ifconf *conf)
}
static string
format_pointer(Context &context, siginfo_t *info)
{
string r;
switch (info->si_code) {
case CLD_EXITED:
r = "WIFEXITED(s) && WEXITSTATUS(s) == " + context.FormatUnsigned(info->si_status & 0xff);
break;
}
return r;
}
template<typename Type>
class SpecializedPointerTypeHandler : public TypeHandler {
string GetParameterValue(Context &context, Parameter *,
@ -633,9 +705,11 @@ class SpecializedPointerTypeHandler : public TypeHandler {
}
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);
#if 0
POINTER_TYPE(message_args_ptr, message_args);
POINTER_TYPE(msghdr_ptr, msghdr);

View File

@ -42,7 +42,9 @@ public:
Parameter(string name, int32 offset, string typeName, TypeHandler *handler)
: Type(typeName, handler),
fName(name),
fOffset(offset)
fOffset(offset),
fInOut(false),
fOut(false)
{
}
@ -50,11 +52,14 @@ public:
int32 Offset() const { return fOffset; }
bool InOut() const { return fInOut; }
void SetInOut(bool inout) { fInOut = inout; }
bool Out() const { return fOut; }
void SetOut(bool out) { fOut = out; }
private:
string fName;
int32 fOffset;
bool fInOut;
bool fOut;
};
// Syscall

View File

@ -98,6 +98,7 @@ struct TypeHandlerFactory<const char*> {
} \
struct fd_set;
struct flock;
struct ifconf;
struct ifreq;
struct message_args;
@ -107,10 +108,12 @@ struct socket_args;
struct sockopt_args;
DEFINE_FACTORY(fdset_ptr, fd_set *);
DEFINE_FACTORY(flock_ptr, flock *);
DEFINE_FACTORY(ifconf_ptr, ifconf *);
DEFINE_FACTORY(ifreq_ptr, ifreq *);
DEFINE_FACTORY(message_args_ptr, message_args *);
DEFINE_FACTORY(pollfd_ptr, pollfd *);
DEFINE_FACTORY(siginfo_t_ptr, siginfo_t *);
DEFINE_FACTORY(sockaddr_args_ptr, sockaddr_args *);
DEFINE_FACTORY(socket_args_ptr, socket_args *);
DEFINE_FACTORY(sockopt_args_ptr, sockopt_args *);

View File

@ -0,0 +1,61 @@
/*
* Copyright 2022, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Copyright 2022, Jérôme Duval, jerome.duval@gmail.com
*/
#include <fcntl.h>
#include "strace.h"
#include "Syscall.h"
#include "TypeHandler.h"
struct fcntl_info {
unsigned int index;
const char *name;
TypeHandler *handler;
};
#define FCNTL_INFO_ENTRY(name) \
{ name, #name, NULL }
#define FCNTL_INFO_ENTRY_TYPE(name, type) \
{ name, #name, TypeHandlerFactory<type>::Create() }
static const fcntl_info kFcntls[] = {
FCNTL_INFO_ENTRY_TYPE(F_DUPFD, int),
FCNTL_INFO_ENTRY(F_GETFD),
FCNTL_INFO_ENTRY_TYPE(F_SETFD, int),
FCNTL_INFO_ENTRY(F_GETFL),
FCNTL_INFO_ENTRY_TYPE(F_SETFL, int),
FCNTL_INFO_ENTRY_TYPE(F_GETLK, struct flock*),
FCNTL_INFO_ENTRY_TYPE(F_SETLK, struct flock*),
FCNTL_INFO_ENTRY_TYPE(F_SETLKW, struct flock*),
{ 0, NULL, NULL }
};
static EnumTypeHandler::EnumMap kFcntlNames;
static TypeHandlerSelector::SelectMap kFcntlTypeHandlers;
void
patch_fcntl()
{
for (int i = 0; kFcntls[i].name != NULL; i++) {
kFcntlNames[kFcntls[i].index] = kFcntls[i].name;
if (kFcntls[i].handler != NULL)
kFcntlTypeHandlers[kFcntls[i].index] = kFcntls[i].handler;
}
Syscall *fcntl = get_syscall("_kern_fcntl");
fcntl->GetParameter("op")->SetHandler(
new EnumTypeHandler(kFcntlNames));
fcntl->GetParameter("argument")->SetHandler(
new TypeHandlerSelector(kFcntlTypeHandlers,
1, TypeHandlerFactory<void *>::Create()));
}

View File

@ -260,8 +260,10 @@ patch_syscalls()
// instead of having this done here manually we should either add the
// patching step to gensyscalls also manually or add metadata to
// kernel/syscalls.h and have it parsed automatically
extern void patch_fcntl();
extern void patch_ioctl();
patch_fcntl();
patch_ioctl();
Syscall *poll = get_syscall("_kern_poll");
@ -271,6 +273,10 @@ patch_syscalls()
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);
}
@ -379,6 +385,8 @@ print_syscall(FILE *outputFile, Syscall* syscall, debug_pre_syscall &message,
for (int32 i = 0; i < count; i++) {
// get the value
Parameter *parameter = syscall->ParameterAt(i);
if (parameter->Out())
continue;
TypeHandler *handler = parameter->Handler();
::string value =
handler->GetParameterValue(ctx, parameter,
@ -455,7 +463,7 @@ print_syscall(FILE *outputFile, Syscall* syscall, debug_post_syscall &message,
for (int32 i = 0; i < count; i++) {
// get the value
Parameter *parameter = syscall->ParameterAt(i);
if (!parameter->InOut())
if (!parameter->InOut() && !parameter->Out())
continue;
TypeHandler *handler = parameter->Handler();
::string value =