Implements UI to start debug (#1015)
Some checks are pending
Development Build / Build (push) Waiting to run
Development Build / Update PRs (push) Waiting to run

This commit is contained in:
Putta Khunchalee 2024-10-05 01:48:26 +07:00 committed by GitHub
parent b97cdfff30
commit 2cac7fbd0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 109 additions and 16 deletions

View File

@ -3,14 +3,19 @@
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QMessageBox>
#include <QPushButton>
#include <QSlider>
CpuSettings::CpuSettings(QWidget *parent) :
QWidget(parent)
QWidget(parent),
m_debugAddr(nullptr)
{
auto layout = new QGridLayout();
layout->addWidget(buildCount(), 0, 0);
layout->addWidget(buildDebug(), 0, 1);
layout->setRowStretch(1, 1);
setLayout(layout);
@ -53,3 +58,50 @@ QWidget *CpuSettings::buildCount()
return group;
}
QWidget *CpuSettings::buildDebug()
{
auto group = new QGroupBox("Debug");
auto layout = new QGridLayout();
// Address label.
auto label = new QLabel("Listen address:");
layout->addWidget(label, 0, 0);
// Address editor.
m_debugAddr = new QLineEdit("127.0.0.1:1234");
label->setBuddy(m_debugAddr);
layout->addWidget(m_debugAddr, 0, 1);
// Start.
auto start = new QPushButton("Start");
connect(start, &QAbstractButton::clicked, [this] {
auto addr = m_debugAddr->text();
if (addr.isEmpty()) {
QMessageBox::critical(this, "Error", "Listen address cannot be empty.");
return;
}
emit debugClicked(addr);
});
layout->addWidget(start, 0, 2);
// Description.
auto desc = new QLabel(
"Specify a TCP address to listen for a debugger. The kernel will wait for a debugger to "
"connect before start.");
desc->setWordWrap(true);
layout->addWidget(desc, 1, 0, 1, -1);
group->setLayout(layout);
return group;
}

View File

@ -2,10 +2,18 @@
#include <QWidget>
class QLineEdit;
class CpuSettings final : public QWidget {
Q_OBJECT
public:
CpuSettings(QWidget *parent = nullptr);
~CpuSettings() override;
signals:
void debugClicked(const QString &addr);
private:
QWidget *buildCount();
QWidget *buildDebug();
QLineEdit *m_debugAddr;
};

View File

@ -94,6 +94,10 @@ QWidget *LaunchSettings::buildSettings(GameListModel *games, QList<VkPhysicalDev
// CPU settings.
m_cpu = new CpuSettings();
connect(m_cpu, &CpuSettings::debugClicked, [this](const QString &addr) {
emit startClicked(addr);
});
tab->addTab(m_cpu, loadIcon(":/resources/cpu-64-bit.svg", iconSize), "CPU");
// Game list.
@ -153,7 +157,7 @@ QLayout *LaunchSettings::buildActions(ProfileList *profiles)
start->setIcon(loadIcon(":/resources/play.svg", start->iconSize()));
connect(start, &QAbstractButton::clicked, [this]() { emit startClicked(); });
connect(start, &QAbstractButton::clicked, [this]() { emit startClicked({}); });
actions->addButton(start, QDialogButtonBox::AcceptRole);

View File

@ -39,7 +39,7 @@ public:
#endif
signals:
void saveClicked(Profile *p);
void startClicked();
void startClicked(const QString &debugAddr);
private:
#ifdef __APPLE__
QWidget *buildSettings(GameListModel *games);

View File

@ -341,7 +341,7 @@ void MainWindow::saveProfile(Profile *p)
}
}
void MainWindow::startKernel()
void MainWindow::startKernel(const QString &debugAddr)
{
// Get full path to kernel binary.
std::string kernel;
@ -387,6 +387,7 @@ void MainWindow::startKernel()
m_main->setCurrentIndex(1);
// Run.
auto debug = debugAddr.toStdString();
VmmScreen screen;
Rust<RustError> error;
Rust<Vmm> vmm;
@ -411,7 +412,7 @@ void MainWindow::startKernel()
kernel.c_str(),
&screen,
m_launch->currentProfile(),
nullptr,
debug.empty() ? nullptr : debug.c_str(),
MainWindow::vmmHandler,
this,
&error);
@ -459,7 +460,7 @@ void MainWindow::waitingDebugger(const QString &addr)
{
QMessageBox::information(
this,
"Action required",
"Debug",
QString("The kernel are waiting for a debugger at %1.").arg(addr));
}

View File

@ -38,7 +38,7 @@ private slots:
void reportIssue();
void aboutObliteration();
void saveProfile(Profile *p);
void startKernel();
void startKernel(const QString &debugAddr);
void updateScreen();
private:
void waitingDebugger(const QString &addr);

View File

@ -20,7 +20,8 @@ use std::ptr::null_mut;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::Sender;
use std::sync::Arc;
use std::thread::JoinHandle;
use std::thread::{sleep, JoinHandle};
use std::time::Duration;
use thiserror::Error;
#[cfg_attr(target_arch = "aarch64", path = "aarch64.rs")]
@ -50,19 +51,32 @@ pub unsafe extern "C" fn vmm_run(
// Setup debug server.
let debug = match debug.is_null() {
true => None,
false => match CStr::from_ptr(debug).to_str() {
Ok(addr) => match TcpListener::bind(addr) {
Ok(v) => Some(v),
false => {
// Get address to listen.
let addr = match CStr::from_ptr(debug).to_str() {
Ok(v) => v,
Err(_) => {
*err = RustError::new("address to listen for a debugger is not UTF-8");
return null_mut();
}
};
// Setup server.
let sock = match TcpListener::bind(addr) {
Ok(v) => v,
Err(e) => {
*err = RustError::with_source("couldn't listen for a debugger", e);
return null_mut();
}
},
Err(_) => {
*err = RustError::new("address to listen for a debugger is not UTF-8");
};
if let Err(e) = sock.set_nonblocking(true) {
*err = RustError::with_source("couldn't enable non-blocking on a debug server", e);
return null_mut();
}
},
Some(sock)
}
};
// Check if path UTF-8.
@ -539,7 +553,21 @@ fn main_cpu<H: Hypervisor>(
}
// Wait for a debugger.
debug.accept().unwrap().0;
loop {
if args.shutdown.load(Ordering::Relaxed) {
return;
}
// Try accept a connection.
let e = match debug.accept() {
Ok(_) => break,
Err(e) => e,
};
assert_eq!(e.kind(), std::io::ErrorKind::WouldBlock);
sleep(Duration::from_secs(1));
}
}
run_cpu(cpu, args);