diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index ca39a6fb..e72a3e3d 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -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(); diff --git a/src/common/network/tcp_server_socket.hpp b/src/common/network/tcp_server_socket.hpp index 3d62fb1f..7acdd2aa 100644 --- a/src/common/network/tcp_server_socket.hpp +++ b/src/common/network/tcp_server_socket.hpp @@ -18,9 +18,9 @@ namespace network tcp_client_socket accept(); + void listen(); + private: bool listening_{false}; - - void listen(); }; } diff --git a/src/common/utils/function.hpp b/src/common/utils/function.hpp index b9925e99..db52ef63 100644 --- a/src/common/utils/function.hpp +++ b/src/common/utils/function.hpp @@ -10,7 +10,6 @@ namespace utils template class optional_function { - private: std::function func; public: diff --git a/src/gdb-stub/connection_handler.cpp b/src/gdb-stub/connection_handler.cpp index e6ee6ffc..5a9556cd 100644 --- a/src/gdb-stub/connection_handler.cpp +++ b/src/gdb-stub/connection_handler.cpp @@ -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 should_stop) + : should_stop_(std::move(should_stop)), + client_(client) { this->client_.set_blocking(false); @@ -48,7 +50,7 @@ namespace gdb_stub std::optional 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_)) { diff --git a/src/gdb-stub/connection_handler.hpp b/src/gdb-stub/connection_handler.hpp index 28d7a76f..e56004e1 100644 --- a/src/gdb-stub/connection_handler.hpp +++ b/src/gdb-stub/connection_handler.hpp @@ -1,7 +1,7 @@ #pragma once #include "stream_processor.hpp" -#include +#include #include #include @@ -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 should_stop = {}); ~connection_handler(); connection_handler(connection_handler&&) = delete; @@ -32,6 +32,7 @@ namespace gdb_stub bool should_stop() const; private: + utils::optional_function should_stop_{}; network::tcp_client_socket& client_; stream_processor processor_{}; diff --git a/src/gdb-stub/gdb_stub.cpp b/src/gdb-stub/gdb_stub.cpp index 5460fce2..c96018ed 100644 --- a/src/gdb-stub/gdb_stub.cpp +++ b/src/gdb-stub/gdb_stub.cpp @@ -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& 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; } diff --git a/src/gdb-stub/gdb_stub.hpp b/src/gdb-stub/gdb_stub.hpp index a29146a3..c9aa7fa0 100644 --- a/src/gdb-stub/gdb_stub.hpp +++ b/src/gdb-stub/gdb_stub.hpp @@ -50,6 +50,11 @@ namespace gdb_stub virtual std::vector get_thread_ids() = 0; virtual std::optional get_exit_code() = 0; + + virtual bool should_stop() + { + return false; + } }; bool run_gdb_stub(const network::address& bind_address, debugging_handler& handler); diff --git a/src/windows-gdb-stub/win_x64_gdb_stub_handler.hpp b/src/windows-gdb-stub/win_x64_gdb_stub_handler.hpp index a9d00147..b3ec03a4 100644 --- a/src/windows-gdb-stub/win_x64_gdb_stub_handler.hpp +++ b/src/windows-gdb-stub/win_x64_gdb_stub_handler.hpp @@ -2,16 +2,23 @@ #include "x64_gdb_stub_handler.hpp" #include +#include 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 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 should_stop_{}; };