mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-19 19:35:41 -04:00
System: Move GDB server into core
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
find_package(Qt6 6.6.0 COMPONENTS Core Gui Widgets Network LinguistTools REQUIRED)
|
||||
find_package(Qt6 6.7.0 COMPONENTS Core Gui Widgets LinguistTools REQUIRED)
|
||||
|
||||
include(CopyBaseTranslations)
|
||||
|
||||
@ -96,10 +96,6 @@ set(SRCS
|
||||
gamesummarywidget.cpp
|
||||
gamesummarywidget.h
|
||||
gamesummarywidget.ui
|
||||
gdbconnection.cpp
|
||||
gdbconnection.h
|
||||
gdbserver.cpp
|
||||
gdbserver.h
|
||||
graphicssettingswidget.cpp
|
||||
graphicssettingswidget.h
|
||||
graphicssettingswidget.ui
|
||||
@ -175,7 +171,7 @@ set(TS_FILES
|
||||
add_executable(duckstation-qt ${SRCS} ${QM_FILES})
|
||||
target_precompile_headers(duckstation-qt PRIVATE "pch.h")
|
||||
target_include_directories(duckstation-qt PRIVATE "${Qt6Gui_PRIVATE_INCLUDE_DIRS}" "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
target_link_libraries(duckstation-qt PRIVATE core common imgui minizip scmversion Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Network)
|
||||
target_link_libraries(duckstation-qt PRIVATE core common imgui minizip scmversion Qt6::Core Qt6::Gui Qt6::Widgets)
|
||||
|
||||
# Our Qt builds may have exceptions on, so force them off.
|
||||
target_compile_definitions(duckstation-qt PRIVATE QT_NO_EXCEPTIONS)
|
||||
|
@ -36,8 +36,6 @@
|
||||
<ClCompile Include="gamelistrefreshthread.cpp" />
|
||||
<ClCompile Include="gamelistwidget.cpp" />
|
||||
<ClCompile Include="gamesummarywidget.cpp" />
|
||||
<ClCompile Include="gdbconnection.cpp" />
|
||||
<ClCompile Include="gdbserver.cpp" />
|
||||
<ClCompile Include="mainwindow.cpp" />
|
||||
<ClCompile Include="memorycardsettingswidget.cpp" />
|
||||
<ClCompile Include="memorycardeditorwindow.cpp" />
|
||||
@ -97,8 +95,6 @@
|
||||
<QtMoc Include="gamelistrefreshthread.h" />
|
||||
<QtMoc Include="gamelistwidget.h" />
|
||||
<QtMoc Include="gamesummarywidget.h" />
|
||||
<QtMoc Include="gdbconnection.h" />
|
||||
<QtMoc Include="gdbserver.h" />
|
||||
<QtMoc Include="postprocessingsettingswidget.h" />
|
||||
<QtMoc Include="mainwindow.h" />
|
||||
<QtMoc Include="qthost.h" />
|
||||
@ -243,8 +239,6 @@
|
||||
<ClCompile Include="$(IntDir)moc_gamelistsettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_gamelistwidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_gamesummarywidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_gdbconnection.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_gdbserver.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_graphicssettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_debuggermodels.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_debuggerwindow.cpp" />
|
||||
|
@ -15,8 +15,6 @@
|
||||
<ClCompile Include="qtprogresscallback.cpp" />
|
||||
<ClCompile Include="interfacesettingswidget.cpp" />
|
||||
<ClCompile Include="advancedsettingswidget.cpp" />
|
||||
<ClCompile Include="gdbconnection.cpp" />
|
||||
<ClCompile Include="gdbserver.cpp" />
|
||||
<ClCompile Include="aboutdialog.cpp" />
|
||||
<ClCompile Include="memorycardsettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)qrc_resources.cpp" />
|
||||
@ -126,12 +124,6 @@
|
||||
<ClCompile Include="$(IntDir)moc_gamesummarywidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)moc_gdbconnection.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)moc_gdbserver.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)moc_hotkeysettingswidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
@ -219,8 +211,6 @@
|
||||
<QtMoc Include="interfacesettingswidget.h" />
|
||||
<QtMoc Include="qtprogresscallback.h" />
|
||||
<QtMoc Include="advancedsettingswidget.h" />
|
||||
<QtMoc Include="gdbconnection.h" />
|
||||
<QtMoc Include="gdbserver.h" />
|
||||
<QtMoc Include="aboutdialog.h" />
|
||||
<QtMoc Include="memorycardsettingswidget.h" />
|
||||
<QtMoc Include="inputbindingdialog.h" />
|
||||
|
@ -1,95 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com> and contributors.
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "gdbconnection.h"
|
||||
#include "common/log.h"
|
||||
#include "core/gdb_protocol.h"
|
||||
#include "qthost.h"
|
||||
Log_SetChannel(GDBConnection);
|
||||
|
||||
GDBConnection::GDBConnection(GDBServer* parent, intptr_t descriptor) : QTcpSocket(parent), m_descriptor(descriptor)
|
||||
{
|
||||
if (!setSocketDescriptor(descriptor))
|
||||
{
|
||||
ERROR_LOG("{} failed to set socket descriptor: {}", descriptor, errorString().toStdString());
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
connect(g_emu_thread, &EmuThread::systemPaused, this, &GDBConnection::onEmulationPaused);
|
||||
connect(g_emu_thread, &EmuThread::systemResumed, this, &GDBConnection::onEmulationResumed);
|
||||
connect(this, &QTcpSocket::readyRead, this, &GDBConnection::receivedData);
|
||||
connect(this, &QTcpSocket::disconnected, this, &GDBConnection::gotDisconnected);
|
||||
|
||||
INFO_LOG("{} client connected", m_descriptor);
|
||||
|
||||
m_seen_resume = System::IsPaused();
|
||||
g_emu_thread->setSystemPaused(true);
|
||||
}
|
||||
|
||||
void GDBConnection::gotDisconnected()
|
||||
{
|
||||
INFO_LOG("{} client disconnected", m_descriptor);
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void GDBConnection::receivedData()
|
||||
{
|
||||
qint64 bytesRead;
|
||||
char buffer[256];
|
||||
|
||||
while ((bytesRead = read(buffer, sizeof(buffer))) > 0)
|
||||
{
|
||||
for (char c : std::string_view(buffer, bytesRead))
|
||||
{
|
||||
m_readBuffer.push_back(c);
|
||||
|
||||
if (GDBProtocol::IsPacketInterrupt(m_readBuffer))
|
||||
{
|
||||
DEBUG_LOG("{} > Interrupt request", m_descriptor);
|
||||
g_emu_thread->setSystemPaused(true);
|
||||
m_readBuffer.erase();
|
||||
}
|
||||
else if (GDBProtocol::IsPacketContinue(m_readBuffer))
|
||||
{
|
||||
DEBUG_LOG("{} > Continue request", m_descriptor);
|
||||
g_emu_thread->setSystemPaused(false);
|
||||
m_readBuffer.erase();
|
||||
}
|
||||
else if (GDBProtocol::IsPacketComplete(m_readBuffer))
|
||||
{
|
||||
DEBUG_LOG("{} > {}", m_descriptor, m_readBuffer);
|
||||
writePacket(GDBProtocol::ProcessPacket(m_readBuffer));
|
||||
m_readBuffer.erase();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bytesRead == -1)
|
||||
{
|
||||
ERROR_LOG("{} failed to read from socket: {}", m_descriptor, errorString().toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
void GDBConnection::onEmulationPaused()
|
||||
{
|
||||
if (m_seen_resume)
|
||||
{
|
||||
m_seen_resume = false;
|
||||
// Generate a stop reply packet, insert '?' command to generate it.
|
||||
writePacket(GDBProtocol::ProcessPacket("$?#3f"));
|
||||
}
|
||||
}
|
||||
|
||||
void GDBConnection::onEmulationResumed()
|
||||
{
|
||||
m_seen_resume = true;
|
||||
// Send ack, in case GDB sent a continue request.
|
||||
writePacket("+");
|
||||
}
|
||||
|
||||
void GDBConnection::writePacket(std::string_view packet)
|
||||
{
|
||||
DEBUG_LOG("{} < {}", m_descriptor, packet);
|
||||
if (write(packet.data(), packet.length()) == -1)
|
||||
ERROR_LOG("{} failed to write to socket: {}", m_descriptor, errorString().toStdString());
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com> and contributors.
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#pragma once
|
||||
#include <QtCore/QThread>
|
||||
#include <QtNetwork/QTcpSocket>
|
||||
|
||||
class GDBServer;
|
||||
|
||||
class GDBConnection : public QTcpSocket
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GDBConnection(GDBServer *parent, intptr_t descriptor);
|
||||
|
||||
public Q_SLOTS:
|
||||
void gotDisconnected();
|
||||
void receivedData();
|
||||
void onEmulationPaused();
|
||||
void onEmulationResumed();
|
||||
|
||||
private:
|
||||
void writePacket(std::string_view data);
|
||||
|
||||
intptr_t m_descriptor;
|
||||
std::string m_readBuffer;
|
||||
bool m_seen_resume;
|
||||
};
|
@ -1,52 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com> and contributors.
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "gdbserver.h"
|
||||
#include "common/log.h"
|
||||
#include "gdbconnection.h"
|
||||
#include "qthost.h"
|
||||
Log_SetChannel(GDBServer);
|
||||
|
||||
GDBServer::GDBServer(QObject* parent) : QTcpServer(parent)
|
||||
{
|
||||
}
|
||||
|
||||
GDBServer::~GDBServer()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void GDBServer::start(quint16 port)
|
||||
{
|
||||
if (isListening())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!listen(QHostAddress::LocalHost, port))
|
||||
{
|
||||
ERROR_LOG("Failed to listen on TCP port {} for GDB server: {}", port, errorString().toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
INFO_LOG("GDB server listening on TCP port {}", port);
|
||||
}
|
||||
|
||||
void GDBServer::stop()
|
||||
{
|
||||
if (isListening())
|
||||
{
|
||||
close();
|
||||
INFO_LOG("GDB server stopped");
|
||||
}
|
||||
|
||||
for (QObject* connection : children())
|
||||
{
|
||||
connection->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void GDBServer::incomingConnection(qintptr descriptor)
|
||||
{
|
||||
new GDBConnection(this, descriptor);
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com> and contributors.
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#pragma once
|
||||
#include "core/types.h"
|
||||
#include "gdbconnection.h"
|
||||
#include <QtNetwork/QTcpServer>
|
||||
|
||||
class GDBServer : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GDBServer(QObject* parent = nullptr);
|
||||
~GDBServer();
|
||||
|
||||
public Q_SLOTS:
|
||||
void start(quint16 port);
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
void incomingConnection(qintptr socketDescriptor) override;
|
||||
};
|
@ -1826,16 +1826,6 @@ void MainWindow::updateEmulationActions(bool starting, bool running, bool cheevo
|
||||
if ((!starting && !running) || running)
|
||||
m_open_debugger_on_start = false;
|
||||
|
||||
if (!g_gdb_server->isListening() && g_settings.debugging.enable_gdb_server && starting)
|
||||
{
|
||||
QMetaObject::invokeMethod(g_gdb_server, "start", Qt::QueuedConnection,
|
||||
Q_ARG(quint16, g_settings.debugging.gdb_server_port));
|
||||
}
|
||||
else if (g_gdb_server->isListening() && !running)
|
||||
{
|
||||
QMetaObject::invokeMethod(g_gdb_server, "stop", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
m_ui.statusBar->clearMessage();
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "core/fullscreen_ui.h"
|
||||
#include "core/game_database.h"
|
||||
#include "core/game_list.h"
|
||||
#include "core/gdb_server.h"
|
||||
#include "core/gpu.h"
|
||||
#include "core/host.h"
|
||||
#include "core/imgui_overlays.h"
|
||||
@ -81,6 +82,9 @@ static constexpr u32 BACKGROUND_CONTROLLER_POLLING_INTERVAL = 100;
|
||||
/// Poll at half the vsync rate for FSUI to reduce the chance of getting a press+release in the same frame.
|
||||
static constexpr u32 FULLSCREEN_UI_CONTROLLER_POLLING_INTERVAL = 8;
|
||||
|
||||
/// Poll at 1ms when running GDB server. We can get rid of this once we move networking to its own thread.
|
||||
static constexpr u32 GDB_SERVER_POLLING_INTERVAL = 1;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Local function declarations
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -116,8 +120,7 @@ static bool s_start_fullscreen_ui_fullscreen = false;
|
||||
static bool s_run_setup_wizard = false;
|
||||
static bool s_cleanup_after_update = false;
|
||||
|
||||
EmuThread* g_emu_thread;
|
||||
GDBServer* g_gdb_server;
|
||||
EmuThread* g_emu_thread = nullptr;
|
||||
|
||||
EmuThread::EmuThread(QThread* ui_thread) : QThread(), m_ui_thread(ui_thread)
|
||||
{
|
||||
@ -1670,8 +1673,13 @@ void EmuThread::startBackgroundControllerPollTimer()
|
||||
if (m_background_controller_polling_timer->isActive())
|
||||
return;
|
||||
|
||||
m_background_controller_polling_timer->start(
|
||||
FullscreenUI::IsInitialized() ? FULLSCREEN_UI_CONTROLLER_POLLING_INTERVAL : BACKGROUND_CONTROLLER_POLLING_INTERVAL);
|
||||
u32 poll_interval = BACKGROUND_CONTROLLER_POLLING_INTERVAL;
|
||||
if (FullscreenUI::IsInitialized())
|
||||
poll_interval = FULLSCREEN_UI_CONTROLLER_POLLING_INTERVAL;
|
||||
if (GDBServer::HasAnyClients())
|
||||
poll_interval = GDB_SERVER_POLLING_INTERVAL;
|
||||
|
||||
m_background_controller_polling_timer->start(poll_interval);
|
||||
}
|
||||
|
||||
void EmuThread::stopBackgroundControllerPollTimer()
|
||||
@ -1687,8 +1695,6 @@ void EmuThread::start()
|
||||
AssertMsg(!g_emu_thread, "Emu thread does not exist");
|
||||
|
||||
g_emu_thread = new EmuThread(QThread::currentThread());
|
||||
g_gdb_server = new GDBServer();
|
||||
g_gdb_server->moveToThread(g_emu_thread);
|
||||
g_emu_thread->QThread::start();
|
||||
g_emu_thread->m_started_semaphore.acquire();
|
||||
g_emu_thread->moveToThread(g_emu_thread);
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gdbserver.h"
|
||||
#include "qtutils.h"
|
||||
|
||||
#include "core/game_list.h"
|
||||
@ -246,7 +245,6 @@ private:
|
||||
};
|
||||
|
||||
extern EmuThread* g_emu_thread;
|
||||
extern GDBServer* g_gdb_server;
|
||||
|
||||
namespace QtHost {
|
||||
/// Sets batch mode (exit after game shutdown).
|
||||
|
Reference in New Issue
Block a user