mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-10-01 15:17:08 +02:00
Add setting to enable/disable logging, some cleanup
This commit is contained in:
parent
69658dc72f
commit
3b60e0ad3d
@ -32,6 +32,10 @@
|
||||
; NOTE: EXPERIMENTAL
|
||||
; If you do not know what you are doing, do not touch this yet.
|
||||
; 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
|
||||
; to fix compatibility with old homebrew.
|
||||
; 0 = Do not enable, 1 = Enable.
|
||||
|
@ -14,7 +14,7 @@
|
||||
"filesystem_access": {
|
||||
"permissions": "0xFFFFFFFFFFFFFFFF"
|
||||
},
|
||||
"service_access": [ "fsp-srv", "pm:info", "psc:m" ],
|
||||
"service_access": [ "fsp-srv", "pm:info", "psc:m", "set:sys" ],
|
||||
"service_host": [ "lm" ],
|
||||
"kernel_capabilities": [
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ namespace ams::lm::impl {
|
||||
std::snprintf(process_dir, sizeof(process_dir), "%s/0x%016lX", DebugLogDirectory, program_id);
|
||||
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 = {
|
||||
.log_id = os::GetSystemTick().GetInt64Value(),
|
||||
.program_id = program_id,
|
||||
@ -52,13 +52,14 @@ namespace ams::lm::impl {
|
||||
|
||||
/* Generate binary log path. */
|
||||
/* 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] = {};
|
||||
std::snprintf(bin_log_path, sizeof(bin_log_path), "%s/0x%016lX.bin", process_dir, info.log_id);
|
||||
|
||||
/* Ensure the file exists. */
|
||||
fs::CreateFile(bin_log_path, 0);
|
||||
|
||||
/* Now, open the file. */
|
||||
/* Open the file. */
|
||||
fs::FileHandle bin_log_file;
|
||||
R_TRY(fs::OpenFile(&bin_log_file, bin_log_path, fs::OpenMode_Write | fs::OpenMode_AllowAppend));
|
||||
ON_SCOPE_EXIT { fs::CloseFile(bin_log_file); };
|
||||
|
@ -7,9 +7,9 @@ namespace ams::lm::impl {
|
||||
constexpr const char DebugLogDirectory[] = "sdmc:/atmosphere/debug_logs";
|
||||
|
||||
enum LogPacketFlags : u8 {
|
||||
LogPacketFlags_Head = BIT(0),
|
||||
LogPacketFlags_Tail = BIT(1),
|
||||
LogPacketFlags_LittleEndian = BIT(2), /* Is this used anywhere? */
|
||||
LogPacketFlags_Head = BIT(0), /* Head -> a packet list is being sent, with this packet being the initial one. */
|
||||
LogPacketFlags_Tail = BIT(1), /* Tail -> this is the final packet of the packet list. */
|
||||
LogPacketFlags_LittleEndian = BIT(2),
|
||||
};
|
||||
|
||||
struct LogPacketHeader {
|
||||
@ -22,12 +22,10 @@ namespace ams::lm::impl {
|
||||
u32 payload_size;
|
||||
|
||||
inline constexpr bool IsHead() const {
|
||||
/* Head -> a packet list is being sent, with this packet being the initial one. */
|
||||
return this->flags & LogPacketFlags_Head;
|
||||
}
|
||||
|
||||
inline constexpr bool IsTail() const {
|
||||
/* Tail -> this is the final packet of the packet list. */
|
||||
return this->flags & LogPacketFlags_Tail;
|
||||
}
|
||||
|
||||
@ -35,7 +33,7 @@ namespace ams::lm::impl {
|
||||
static_assert(sizeof(LogPacketHeader) == 0x18, "LogPacketHeader definition");
|
||||
|
||||
struct LogInfo {
|
||||
s64 log_id;
|
||||
s64 log_id; /* This is the system tick value when the log was saved. */
|
||||
u64 program_id;
|
||||
};
|
||||
|
||||
@ -69,14 +67,6 @@ namespace ams::lm::impl {
|
||||
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 {
|
||||
if(this->buf == nullptr) {
|
||||
return false;
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "lm_service.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern u32 __start__;
|
||||
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
|
||||
@ -13,7 +13,6 @@ extern "C" {
|
||||
void __libnx_initheap(void);
|
||||
void __appInit(void);
|
||||
void __appExit(void);
|
||||
|
||||
}
|
||||
|
||||
namespace ams {
|
||||
@ -22,7 +21,7 @@ namespace ams {
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
@ -51,15 +50,19 @@ void __appInit(void) {
|
||||
R_ABORT_UNLESS(pminfoInitialize());
|
||||
R_ABORT_UNLESS(fsInitialize());
|
||||
R_ABORT_UNLESS(pscmInitialize());
|
||||
R_ABORT_UNLESS(setsysInitialize());
|
||||
});
|
||||
|
||||
R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
|
||||
|
||||
ams::CheckApiVersion();
|
||||
}
|
||||
|
||||
void __appExit(void) {
|
||||
/* Cleanup services. */
|
||||
fs::Unmount("sdmc");
|
||||
|
||||
/* Cleanup services. */
|
||||
setsysExit();
|
||||
pscmExit();
|
||||
fsExit();
|
||||
pminfoExit();
|
||||
@ -67,8 +70,7 @@ void __appExit(void) {
|
||||
|
||||
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 {
|
||||
static constexpr size_t PointerBufferSize = 0;
|
||||
static constexpr size_t MaxDomains = 0x40;
|
||||
@ -143,5 +145,6 @@ int main(int argc, char **argv) {
|
||||
/* Loop forever, servicing our services. */
|
||||
lm::StartAndLoopProcess();
|
||||
|
||||
/* Cleanup */
|
||||
return 0;
|
||||
}
|
@ -2,38 +2,52 @@
|
||||
|
||||
namespace ams::lm {
|
||||
|
||||
void Logger::WriteQueuedPackets() {
|
||||
impl::WriteLogPackets(this->queued_packets);
|
||||
namespace {
|
||||
|
||||
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) {
|
||||
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. */
|
||||
const bool has_queued_packets = !this->queued_packets.empty();
|
||||
/* Check if there's a queue already started. */
|
||||
const bool has_queued_packets = !this->queued_packets.empty();
|
||||
|
||||
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. */
|
||||
this->queued_packets.clear();
|
||||
this->queued_packets.push_back(std::move(log_packet_buf));
|
||||
impl::WriteLogPackets(this->queued_packets);
|
||||
}
|
||||
else if(log_packet_buf.IsHead()) {
|
||||
/* This is the initial packet of a queue - ensure the queue is empty and push it. */
|
||||
this->queued_packets.clear();
|
||||
this->queued_packets.push_back(std::move(log_packet_buf));
|
||||
}
|
||||
else if(log_packet_buf.IsTail()) {
|
||||
/* This is the last packet of the queue - push it and log the queue. */
|
||||
this->queued_packets.push_back(std::move(log_packet_buf));
|
||||
impl::WriteLogPackets(this->queued_packets);
|
||||
}
|
||||
else if(has_queued_packets) {
|
||||
/* Another packet of the queue - push it. */
|
||||
this->queued_packets.push_back(std::move(log_packet_buf));
|
||||
}
|
||||
else {
|
||||
/* Invalid packet - but lm always must succeed on this call. */
|
||||
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. */
|
||||
this->queued_packets.clear();
|
||||
this->queued_packets.push_back(std::move(log_packet_buf));
|
||||
impl::WriteLogPackets(this->queued_packets);
|
||||
}
|
||||
else if(log_packet_buf.IsHead()) {
|
||||
/* This is the initial packet of a queue - ensure the queue is empty and push it. */
|
||||
this->queued_packets.clear();
|
||||
this->queued_packets.push_back(std::move(log_packet_buf));
|
||||
}
|
||||
else if(log_packet_buf.IsTail()) {
|
||||
/* This is the last packet of the queue - push it and log the queue. */
|
||||
this->queued_packets.push_back(std::move(log_packet_buf));
|
||||
impl::WriteLogPackets(this->queued_packets);
|
||||
}
|
||||
else if(has_queued_packets) {
|
||||
/* Another packet of the queue - push it. */
|
||||
this->queued_packets.push_back(std::move(log_packet_buf));
|
||||
}
|
||||
else {
|
||||
/* Invalid packet - but lm must succeed on this call. */
|
||||
/* This shouldn't happen at all... */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,6 @@ namespace ams::lm {
|
||||
u64 program_id;
|
||||
LogDestination destination;
|
||||
std::vector<impl::LogPacketBuffer> queued_packets;
|
||||
|
||||
void WriteQueuedPackets();
|
||||
public:
|
||||
Logger(u64 program_id) : program_id(program_id), destination(LogDestination::TMA), queued_packets() {}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user