mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-24 22:21:03 +00:00
Support dump generation for GDB mode
This commit is contained in:
@@ -14,7 +14,7 @@ namespace
|
||||
{
|
||||
struct analysis_options
|
||||
{
|
||||
bool use_gdb{false};
|
||||
mutable bool use_gdb{false};
|
||||
bool concise_logging{false};
|
||||
bool verbose_logging{false};
|
||||
bool silent{false};
|
||||
@@ -98,7 +98,9 @@ namespace
|
||||
const auto* address = "127.0.0.1:28960";
|
||||
win_emu.log.print(color::pink, "Waiting for GDB connection on %s...\n", address);
|
||||
|
||||
win_x64_gdb_stub_handler handler{win_emu};
|
||||
const auto should_stop = [&] { return signals_received > 0; };
|
||||
|
||||
win_x64_gdb_stub_handler handler{win_emu, should_stop};
|
||||
gdb_stub::run_gdb_stub(network::address{"0.0.0.0:28960", AF_INET}, handler);
|
||||
}
|
||||
else
|
||||
@@ -108,6 +110,8 @@ namespace
|
||||
|
||||
if (signals_received > 0)
|
||||
{
|
||||
options.use_gdb = false;
|
||||
|
||||
win_emu.log.log("Do you want to create a snapshot? (y/n)\n");
|
||||
const auto write_snapshot = read_yes_no_answer();
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ namespace network
|
||||
|
||||
tcp_client_socket accept();
|
||||
|
||||
void listen();
|
||||
|
||||
private:
|
||||
bool listening_{false};
|
||||
|
||||
void listen();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ namespace utils
|
||||
template <typename Ret, typename... Args>
|
||||
class optional_function<Ret(Args...)>
|
||||
{
|
||||
private:
|
||||
std::function<Ret(Args...)> func;
|
||||
|
||||
public:
|
||||
|
||||
@@ -23,8 +23,10 @@ namespace gdb_stub
|
||||
}
|
||||
}
|
||||
|
||||
connection_handler::connection_handler(network::tcp_client_socket& client)
|
||||
: client_(client)
|
||||
connection_handler::connection_handler(network::tcp_client_socket& client,
|
||||
utils::optional_function<bool()> should_stop)
|
||||
: should_stop_(std::move(should_stop)),
|
||||
client_(client)
|
||||
{
|
||||
this->client_.set_blocking(false);
|
||||
|
||||
@@ -48,7 +50,7 @@ namespace gdb_stub
|
||||
|
||||
std::optional<std::string> connection_handler::get_packet()
|
||||
{
|
||||
while (this->client_.is_valid() && !this->processor_.has_packet())
|
||||
while (this->client_.is_valid() && !this->processor_.has_packet() && !this->should_stop_())
|
||||
{
|
||||
if (!read_from_socket(this->processor_, this->client_))
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "stream_processor.hpp"
|
||||
|
||||
#include <utils/concurrency.hpp>
|
||||
#include <utils/function.hpp>
|
||||
#include <network/tcp_client_socket.hpp>
|
||||
|
||||
#include <thread>
|
||||
@@ -13,7 +13,7 @@ namespace gdb_stub
|
||||
class connection_handler
|
||||
{
|
||||
public:
|
||||
connection_handler(network::tcp_client_socket& client);
|
||||
connection_handler(network::tcp_client_socket& client, utils::optional_function<bool()> should_stop = {});
|
||||
~connection_handler();
|
||||
|
||||
connection_handler(connection_handler&&) = delete;
|
||||
@@ -32,6 +32,7 @@ namespace gdb_stub
|
||||
bool should_stop() const;
|
||||
|
||||
private:
|
||||
utils::optional_function<bool()> should_stop_{};
|
||||
network::tcp_client_socket& client_;
|
||||
stream_processor processor_{};
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ namespace gdb_stub
|
||||
async_handler& async;
|
||||
};
|
||||
|
||||
network::tcp_client_socket accept_client(const network::address& bind_address)
|
||||
network::tcp_client_socket accept_client(const network::address& bind_address,
|
||||
const utils::optional_function<bool()>& should_stop)
|
||||
{
|
||||
network::tcp_server_socket server{bind_address.get_family()};
|
||||
if (!server.bind(bind_address))
|
||||
@@ -43,6 +44,17 @@ namespace gdb_stub
|
||||
return false;
|
||||
}
|
||||
|
||||
server.set_blocking(false);
|
||||
server.listen();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (should_stop() || server.sleep(100ms))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return server.accept();
|
||||
}
|
||||
|
||||
@@ -593,7 +605,11 @@ namespace gdb_stub
|
||||
|
||||
bool run_gdb_stub(const network::address& bind_address, debugging_handler& handler)
|
||||
{
|
||||
auto client = accept_client(bind_address);
|
||||
const auto should_stop = [&] {
|
||||
return handler.should_stop(); //
|
||||
};
|
||||
|
||||
auto client = accept_client(bind_address, should_stop);
|
||||
if (!client)
|
||||
{
|
||||
return false;
|
||||
@@ -602,11 +618,10 @@ namespace gdb_stub
|
||||
async_handler async{[&](std::atomic_bool& can_run) {
|
||||
while (can_run)
|
||||
{
|
||||
std::this_thread::sleep_for(10ms);
|
||||
|
||||
(void)client.sleep(100ms);
|
||||
const auto data = client.receive(1);
|
||||
|
||||
if (is_interrupt_packet(data) || !client.is_valid())
|
||||
if (is_interrupt_packet(data) || !client.is_valid() || should_stop())
|
||||
{
|
||||
handler.on_interrupt();
|
||||
can_run = false;
|
||||
@@ -615,7 +630,7 @@ namespace gdb_stub
|
||||
}};
|
||||
|
||||
debugging_state state{};
|
||||
connection_handler connection{client};
|
||||
connection_handler connection{client, should_stop};
|
||||
|
||||
debugging_context c{
|
||||
.connection = connection,
|
||||
@@ -624,10 +639,10 @@ namespace gdb_stub
|
||||
.async = async,
|
||||
};
|
||||
|
||||
while (true)
|
||||
while (!should_stop())
|
||||
{
|
||||
const auto packet = connection.get_packet();
|
||||
if (!packet)
|
||||
if (!packet || should_stop())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,11 @@ namespace gdb_stub
|
||||
virtual std::vector<uint32_t> get_thread_ids() = 0;
|
||||
|
||||
virtual std::optional<uint32_t> get_exit_code() = 0;
|
||||
|
||||
virtual bool should_stop()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
bool run_gdb_stub(const network::address& bind_address, debugging_handler& handler);
|
||||
|
||||
@@ -2,16 +2,23 @@
|
||||
#include "x64_gdb_stub_handler.hpp"
|
||||
|
||||
#include <windows_emulator.hpp>
|
||||
#include <utils/function.hpp>
|
||||
|
||||
class win_x64_gdb_stub_handler : public x64_gdb_stub_handler
|
||||
{
|
||||
public:
|
||||
win_x64_gdb_stub_handler(windows_emulator& win_emu)
|
||||
win_x64_gdb_stub_handler(windows_emulator& win_emu, utils::optional_function<bool()> should_stop = {})
|
||||
: x64_gdb_stub_handler(win_emu.emu()),
|
||||
win_emu_(&win_emu)
|
||||
win_emu_(&win_emu),
|
||||
should_stop_(std::move(should_stop))
|
||||
{
|
||||
}
|
||||
|
||||
bool should_stop() override
|
||||
{
|
||||
return this->should_stop_();
|
||||
}
|
||||
|
||||
gdb_stub::action run() override
|
||||
{
|
||||
try
|
||||
@@ -81,4 +88,5 @@ class win_x64_gdb_stub_handler : public x64_gdb_stub_handler
|
||||
|
||||
private:
|
||||
windows_emulator* win_emu_{};
|
||||
utils::optional_function<bool()> should_stop_{};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user