committed by
GitHub
8 changed files with 288 additions and 345 deletions
-
2src/core/CMakeLists.txt
-
12src/core/core.cpp
-
7src/core/core.h
-
319src/core/hle/service/lm/lm.cpp
-
134src/core/hle/service/lm/manager.cpp
-
106src/core/hle/service/lm/manager.h
-
50src/core/reporter.cpp
-
3src/core/reporter.h
@ -1,134 +0,0 @@ |
|||
// Copyright 2019 yuzu emulator team
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include "common/assert.h"
|
|||
#include "common/logging/log.h"
|
|||
#include "common/string_util.h"
|
|||
#include "core/hle/service/lm/manager.h"
|
|||
#include "core/reporter.h"
|
|||
|
|||
namespace Service::LM { |
|||
|
|||
std::ostream& operator<<(std::ostream& os, DestinationFlag dest) { |
|||
std::vector<std::string> array; |
|||
const auto check_single_flag = [dest, &array](DestinationFlag check, std::string name) { |
|||
if ((static_cast<u32>(check) & static_cast<u32>(dest)) != 0) { |
|||
array.emplace_back(std::move(name)); |
|||
} |
|||
}; |
|||
|
|||
check_single_flag(DestinationFlag::Default, "Default"); |
|||
check_single_flag(DestinationFlag::UART, "UART"); |
|||
check_single_flag(DestinationFlag::UARTSleeping, "UART (Sleeping)"); |
|||
|
|||
os << "["; |
|||
for (const auto& entry : array) { |
|||
os << entry << ", "; |
|||
} |
|||
return os << "]"; |
|||
} |
|||
|
|||
std::ostream& operator<<(std::ostream& os, MessageHeader::Severity severity) { |
|||
switch (severity) { |
|||
case MessageHeader::Severity::Trace: |
|||
return os << "Trace"; |
|||
case MessageHeader::Severity::Info: |
|||
return os << "Info"; |
|||
case MessageHeader::Severity::Warning: |
|||
return os << "Warning"; |
|||
case MessageHeader::Severity::Error: |
|||
return os << "Error"; |
|||
case MessageHeader::Severity::Critical: |
|||
return os << "Critical"; |
|||
default: |
|||
return os << fmt::format("{:08X}", static_cast<u32>(severity)); |
|||
} |
|||
} |
|||
|
|||
std::ostream& operator<<(std::ostream& os, Field field) { |
|||
switch (field) { |
|||
case Field::Skip: |
|||
return os << "Skip"; |
|||
case Field::Message: |
|||
return os << "Message"; |
|||
case Field::Line: |
|||
return os << "Line"; |
|||
case Field::Filename: |
|||
return os << "Filename"; |
|||
case Field::Function: |
|||
return os << "Function"; |
|||
case Field::Module: |
|||
return os << "Module"; |
|||
case Field::Thread: |
|||
return os << "Thread"; |
|||
default: |
|||
return os << fmt::format("{:08X}", static_cast<u32>(field)); |
|||
} |
|||
} |
|||
|
|||
std::string FormatField(Field type, const std::vector<u8>& data) { |
|||
switch (type) { |
|||
case Field::Skip: |
|||
return ""; |
|||
case Field::Line: |
|||
if (data.size() >= sizeof(u32)) { |
|||
u32 line; |
|||
std::memcpy(&line, data.data(), sizeof(u32)); |
|||
return fmt::format("{}", line); |
|||
} |
|||
return "[ERROR DECODING LINE NUMBER]"; |
|||
case Field::Message: |
|||
case Field::Filename: |
|||
case Field::Function: |
|||
case Field::Module: |
|||
case Field::Thread: |
|||
return Common::StringFromFixedZeroTerminatedBuffer( |
|||
reinterpret_cast<const char*>(data.data()), data.size()); |
|||
default: |
|||
UNIMPLEMENTED_MSG("Unimplemented field type={}", type); |
|||
return ""; |
|||
} |
|||
} |
|||
|
|||
Manager::Manager(Core::Reporter& reporter) : reporter(reporter) {} |
|||
|
|||
Manager::~Manager() = default; |
|||
|
|||
void Manager::SetEnabled(bool enabled) { |
|||
this->enabled = enabled; |
|||
} |
|||
|
|||
void Manager::SetDestination(DestinationFlag destination) { |
|||
this->destination = destination; |
|||
} |
|||
|
|||
void Manager::Log(LogMessage message) { |
|||
if (message.header.IsHeadLog()) { |
|||
InitializeLog(); |
|||
} |
|||
|
|||
current_log.emplace_back(std::move(message)); |
|||
|
|||
if (current_log.back().header.IsTailLog()) { |
|||
FinalizeLog(); |
|||
} |
|||
} |
|||
|
|||
void Manager::Flush() { |
|||
FinalizeLog(); |
|||
} |
|||
|
|||
void Manager::InitializeLog() { |
|||
current_log.clear(); |
|||
|
|||
LOG_INFO(Service_LM, "Initialized new log session"); |
|||
} |
|||
|
|||
void Manager::FinalizeLog() { |
|||
reporter.SaveLogReport(static_cast<u32>(destination), std::move(current_log)); |
|||
|
|||
LOG_INFO(Service_LM, "Finalized current log session"); |
|||
} |
|||
|
|||
} // namespace Service::LM
|
|||
@ -1,106 +0,0 @@ |
|||
// Copyright 2019 yuzu emulator team |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <map> |
|||
#include <ostream> |
|||
#include <vector> |
|||
#include "common/bit_field.h" |
|||
#include "common/common_types.h" |
|||
#include "common/swap.h" |
|||
|
|||
namespace Core { |
|||
class Reporter; |
|||
} |
|||
|
|||
namespace Service::LM { |
|||
|
|||
enum class DestinationFlag : u32 { |
|||
Default = 1, |
|||
UART = 2, |
|||
UARTSleeping = 4, |
|||
|
|||
All = 0xFFFF, |
|||
}; |
|||
|
|||
struct MessageHeader { |
|||
enum Flags : u32_le { |
|||
IsHead = 1, |
|||
IsTail = 2, |
|||
}; |
|||
enum Severity : u32_le { |
|||
Trace, |
|||
Info, |
|||
Warning, |
|||
Error, |
|||
Critical, |
|||
}; |
|||
|
|||
u64_le pid; |
|||
u64_le thread_context; |
|||
union { |
|||
BitField<0, 16, Flags> flags; |
|||
BitField<16, 8, Severity> severity; |
|||
BitField<24, 8, u32> verbosity; |
|||
}; |
|||
u32_le payload_size; |
|||
|
|||
bool IsHeadLog() const { |
|||
return flags & IsHead; |
|||
} |
|||
bool IsTailLog() const { |
|||
return flags & IsTail; |
|||
} |
|||
}; |
|||
static_assert(sizeof(MessageHeader) == 0x18, "MessageHeader is incorrect size"); |
|||
|
|||
enum class Field : u8 { |
|||
Skip = 1, |
|||
Message = 2, |
|||
Line = 3, |
|||
Filename = 4, |
|||
Function = 5, |
|||
Module = 6, |
|||
Thread = 7, |
|||
}; |
|||
|
|||
std::ostream& operator<<(std::ostream& os, DestinationFlag dest); |
|||
std::ostream& operator<<(std::ostream& os, MessageHeader::Severity severity); |
|||
std::ostream& operator<<(std::ostream& os, Field field); |
|||
|
|||
using FieldMap = std::map<Field, std::vector<u8>>; |
|||
|
|||
struct LogMessage { |
|||
MessageHeader header; |
|||
FieldMap fields; |
|||
}; |
|||
|
|||
std::string FormatField(Field type, const std::vector<u8>& data); |
|||
|
|||
class Manager { |
|||
public: |
|||
explicit Manager(Core::Reporter& reporter); |
|||
~Manager(); |
|||
|
|||
void SetEnabled(bool enabled); |
|||
void SetDestination(DestinationFlag destination); |
|||
|
|||
void Log(LogMessage message); |
|||
|
|||
void Flush(); |
|||
|
|||
private: |
|||
void InitializeLog(); |
|||
void FinalizeLog(); |
|||
|
|||
bool enabled = true; |
|||
DestinationFlag destination = DestinationFlag::All; |
|||
|
|||
std::vector<LogMessage> current_log; |
|||
|
|||
Core::Reporter& reporter; |
|||
}; |
|||
|
|||
} // namespace Service::LM |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue