Add setting to enable/disable logging, some cleanup

This commit is contained in:
XorTroll 2020-06-21 14:03:13 +02:00
parent 69658dc72f
commit 3b60e0ad3d
7 changed files with 62 additions and 52 deletions

View File

@ -32,6 +32,10 @@
; NOTE: EXPERIMENTAL ; NOTE: EXPERIMENTAL
; If you do not know what you are doing, do not touch this yet. ; If you do not know what you are doing, do not touch this yet.
; fsmitm_redirect_saves_to_sd = u8!0x0 ; fsmitm_redirect_saves_to_sd = u8!0x0
; Controls whether debug system/game logs should be saved on the SD card.
; 0 = Do not save, 1 = Save.
; If you do not know what you are doing, do not touch this yet.
; logmanager_save_debug_logs = u8!0x0
; Controls whether to enable the deprecated hid mitm ; Controls whether to enable the deprecated hid mitm
; to fix compatibility with old homebrew. ; to fix compatibility with old homebrew.
; 0 = Do not enable, 1 = Enable. ; 0 = Do not enable, 1 = Enable.

View File

@ -14,7 +14,7 @@
"filesystem_access": { "filesystem_access": {
"permissions": "0xFFFFFFFFFFFFFFFF" "permissions": "0xFFFFFFFFFFFFFFFF"
}, },
"service_access": [ "fsp-srv", "pm:info", "psc:m" ], "service_access": [ "fsp-srv", "pm:info", "psc:m", "set:sys" ],
"service_host": [ "lm" ], "service_host": [ "lm" ],
"kernel_capabilities": [ "kernel_capabilities": [
{ {

View File

@ -44,7 +44,7 @@ namespace ams::lm::impl {
std::snprintf(process_dir, sizeof(process_dir), "%s/0x%016lX", DebugLogDirectory, program_id); std::snprintf(process_dir, sizeof(process_dir), "%s/0x%016lX", DebugLogDirectory, program_id);
fs::CreateDirectory(process_dir); fs::CreateDirectory(process_dir);
/* Use current system tick as the binary log file's name. */ /* Use current system tick as the binary log's identifier / file name. */
const LogInfo info = { const LogInfo info = {
.log_id = os::GetSystemTick().GetInt64Value(), .log_id = os::GetSystemTick().GetInt64Value(),
.program_id = program_id, .program_id = program_id,
@ -52,13 +52,14 @@ namespace ams::lm::impl {
/* Generate binary log path. */ /* Generate binary log path. */
/* All current log packets will be written to the same file. */ /* All current log packets will be written to the same file. */
/* Binary log files might contain several packets, but they all must start with a head packet and end with a tail packet. */
char bin_log_path[FS_MAX_PATH] = {}; char bin_log_path[FS_MAX_PATH] = {};
std::snprintf(bin_log_path, sizeof(bin_log_path), "%s/0x%016lX.bin", process_dir, info.log_id); std::snprintf(bin_log_path, sizeof(bin_log_path), "%s/0x%016lX.bin", process_dir, info.log_id);
/* Ensure the file exists. */ /* Ensure the file exists. */
fs::CreateFile(bin_log_path, 0); fs::CreateFile(bin_log_path, 0);
/* Now, open the file. */ /* Open the file. */
fs::FileHandle bin_log_file; fs::FileHandle bin_log_file;
R_TRY(fs::OpenFile(&bin_log_file, bin_log_path, fs::OpenMode_Write | fs::OpenMode_AllowAppend)); R_TRY(fs::OpenFile(&bin_log_file, bin_log_path, fs::OpenMode_Write | fs::OpenMode_AllowAppend));
ON_SCOPE_EXIT { fs::CloseFile(bin_log_file); }; ON_SCOPE_EXIT { fs::CloseFile(bin_log_file); };

View File

@ -7,9 +7,9 @@ namespace ams::lm::impl {
constexpr const char DebugLogDirectory[] = "sdmc:/atmosphere/debug_logs"; constexpr const char DebugLogDirectory[] = "sdmc:/atmosphere/debug_logs";
enum LogPacketFlags : u8 { enum LogPacketFlags : u8 {
LogPacketFlags_Head = BIT(0), LogPacketFlags_Head = BIT(0), /* Head -> a packet list is being sent, with this packet being the initial one. */
LogPacketFlags_Tail = BIT(1), LogPacketFlags_Tail = BIT(1), /* Tail -> this is the final packet of the packet list. */
LogPacketFlags_LittleEndian = BIT(2), /* Is this used anywhere? */ LogPacketFlags_LittleEndian = BIT(2),
}; };
struct LogPacketHeader { struct LogPacketHeader {
@ -22,12 +22,10 @@ namespace ams::lm::impl {
u32 payload_size; u32 payload_size;
inline constexpr bool IsHead() const { inline constexpr bool IsHead() const {
/* Head -> a packet list is being sent, with this packet being the initial one. */
return this->flags & LogPacketFlags_Head; return this->flags & LogPacketFlags_Head;
} }
inline constexpr bool IsTail() const { inline constexpr bool IsTail() const {
/* Tail -> this is the final packet of the packet list. */
return this->flags & LogPacketFlags_Tail; return this->flags & LogPacketFlags_Tail;
} }
@ -35,7 +33,7 @@ namespace ams::lm::impl {
static_assert(sizeof(LogPacketHeader) == 0x18, "LogPacketHeader definition"); static_assert(sizeof(LogPacketHeader) == 0x18, "LogPacketHeader definition");
struct LogInfo { struct LogInfo {
s64 log_id; s64 log_id; /* This is the system tick value when the log was saved. */
u64 program_id; u64 program_id;
}; };
@ -69,14 +67,6 @@ namespace ams::lm::impl {
return sizeof(LogPacketHeader) + header->payload_size; return sizeof(LogPacketHeader) + header->payload_size;
} }
inline size_t GetPacketBufferSize() const {
if(this->buf == nullptr) {
return 0;
}
/* We also send the program ID in the buffer, so include sizeof(u64). */
return this->GetPacketSize() + sizeof(u64);
}
inline bool ValidatePacket() const { inline bool ValidatePacket() const {
if(this->buf == nullptr) { if(this->buf == nullptr) {
return false; return false;

View File

@ -1,8 +1,8 @@
#include "lm_service.hpp" #include "lm_service.hpp"
extern "C" { extern "C" {
extern u32 __start__; extern u32 __start__;
u32 __nx_applet_type = AppletType_None; u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1; u32 __nx_fs_num_sessions = 1;
@ -13,7 +13,6 @@ extern "C" {
void __libnx_initheap(void); void __libnx_initheap(void);
void __appInit(void); void __appInit(void);
void __appExit(void); void __appExit(void);
} }
namespace ams { namespace ams {
@ -22,7 +21,7 @@ namespace ams {
namespace result { namespace result {
/* Fatal is launched way later after we are launched, so disable this. */ /* Fatal is launched after we are launched, so disable this. */
bool CallFatalOnResultAssertion = false; bool CallFatalOnResultAssertion = false;
} }
@ -51,15 +50,19 @@ void __appInit(void) {
R_ABORT_UNLESS(pminfoInitialize()); R_ABORT_UNLESS(pminfoInitialize());
R_ABORT_UNLESS(fsInitialize()); R_ABORT_UNLESS(fsInitialize());
R_ABORT_UNLESS(pscmInitialize()); R_ABORT_UNLESS(pscmInitialize());
R_ABORT_UNLESS(setsysInitialize());
}); });
R_ABORT_UNLESS(fs::MountSdCard("sdmc")); R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
ams::CheckApiVersion(); ams::CheckApiVersion();
} }
void __appExit(void) { void __appExit(void) {
/* Cleanup services. */
fs::Unmount("sdmc"); fs::Unmount("sdmc");
/* Cleanup services. */
setsysExit();
pscmExit(); pscmExit();
fsExit(); fsExit();
pminfoExit(); pminfoExit();
@ -67,8 +70,7 @@ void __appExit(void) {
namespace { namespace {
/* TODO: these domain/domain object amounts work fine, but which ones does N's LogManager actually use? */ /* TODO: these domain/domain object amounts work fine, but which ones does N actually use? */
struct ServerOptions { struct ServerOptions {
static constexpr size_t PointerBufferSize = 0; static constexpr size_t PointerBufferSize = 0;
static constexpr size_t MaxDomains = 0x40; static constexpr size_t MaxDomains = 0x40;
@ -143,5 +145,6 @@ int main(int argc, char **argv) {
/* Loop forever, servicing our services. */ /* Loop forever, servicing our services. */
lm::StartAndLoopProcess(); lm::StartAndLoopProcess();
/* Cleanup */
return 0; return 0;
} }

View File

@ -2,38 +2,52 @@
namespace ams::lm { namespace ams::lm {
void Logger::WriteQueuedPackets() { namespace {
impl::WriteLogPackets(this->queued_packets);
bool SaveDebugLogs() {
/* Get whether we should actually save logs. */
u8 save_debug_logs = 0;
if (settings::fwdbg::GetSettingsItemValue(&save_debug_logs, sizeof(save_debug_logs), "atmosphere", "logmanager_save_debug_logs") != sizeof(save_debug_logs)) {
return false;
}
return save_debug_logs != 0;
}
} }
void Logger::Log(const sf::InAutoSelectBuffer &buf) { void Logger::Log(const sf::InAutoSelectBuffer &buf) {
impl::LogPacketBuffer log_packet_buf(this->program_id, buf.GetPointer(), buf.GetSize()); /* Don't log unless we should do it. */
if(SaveDebugLogs()) {
impl::LogPacketBuffer log_packet_buf(this->program_id, buf.GetPointer(), buf.GetSize());
/* Check if there's a queue already started. */ /* Check if there's a queue already started. */
const bool has_queued_packets = !this->queued_packets.empty(); const bool has_queued_packets = !this->queued_packets.empty();
if(log_packet_buf.IsHead() && log_packet_buf.IsTail()) { if(log_packet_buf.IsHead() && log_packet_buf.IsTail()) {
/* Single packet to be logged - ensure the queue is empty, push it alone on the queue and log it. */ /* Single packet to be logged - ensure the queue is empty, push it alone on the queue and log it. */
this->queued_packets.clear(); this->queued_packets.clear();
this->queued_packets.push_back(std::move(log_packet_buf)); this->queued_packets.push_back(std::move(log_packet_buf));
impl::WriteLogPackets(this->queued_packets); impl::WriteLogPackets(this->queued_packets);
} }
else if(log_packet_buf.IsHead()) { else if(log_packet_buf.IsHead()) {
/* This is the initial packet of a queue - ensure the queue is empty and push it. */ /* This is the initial packet of a queue - ensure the queue is empty and push it. */
this->queued_packets.clear(); this->queued_packets.clear();
this->queued_packets.push_back(std::move(log_packet_buf)); this->queued_packets.push_back(std::move(log_packet_buf));
} }
else if(log_packet_buf.IsTail()) { else if(log_packet_buf.IsTail()) {
/* This is the last packet of the queue - push it and log the queue. */ /* This is the last packet of the queue - push it and log the queue. */
this->queued_packets.push_back(std::move(log_packet_buf)); this->queued_packets.push_back(std::move(log_packet_buf));
impl::WriteLogPackets(this->queued_packets); impl::WriteLogPackets(this->queued_packets);
} }
else if(has_queued_packets) { else if(has_queued_packets) {
/* Another packet of the queue - push it. */ /* Another packet of the queue - push it. */
this->queued_packets.push_back(std::move(log_packet_buf)); this->queued_packets.push_back(std::move(log_packet_buf));
} }
else { else {
/* Invalid packet - but lm always must succeed on this call. */ /* Invalid packet - but lm must succeed on this call. */
/* This shouldn't happen at all... */
}
} }
} }

View File

@ -16,8 +16,6 @@ namespace ams::lm {
u64 program_id; u64 program_id;
LogDestination destination; LogDestination destination;
std::vector<impl::LogPacketBuffer> queued_packets; std::vector<impl::LogPacketBuffer> queued_packets;
void WriteQueuedPackets();
public: public:
Logger(u64 program_id) : program_id(program_id), destination(LogDestination::TMA), queued_packets() {} Logger(u64 program_id) : program_id(program_id), destination(LogDestination::TMA), queued_packets() {}