mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-20 17:05:41 -04:00
Qt: Implement GDB server
This commit is contained in:

committed by
Connor McLaughlin

parent
abd2399aaf
commit
7dcacc2cda
82
src/duckstation-qt/gdbconnection.cpp
Normal file
82
src/duckstation-qt/gdbconnection.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include "gdbconnection.h"
|
||||
#include "qthostinterface.h"
|
||||
#include "common/log.h"
|
||||
#include "core/gdb_protocol.h"
|
||||
Log_SetChannel(GDBConnection);
|
||||
|
||||
GDBConnection::GDBConnection(QObject *parent, int descriptor)
|
||||
: QThread(parent), m_descriptor(descriptor)
|
||||
{
|
||||
Log_InfoPrintf("(%u) Accepted new connection on GDB server", m_descriptor);
|
||||
|
||||
connect(&m_socket, &QTcpSocket::readyRead, this, &GDBConnection::receivedData);
|
||||
connect(&m_socket, &QTcpSocket::disconnected, this, &GDBConnection::gotDisconnected);
|
||||
|
||||
if (m_socket.setSocketDescriptor(m_descriptor)) {
|
||||
QtHostInterface::GetInstance()->pauseSystem(true, true);
|
||||
}
|
||||
else {
|
||||
Log_ErrorPrintf("(%u) Failed to set socket descriptor: %s", m_descriptor, m_socket.errorString().toUtf8().constData());
|
||||
}
|
||||
}
|
||||
|
||||
void GDBConnection::gotDisconnected()
|
||||
{
|
||||
Log_InfoPrintf("(%u) Client disconnected", m_descriptor);
|
||||
this->exit(0);
|
||||
}
|
||||
|
||||
void GDBConnection::receivedData()
|
||||
{
|
||||
qint64 bytesRead;
|
||||
char buffer[256];
|
||||
|
||||
while ((bytesRead = m_socket.read(buffer, sizeof(buffer))) > 0) {
|
||||
for (char c : std::string_view(buffer, bytesRead)) {
|
||||
m_readBuffer.push_back(c);
|
||||
|
||||
if (GDBProtocol::IsPacketInterrupt(m_readBuffer)) {
|
||||
Log_DebugPrintf("(%u) > Interrupt request", m_descriptor);
|
||||
QtHostInterface::GetInstance()->pauseSystem(true, true);
|
||||
m_readBuffer.erase();
|
||||
}
|
||||
else if (GDBProtocol::IsPacketContinue(m_readBuffer)) {
|
||||
Log_DebugPrintf("(%u) > Continue request", m_descriptor);
|
||||
QtHostInterface::GetInstance()->pauseSystem(false, false);
|
||||
m_readBuffer.erase();
|
||||
}
|
||||
else if (GDBProtocol::IsPacketComplete(m_readBuffer)) {
|
||||
Log_DebugPrintf("(%u) > %s", m_descriptor, m_readBuffer.c_str());
|
||||
writePacket(GDBProtocol::ProcessPacket(m_readBuffer));
|
||||
m_readBuffer.erase();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bytesRead == -1) {
|
||||
Log_ErrorPrintf("(%u) Failed to read from socket: %s", m_descriptor, m_socket.errorString().toUtf8().constData());
|
||||
}
|
||||
}
|
||||
|
||||
void GDBConnection::onEmulationPaused(bool paused)
|
||||
{
|
||||
if (paused) {
|
||||
if (m_seen_resume) {
|
||||
m_seen_resume = false;
|
||||
// Generate a stop reply packet, insert '?' command to generate it.
|
||||
writePacket(GDBProtocol::ProcessPacket("$?#3f"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_seen_resume = true;
|
||||
// Send ack, in case GDB sent a continue request.
|
||||
writePacket("+");
|
||||
}
|
||||
}
|
||||
|
||||
void GDBConnection::writePacket(std::string_view packet)
|
||||
{
|
||||
Log_DebugPrintf("(%u) < %*s", m_descriptor, packet.length(), packet.data());
|
||||
if (m_socket.write(packet.data(), packet.length()) == -1) {
|
||||
Log_ErrorPrintf("(%u) Failed to write to socket: %s", m_descriptor, m_socket.errorString().toUtf8().constData());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user