From 566ad3edd81f8956e429fc8b933bf23950cc8fb7 Mon Sep 17 00:00:00 2001 From: DH Date: Wed, 3 Dec 2025 21:06:11 +0300 Subject: [PATCH] orbis: improve fd tracing --- kernel/orbis/include/orbis/IoDevice.hpp | 8 +++++ kernel/orbis/include/orbis/file.hpp | 34 ++++++++++---------- kernel/orbis/include/orbis/thread/sysent.hpp | 2 +- kernel/orbis/src/IoDevice.cpp | 9 ++++-- kernel/orbis/src/sysvec.cpp | 27 ++++++++++++++-- rpcsx/io-device.cpp | 18 +++++++++++ rpcsx/iodev/aout.cpp | 5 +++ rpcsx/iodev/blockpool.cpp | 2 ++ rpcsx/iodev/dmem.cpp | 7 +++- rpcsx/main.cpp | 22 ++++++------- 10 files changed, 100 insertions(+), 34 deletions(-) diff --git a/kernel/orbis/include/orbis/IoDevice.hpp b/kernel/orbis/include/orbis/IoDevice.hpp index b2571f3f9..e02e22644 100644 --- a/kernel/orbis/include/orbis/IoDevice.hpp +++ b/kernel/orbis/include/orbis/IoDevice.hpp @@ -76,6 +76,8 @@ struct IoDevice : rx::RcBase { virtual ErrorCode map(rx::AddressRange range, std::int64_t offset, rx::EnumBitSet protection, File *file, Process *process); + + [[nodiscard]] virtual std::string toString() const; }; namespace ioctl { @@ -95,6 +97,8 @@ constexpr std::uint32_t paramSize(std::uint32_t cmd) { } constexpr std::uint32_t group(std::uint32_t cmd) { return (cmd >> 8) & 0xff; } constexpr std::uint32_t id(std::uint32_t cmd) { return cmd & 0xff; } + +std::string groupToString(unsigned iocGroup); } // namespace ioctl struct IoctlHandlerEntry; @@ -201,5 +205,9 @@ template struct IoDeviceWithIoctl : IoDevice { return ioctlTable[id].handler(thread, argp, this, ioctlTable[id].impl); } + + [[nodiscard]] std::string toString() const override { + return ioctl::groupToString(Group) + " " + IoDevice::toString(); + } }; } // namespace orbis diff --git a/kernel/orbis/include/orbis/file.hpp b/kernel/orbis/include/orbis/file.hpp index a6639bb13..75953a8e7 100644 --- a/kernel/orbis/include/orbis/file.hpp +++ b/kernel/orbis/include/orbis/file.hpp @@ -43,32 +43,32 @@ struct FileOps { // TODO: chown // TODO: chmod - ErrorCode (*bind)(orbis::File *file, SocketAddress *address, - std::size_t addressLen, Thread *thread) = nullptr; - ErrorCode (*listen)(orbis::File *file, int backlog, Thread *thread) = nullptr; - ErrorCode (*accept)(orbis::File *file, SocketAddress *address, + ErrorCode (*bind)(File *file, SocketAddress *address, std::size_t addressLen, + Thread *thread) = nullptr; + ErrorCode (*listen)(File *file, int backlog, Thread *thread) = nullptr; + ErrorCode (*accept)(File *file, SocketAddress *address, std::uint32_t *addressLen, Thread *thread) = nullptr; - ErrorCode (*connect)(orbis::File *file, SocketAddress *address, + ErrorCode (*connect)(File *file, SocketAddress *address, std::uint32_t addressLen, Thread *thread) = nullptr; - ErrorCode (*sendto)(orbis::File *file, const void *buf, size_t len, - sint flags, caddr_t to, sint tolen, - Thread *thread) = nullptr; - ErrorCode (*sendmsg)(orbis::File *file, msghdr *msg, sint flags, + ErrorCode (*sendto)(File *file, const void *buf, size_t len, sint flags, + caddr_t to, sint tolen, Thread *thread) = nullptr; + ErrorCode (*sendmsg)(File *file, msghdr *msg, sint flags, Thread *thread) = nullptr; - ErrorCode (*recvfrom)(orbis::File *file, void *buf, size_t len, sint flags, + ErrorCode (*recvfrom)(File *file, void *buf, size_t len, sint flags, SocketAddress *from, uint32_t *fromlenaddr, Thread *thread) = nullptr; - ErrorCode (*recvmsg)(orbis::File *file, msghdr *msg, sint flags, + ErrorCode (*recvmsg)(File *file, msghdr *msg, sint flags, Thread *thread) = nullptr; - ErrorCode (*shutdown)(orbis::File *file, sint how, Thread *thread) = nullptr; - ErrorCode (*setsockopt)(orbis::File *file, sint level, sint name, - const void *val, sint valsize, - Thread *thread) = nullptr; - ErrorCode (*getsockopt)(orbis::File *file, sint level, sint name, void *val, + ErrorCode (*shutdown)(File *file, sint how, Thread *thread) = nullptr; + ErrorCode (*setsockopt)(File *file, sint level, sint name, const void *val, + sint valsize, Thread *thread) = nullptr; + ErrorCode (*getsockopt)(File *file, sint level, sint name, void *val, sint *avalsize, Thread *thread) = nullptr; - ErrorCode (*sendfile)(orbis::File *file, sint fd, off_t offset, size_t nbytes, + ErrorCode (*sendfile)(File *file, sint fd, off_t offset, size_t nbytes, ptr hdtr, ptr sbytes, sint flags, Thread *thread) = nullptr; + + std::string (*toString)(File *file, Thread *thread); }; struct File : rx::RcBase { diff --git a/kernel/orbis/include/orbis/thread/sysent.hpp b/kernel/orbis/include/orbis/thread/sysent.hpp index 719f45c70..80753ad66 100644 --- a/kernel/orbis/include/orbis/thread/sysent.hpp +++ b/kernel/orbis/include/orbis/thread/sysent.hpp @@ -10,7 +10,7 @@ using sy_call_t = SysResult(Thread *, uint64_t *); struct sysent { sint narg; sy_call_t *call; - std::string (*format)(uint64_t *); + std::string (*format)(Thread *, uint64_t *); }; struct sysentvec { diff --git a/kernel/orbis/src/IoDevice.cpp b/kernel/orbis/src/IoDevice.cpp index bd0dfecd1..875a915c1 100644 --- a/kernel/orbis/src/IoDevice.cpp +++ b/kernel/orbis/src/IoDevice.cpp @@ -1,11 +1,12 @@ #include "IoDevice.hpp" #include "file.hpp" #include "rx/Mappable.hpp" +#include "rx/format-base.hpp" #include "thread/Thread.hpp" #include "utils/Logs.hpp" #include "vmem.hpp" -static std::string iocGroupToString(unsigned iocGroup) { +std::string orbis::ioctl::groupToString(unsigned iocGroup) { if (iocGroup >= 128) { const char *sceGroups[] = { "DEV", @@ -86,10 +87,14 @@ orbis::IoDevice::map(rx::AddressRange range, std::int64_t offset, orbis::ErrorCode orbis::IoDevice::ioctl(std::uint64_t request, orbis::ptr argp, Thread *thread) { - auto group = iocGroupToString(ioctl::group(request)); + auto group = ioctl::groupToString(ioctl::group(request)); auto paramSize = ioctl::paramSize(request); ORBIS_LOG_ERROR("unhandled ioctl", request, group, paramSize, argp, thread->tid); thread->where(); return ErrorCode::NOTSUP; } + +std::string orbis::IoDevice::toString() const { + return rx::format("{}", static_cast(this)); +} diff --git a/kernel/orbis/src/sysvec.cpp b/kernel/orbis/src/sysvec.cpp index c000ae180..aae20789d 100644 --- a/kernel/orbis/src/sysvec.cpp +++ b/kernel/orbis/src/sysvec.cpp @@ -106,7 +106,7 @@ struct WrapImpl { sysent result; result.narg = sizeof...(Args); result.call = &WrapImpl::call; - result.format = [](uint64_t *values) -> std::string { + result.format = [](Thread *thread, uint64_t *values) -> std::string { std::string result = getSysentName(&WrapImpl::call); result += "("; @@ -134,7 +134,9 @@ struct WrapImpl { } else if constexpr (std::is_pointer_v) { result += rx::format("{}", (void *)value); - // using pointee = std::remove_cvref_t>; + // using pointee = + // std::remove_cvref_t>; + // // if constexpr (requires(rx::format_parse_context &ctx) { // rx::formatter().parse(ctx); // }) { @@ -149,6 +151,27 @@ struct WrapImpl { // } // } // } + } else if constexpr (std::is_same_v) { + result += rx::format("{}", std::to_underlying(value)); + if (std::to_underlying(value) >= 0) { + auto file = thread->tproc->fileDescriptors.get(value); + result += " ("; + + if (file) { + if (file->ops && file->ops->toString) { + result += file->ops->toString(file.get(), thread); + } else if (file->device) { + result += file->device->toString(); + } else { + result += ""; + } + + } else { + result += ""; + } + + result += ")"; + } } else if constexpr (requires(rx::format_parse_context &ctx) { rx::formatter().parse(ctx); }) { diff --git a/rpcsx/io-device.cpp b/rpcsx/io-device.cpp index a9b389fec..655381947 100644 --- a/rpcsx/io-device.cpp +++ b/rpcsx/io-device.cpp @@ -10,6 +10,7 @@ #include "orbis/utils/Logs.hpp" #include "orbis/vmem.hpp" #include "rx/Mappable.hpp" +#include "rx/format-base.hpp" #include "vfs.hpp" #include #include @@ -33,6 +34,7 @@ struct HostFile : orbis::File { bool closeOnExit = true; bool alignTruncate = false; + orbis::kstring path; ~HostFile() { if (!closeOnExit && hostFd) { @@ -611,11 +613,26 @@ orbis::ErrorCode socket_recvfrom(orbis::File *file, void *buf, return orbis::ErrorCode::NOTSUP; } +static std::string host_toString(orbis::File *file, orbis::Thread *thread) { + auto hostFile = static_cast(file); + + if (!hostFile->path.empty()) { + std::string result; + result += '"'; + result += hostFile->path; + result += '"'; + return result; + } + + return rx::format("host fd {}", hostFile->hostFd.native_handle()); +} + static const orbis::FileOps hostOps = { .read = host_read, .write = host_write, .truncate = host_truncate, .stat = host_stat, + .toString = host_toString, }; static const orbis::FileOps socketOps = { @@ -828,6 +845,7 @@ orbis::ErrorCode HostFsDevice::open(rx::Ref *file, newFile->dirEntries = std::move(dirEntries); newFile->ops = &hostOps; newFile->device = this; + newFile->path = path; *file = newFile; return {}; } diff --git a/rpcsx/iodev/aout.cpp b/rpcsx/iodev/aout.cpp index d1a5a7611..03f3936fa 100644 --- a/rpcsx/iodev/aout.cpp +++ b/rpcsx/iodev/aout.cpp @@ -9,6 +9,7 @@ #include "orbis/utils/Logs.hpp" #include "rx/Rc.hpp" #include +#include // #include #define SNDCTL_DSP_RESET 0x20005000 @@ -37,6 +38,10 @@ struct AoutDevice : public orbis::IoDevice { orbis::ErrorCode open(rx::Ref *file, const char *path, std::uint32_t flags, std::uint32_t mode, orbis::Thread *thread) override; + + [[nodiscard]] std::string toString() const override { + return "aout" + std::to_string(id); + } }; static orbis::ErrorCode aout_ioctl(orbis::File *file, std::uint64_t request, diff --git a/rpcsx/iodev/blockpool.cpp b/rpcsx/iodev/blockpool.cpp index 974ff463f..c5424c5ed 100644 --- a/rpcsx/iodev/blockpool.cpp +++ b/rpcsx/iodev/blockpool.cpp @@ -51,6 +51,8 @@ struct BlockPoolDevice orbis::ErrorCode map(rx::AddressRange range, std::int64_t offset, rx::EnumBitSet protection, orbis::File *file, orbis::Process *process) override; + + [[nodiscard]] std::string toString() const override { return "blockpool"; } }; #pragma pack(push, 1) diff --git a/rpcsx/iodev/dmem.cpp b/rpcsx/iodev/dmem.cpp index 7460e3a98..d4978f211 100644 --- a/rpcsx/iodev/dmem.cpp +++ b/rpcsx/iodev/dmem.cpp @@ -9,9 +9,10 @@ #include "orbis/thread/Thread.hpp" #include "orbis/utils/Logs.hpp" #include "orbis/vmem.hpp" -#include "rx/format.hpp" #include "rx/AddressRange.hpp" #include "rx/EnumBitSet.hpp" +#include "rx/format.hpp" +#include enum { DMEM_IOCTL_ALLOCATE = 0xc0288001, @@ -42,6 +43,10 @@ struct DmemDevice orbis::ErrorCode map(rx::AddressRange range, std::int64_t offset, rx::EnumBitSet protection, orbis::File *file, orbis::Process *process) override; + + [[nodiscard]] std::string toString() const override { + return "dmem" + std::to_string(index); + } }; struct DmemFile : public orbis::File {}; diff --git a/rpcsx/main.cpp b/rpcsx/main.cpp index 4e3a17aa3..017b2a6fe 100644 --- a/rpcsx/main.cpp +++ b/rpcsx/main.cpp @@ -15,6 +15,7 @@ #include "orbis/utils/Logs.hpp" #include "orbis/vmem.hpp" #include "rx/Config.hpp" +#include "rx/FileLock.hpp" #include "rx/die.hpp" #include "rx/format.hpp" #include "rx/mem.hpp" @@ -299,26 +300,26 @@ static void onSysEnter(orbis::Thread *thread, int id, uint64_t *args, if (!g_traceSyscalls) { return; } - flockfile(stderr); - std::fprintf(stderr, " [%u] ", thread->tid); + + rx::ScopedFileLock lock(stderr); + rx::print(stderr, " [{}] ", thread->tid); if (auto ent = getSyscallEnt(thread, id)) { - std::fprintf(stderr, "%s\n", ent->format(args).c_str()); + rx::println(stderr, "{}", ent->format(thread, args).c_str()); return; } - std::fprintf(stderr, "sys_%u(", id); + rx::print(stderr, "sys_{}(", id); for (int i = 0; i < argsCount; ++i) { if (i != 0) { - std::fprintf(stderr, ", "); + rx::print(stderr, ", "); } - std::fprintf(stderr, "%#lx", args[i]); + rx::print(stderr, "{:#x}", args[i]); } - std::fprintf(stderr, ")\n"); - funlockfile(stderr); + rx::println(stderr, ")"); } static void onSysExit(orbis::Thread *thread, int id, uint64_t *args, @@ -327,11 +328,11 @@ static void onSysExit(orbis::Thread *thread, int id, uint64_t *args, return; } - flockfile(stderr); + rx::ScopedFileLock lock(stderr); rx::print(stderr, "{}: [{}] ", result.isError() ? 'E' : 'S', thread->tid); if (auto ent = getSyscallEnt(thread, id)) { - rx::print(stderr, "{}", ent->format(args)); + rx::print(stderr, "{}", ent->format(thread, args)); } else { rx::print(stderr, "sys_{}(", id); @@ -352,7 +353,6 @@ static void onSysExit(orbis::Thread *thread, int id, uint64_t *args, if (result.isError()) { thread->where(); } - funlockfile(stderr); } static void guestInitDev(orbis::Thread *thread, int stdinFd, int stdoutFd,