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:
parent
68d1b97e4f
commit
1d2cf139a8
@ -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
|
||||
;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 *);
|
||||
|
61
src/bin/debug/strace/fcntl.cpp
Normal file
61
src/bin/debug/strace/fcntl.cpp
Normal 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()));
|
||||
}
|
||||
|
@ -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 =
|
||||
|
Loading…
Reference in New Issue
Block a user