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
|
; 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.
|
||||||
|
@ -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": [
|
||||||
{
|
{
|
||||||
|
@ -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); };
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
@ -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... */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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() {}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user