Update some Android dependencies and fix build by making boost-process optional (#120)
Based on #119 Co-authored-by: Ramiro <ramiro.depaoli@gmail.com> Co-authored-by: spectranator <spectranator@y2nlvhmmk5jnsvechppxnbyzmmv3vbl7dvzn6ltwcdbpgxixp3clkgqd.onion> Reviewed-on: http://vub63vv26q6v27xzv2dtcd25xumubshogm67yrpaz2rculqxs7jlfqad.onion/torzu-emu/torzu/pulls/120
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/debugger/debugger.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
@@ -9,33 +11,34 @@
|
||||
#include <boost/process/v1/async_pipe.hpp>
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "common/polyfill_thread.h"
|
||||
#include "common/thread.h"
|
||||
#include "core/core.h"
|
||||
#include "core/debugger/debugger.h"
|
||||
#include "core/debugger/debugger_interface.h"
|
||||
#include "core/debugger/gdbstub.h"
|
||||
#include "core/hle/kernel/global_scheduler_context.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/k_scheduler.h"
|
||||
|
||||
template <typename Readable, typename Buffer, typename Callback>
|
||||
static void AsyncReceiveInto(Readable& r, Buffer& buffer, Callback&& c) {
|
||||
template<typename Readable, typename Buffer, typename Callback>
|
||||
static void AsyncReceiveInto(Readable& r, Buffer& buffer, Callback&& c)
|
||||
{
|
||||
static_assert(std::is_trivial_v<Buffer>);
|
||||
auto boost_buffer{boost::asio::buffer(&buffer, sizeof(Buffer))};
|
||||
r.async_read_some(
|
||||
boost_buffer, [&, c](const boost::system::error_code& error, size_t bytes_read) {
|
||||
if (!error.failed()) {
|
||||
const u8* buffer_start = reinterpret_cast<const u8*>(&buffer);
|
||||
std::span<const u8> received_data{buffer_start, buffer_start + bytes_read};
|
||||
c(received_data);
|
||||
AsyncReceiveInto(r, buffer, c);
|
||||
}
|
||||
});
|
||||
r.async_read_some(boost_buffer,
|
||||
[&, c](const boost::system::error_code& error, size_t bytes_read) {
|
||||
if (!error.failed()) {
|
||||
const u8* buffer_start = reinterpret_cast<const u8*>(&buffer);
|
||||
std::span<const u8> received_data{buffer_start,
|
||||
buffer_start + bytes_read};
|
||||
c(received_data);
|
||||
AsyncReceiveInto(r, buffer, c);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Callback>
|
||||
static void AsyncAccept(boost::asio::ip::tcp::acceptor& acceptor, Callback&& c) {
|
||||
template<typename Callback>
|
||||
static void AsyncAccept(boost::asio::ip::tcp::acceptor& acceptor, Callback&& c)
|
||||
{
|
||||
acceptor.async_accept([&, c](const boost::system::error_code& error, auto&& peer_socket) {
|
||||
if (!error.failed()) {
|
||||
c(peer_socket);
|
||||
@@ -44,8 +47,9 @@ static void AsyncAccept(boost::asio::ip::tcp::acceptor& acceptor, Callback&& c)
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Readable, typename Buffer>
|
||||
static std::span<const u8> ReceiveInto(Readable& r, Buffer& buffer) {
|
||||
template<typename Readable, typename Buffer>
|
||||
static std::span<const u8> ReceiveInto(Readable& r, Buffer& buffer)
|
||||
{
|
||||
static_assert(std::is_trivial_v<Buffer>);
|
||||
auto boost_buffer{boost::asio::buffer(&buffer, sizeof(Buffer))};
|
||||
size_t bytes_read = r.read_some(boost_buffer);
|
||||
@@ -60,7 +64,8 @@ enum class SignalType {
|
||||
ShuttingDown,
|
||||
};
|
||||
|
||||
struct SignalInfo {
|
||||
struct SignalInfo
|
||||
{
|
||||
SignalType type;
|
||||
Kernel::KThread* thread;
|
||||
const Kernel::DebugWatchpoint* watchpoint;
|
||||
@@ -68,17 +73,19 @@ struct SignalInfo {
|
||||
|
||||
namespace Core {
|
||||
|
||||
class DebuggerImpl : public DebuggerBackend {
|
||||
class DebuggerImpl : public DebuggerBackend
|
||||
{
|
||||
public:
|
||||
explicit DebuggerImpl(Core::System& system_, u16 port) : system{system_} {
|
||||
explicit DebuggerImpl(Core::System& system_, u16 port)
|
||||
: system{system_}
|
||||
{
|
||||
InitializeServer(port);
|
||||
}
|
||||
|
||||
~DebuggerImpl() override {
|
||||
ShutdownServer();
|
||||
}
|
||||
~DebuggerImpl() override { ShutdownServer(); }
|
||||
|
||||
bool SignalDebugger(SignalInfo signal_info) {
|
||||
bool SignalDebugger(SignalInfo signal_info)
|
||||
{
|
||||
std::scoped_lock lk{connection_lock};
|
||||
|
||||
if (stopped || !state) {
|
||||
@@ -100,25 +107,24 @@ public:
|
||||
// These functions are callbacks from the frontend, and the lock will be held.
|
||||
// There is no need to relock it.
|
||||
|
||||
std::span<const u8> ReadFromClient() override {
|
||||
std::span<const u8> ReadFromClient() override
|
||||
{
|
||||
return ReceiveInto(state->client_socket, state->client_data);
|
||||
}
|
||||
|
||||
void WriteToClient(std::span<const u8> data) override {
|
||||
void WriteToClient(std::span<const u8> data) override
|
||||
{
|
||||
boost::asio::write(state->client_socket,
|
||||
boost::asio::buffer(data.data(), data.size_bytes()));
|
||||
}
|
||||
|
||||
void SetActiveThread(Kernel::KThread* thread) override {
|
||||
state->active_thread = thread;
|
||||
}
|
||||
void SetActiveThread(Kernel::KThread* thread) override { state->active_thread = thread; }
|
||||
|
||||
Kernel::KThread* GetActiveThread() override {
|
||||
return state->active_thread.GetPointerUnsafe();
|
||||
}
|
||||
Kernel::KThread* GetActiveThread() override { return state->active_thread.GetPointerUnsafe(); }
|
||||
|
||||
private:
|
||||
void InitializeServer(u16 port) {
|
||||
void InitializeServer(u16 port)
|
||||
{
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
LOG_INFO(Debug_GDBStub, "Starting server on port {}...", port);
|
||||
@@ -142,7 +148,8 @@ private:
|
||||
});
|
||||
}
|
||||
|
||||
void AcceptConnection(boost::asio::ip::tcp::socket&& peer) {
|
||||
void AcceptConnection(boost::asio::ip::tcp::socket&& peer)
|
||||
{
|
||||
LOG_INFO(Debug_GDBStub, "Accepting new peer connection");
|
||||
|
||||
std::scoped_lock lk{connection_lock};
|
||||
@@ -177,13 +184,15 @@ private:
|
||||
frontend->Connected();
|
||||
}
|
||||
|
||||
void ShutdownServer() {
|
||||
void ShutdownServer()
|
||||
{
|
||||
connection_thread.request_stop();
|
||||
io_context.stop();
|
||||
connection_thread.join();
|
||||
}
|
||||
|
||||
void PipeData(std::span<const u8> data) {
|
||||
void PipeData(std::span<const u8> data)
|
||||
{
|
||||
std::scoped_lock lk{connection_lock};
|
||||
|
||||
switch (state->info.type) {
|
||||
@@ -197,8 +206,7 @@ private:
|
||||
UpdateActiveThread();
|
||||
|
||||
if (state->info.type == SignalType::Watchpoint) {
|
||||
frontend->Watchpoint(std::addressof(*state->active_thread),
|
||||
*state->info.watchpoint);
|
||||
frontend->Watchpoint(std::addressof(*state->active_thread), *state->info.watchpoint);
|
||||
} else {
|
||||
frontend->Stopped(std::addressof(*state->active_thread));
|
||||
}
|
||||
@@ -220,7 +228,8 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void ClientData(std::span<const u8> data) {
|
||||
void ClientData(std::span<const u8> data)
|
||||
{
|
||||
std::scoped_lock lk{connection_lock};
|
||||
|
||||
const auto actions{frontend->ClientData(data)};
|
||||
@@ -262,7 +271,8 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void PauseEmulation() {
|
||||
void PauseEmulation()
|
||||
{
|
||||
Kernel::KScopedLightLock ll{debug_process->GetListLock()};
|
||||
Kernel::KScopedSchedulerLock sl{system.Kernel()};
|
||||
|
||||
@@ -272,7 +282,8 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void ResumeEmulation(Kernel::KThread* except = nullptr) {
|
||||
void ResumeEmulation(Kernel::KThread* except = nullptr)
|
||||
{
|
||||
Kernel::KScopedLightLock ll{debug_process->GetListLock()};
|
||||
Kernel::KScopedSchedulerLock sl{system.Kernel()};
|
||||
|
||||
@@ -287,13 +298,15 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Callback>
|
||||
void MarkResumed(Callback&& cb) {
|
||||
template<typename Callback>
|
||||
void MarkResumed(Callback&& cb)
|
||||
{
|
||||
stopped = false;
|
||||
cb();
|
||||
}
|
||||
|
||||
void UpdateActiveThread() {
|
||||
void UpdateActiveThread()
|
||||
{
|
||||
Kernel::KScopedLightLock ll{debug_process->GetListLock()};
|
||||
|
||||
auto& threads{ThreadList()};
|
||||
@@ -307,13 +320,9 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
void SetDebugProcess() {
|
||||
debug_process = std::move(system.Kernel().GetProcessList().back());
|
||||
}
|
||||
void SetDebugProcess() { debug_process = std::move(system.Kernel().GetProcessList().back()); }
|
||||
|
||||
Kernel::KProcess::ThreadList& ThreadList() {
|
||||
return debug_process->GetThreadList();
|
||||
}
|
||||
Kernel::KProcess::ThreadList& ThreadList() { return debug_process->GetThreadList(); }
|
||||
|
||||
private:
|
||||
System& system;
|
||||
@@ -324,7 +333,8 @@ private:
|
||||
std::jthread connection_thread;
|
||||
std::mutex connection_lock;
|
||||
|
||||
struct ConnectionState {
|
||||
struct ConnectionState
|
||||
{
|
||||
boost::asio::ip::tcp::socket client_socket;
|
||||
boost::process::v1::async_pipe signal_pipe;
|
||||
|
||||
@@ -338,7 +348,8 @@ private:
|
||||
bool stopped{};
|
||||
};
|
||||
|
||||
Debugger::Debugger(Core::System& system, u16 port) {
|
||||
Debugger::Debugger(Core::System& system, u16 port)
|
||||
{
|
||||
try {
|
||||
impl = std::make_unique<DebuggerImpl>(system, port);
|
||||
} catch (const std::exception& ex) {
|
||||
@@ -348,16 +359,18 @@ Debugger::Debugger(Core::System& system, u16 port) {
|
||||
|
||||
Debugger::~Debugger() = default;
|
||||
|
||||
bool Debugger::NotifyThreadStopped(Kernel::KThread* thread) {
|
||||
bool Debugger::NotifyThreadStopped(Kernel::KThread* thread)
|
||||
{
|
||||
return impl && impl->SignalDebugger(SignalInfo{SignalType::Stopped, thread, nullptr});
|
||||
}
|
||||
|
||||
bool Debugger::NotifyThreadWatchpoint(Kernel::KThread* thread,
|
||||
const Kernel::DebugWatchpoint& watch) {
|
||||
bool Debugger::NotifyThreadWatchpoint(Kernel::KThread* thread, const Kernel::DebugWatchpoint& watch)
|
||||
{
|
||||
return impl && impl->SignalDebugger(SignalInfo{SignalType::Watchpoint, thread, &watch});
|
||||
}
|
||||
|
||||
void Debugger::NotifyShutdown() {
|
||||
void Debugger::NotifyShutdown()
|
||||
{
|
||||
if (impl) {
|
||||
impl->SignalDebugger(SignalInfo{SignalType::ShuttingDown, nullptr, nullptr});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user