Skip to content

Commit

Permalink
Add step-in and GUI support for the GDB stub
Browse files Browse the repository at this point in the history
  • Loading branch information
Fanter2033 authored and Luca Bassi committed Nov 13, 2024
1 parent 55e9fbb commit 4f1a1aa
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 14 deletions.
30 changes: 29 additions & 1 deletion src/frontends/qriscv/debug_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <QAction>
#include <QMessageBox>
#include <QTimer>
#include<unistd.h>

#include "qriscv/application.h"
#include "uriscv/error.h"
Expand Down Expand Up @@ -52,6 +53,19 @@ void DebugSession::halt() {
setStatus(MS_HALTED);
}

void DebugSession::killServer(){
if(isGdbEnabled()){
int w = 0;
w = gdb->killServer();
while(w != 1){
//wait till the server correctly shutdown
}
printf("gdb server terminated\n");

gdb->~GDBServer();
}
}

void DebugSession::setSpeed(int value) {
value = qBound(0, value, kMaxSpeed);
if (speed != value) {
Expand All @@ -70,6 +84,10 @@ void DebugSession::setStopMask(unsigned int value) {
machine->setStopMask(stopMask);
}

void DebugSession::setGdbStatus(bool newStatus){
GdbStatus = newStatus;
}

void DebugSession::createActions() {
startMachineAction = new QAction("Power On", this);
startMachineAction->setShortcut(QKeySequence("F5"));
Expand Down Expand Up @@ -174,6 +192,12 @@ void DebugSession::initializeMachine() {

try {
machine.reset(new Machine(config, &breakpoints, &suspects, &tracepoints));
if (isGdbEnabled()) {
gts = std::thread([&]() {
gdb = new GDBServer(machine.get());
gdb->StartServer(); });
gts.detach();
}
} catch (const FileError &e) {
QMessageBox::critical(
Appl()->getApplWindow(),
Expand Down Expand Up @@ -266,6 +290,7 @@ void DebugSession::startMachine() {

void DebugSession::onHaltMachine() {
assert(status != MS_HALTED);
killServer();
halt();
}

Expand All @@ -282,6 +307,9 @@ void DebugSession::onResetMachine() {
stop();

machine.reset();

killServer();

initializeMachine();
if (machine) {
Q_EMIT MachineReset();
Expand Down Expand Up @@ -443,4 +471,4 @@ void DebugSession::relocateStoppoints(const SymbolTable *newTable,
}

set = rset;
}
}
17 changes: 17 additions & 0 deletions src/frontends/qriscv/monitor_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

#include <QtWidgets>

#include "gdb/gdb.h"

#include "uriscv/device.h"
#include "uriscv/error.h"
#include "uriscv/machine.h"
Expand Down Expand Up @@ -173,6 +175,13 @@ void MonitorWindow::createActions() {
removeTraceAction = new QAction("Remove Traced Region", this);
removeTraceAction->setEnabled(false);

//GDB server
enableGDBserver = new QAction("Enable GDB Server", this);
enableGDBserver->setCheckable(true);
enableGDBserver->setChecked(debugSession->isGdbEnabled());
connect(enableGDBserver, SIGNAL(triggered()),this, SLOT(onEnableGDBserver()));
enableGDBserver->setEnabled(true);

speedActionGroup = new QActionGroup(this);
for (int i = 0; i < DebugSession::kNumSpeedLevels; i++) {
simSpeedActions[i] = new QAction(simSpeedMnemonics[i], speedActionGroup);
Expand Down Expand Up @@ -279,6 +288,10 @@ void MonitorWindow::createMenu() {
stopMaskSubMenu->addAction(it->second);
}

debugMenu->addSeparator();
QMenu *gdbMenu = debugMenu->addMenu("GDB Server");
gdbMenu->addAction(enableGDBserver); //power one the server

QMenu *settingsMenu = menuBar()->addMenu("Se&ttings");
QMenu *speedLevelsSubMenu = settingsMenu->addMenu("Simulation Speed");
for (int i = 0; i < DebugSession::kNumSpeedLevels; i++)
Expand Down Expand Up @@ -797,6 +810,10 @@ void MonitorWindow::onAddTracepoint() {
"it overlaps with an already inserted range");
}

void MonitorWindow::onEnableGDBserver(){
dbgSession->setGdbStatus(!dbgSession->isGdbEnabled());
}

StatusDisplay::StatusDisplay(QWidget *parent) : QWidget(parent) {
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
Expand Down
59 changes: 48 additions & 11 deletions src/gdb/gdb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,31 @@ pthread_mutex_t stopped_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t bp_mutex = PTHREAD_MUTEX_INITIALIZER;

GDBServer::GDBServer(Machine *mac) {
this->killed = false;
this->stopped = false;
this->mac = mac;
}

GDBServer::~GDBServer() {
this->mac = NULL;
}

GDBServer *gdb = NULL;
bool *killed_ptr = NULL;

int GDBServer::killServer() {
pthread_mutex_lock(&stopped_mutex);
stopped = true; // stop the machine
pthread_mutex_unlock(&stopped_mutex);

pthread_mutex_lock(&continue_mutex);
killed = true;
pthread_cond_signal(&continue_cond); // wake up the waiting thread
pthread_mutex_unlock(&continue_mutex);

return 1;
}


inline std::string GDBServer::getMsg(const std::string &msg) {
static std::regex reg(R"(.*\$(.*)#.*)");
std::smatch matches;
Expand Down Expand Up @@ -238,6 +258,10 @@ std::string GDBServer::ReadData(const std::string &msg) {
return OKReply;
} else if (body.c_str()[0] == 'c') {

pthread_mutex_lock(&stopped_mutex);
stopped = false;
pthread_mutex_unlock(&stopped_mutex);

pthread_mutex_lock(&continue_mutex);
pthread_cond_signal(&continue_cond);
pthread_mutex_unlock(&continue_mutex);
Expand All @@ -252,6 +276,9 @@ std::string GDBServer::ReadData(const std::string &msg) {
uint addr = parseBreakpoint(body);
addBreakpoint(addr);
return OKReply;
} else if (body.c_str()[0] == 's'){
stepIn();
return OKReply;
} else if (strcmp(body.c_str(), vContMsg) == 0) {
/* Not supported */
return emptyReply;
Expand All @@ -262,22 +289,22 @@ std::string GDBServer::ReadData(const std::string &msg) {

void *MachineStep(void *vargp) {

GDBServer *gdb = (GDBServer *)vargp;

while (true) {

while (!(*killed_ptr)) {
pthread_mutex_lock(&continue_mutex);
pthread_cond_wait(&continue_cond, &continue_mutex);
pthread_cond_wait(&continue_cond, &continue_mutex);
pthread_mutex_unlock(&continue_mutex);

if (*killed_ptr) {
break; // Exit the loop if killed
}
bool s = false;
do {
gdb->Step();

pthread_mutex_lock(&stopped_mutex);
s = gdb->IsStopped();
pthread_mutex_unlock(&stopped_mutex);
} while (!gdb->CheckBreakpoint() && !s);
} while (!(*killed_ptr) && !gdb->CheckBreakpoint() && !s);

if (!s) {
pthread_mutex_lock(&stopped_mutex);
Expand All @@ -297,6 +324,14 @@ void GDBServer::sendMsg(const int &socket, const std::string &msg) {
send(socket, reply.c_str(), (reply).size(), 0);
}

void GDBServer::stepIn(){
gdb->Step();

pthread_mutex_lock(&stopped_mutex);
gdb->Stop();
pthread_mutex_unlock(&stopped_mutex);
}

void GDBServer::StartServer() {
DEBUGMSG("[GDB] Starting GDB Server\n");

Expand All @@ -305,6 +340,7 @@ void GDBServer::StartServer() {
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
this->killed = false;

// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
Expand Down Expand Up @@ -332,7 +368,9 @@ void GDBServer::StartServer() {
exit(EXIT_FAILURE);
}

for (;;) {
gdb = (GDBServer *)(this);

killed_ptr = &killed;

pthread_t tid;

Expand Down Expand Up @@ -381,10 +419,9 @@ void GDBServer::StartServer() {

pthread_kill(tid, SIGTERM);

// closing the connected socket
// clong the connected socket
close(new_socket);
}

// closing the listening socket
shutdown(server_fd, SHUT_RDWR);
}
}
13 changes: 12 additions & 1 deletion src/include/gdb/gdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
//
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef GDB_SERVER_H
#define GDB_SERVER_H

#include "uriscv/machine.h"
#include <cstring>
#include <netinet/in.h>
Expand All @@ -16,6 +19,7 @@
class GDBServer {
public:
GDBServer(Machine *mac);
~GDBServer();
void StartServer();

static std::string GetChecksum(const std::string &msg) {
Expand Down Expand Up @@ -43,8 +47,11 @@ class GDBServer {
inline void Stop() { stopped = true; };
bool IsStopped() const { return stopped; };

int killServer() ;
bool isKilled() { return killed; };

private:
bool killed, stopped;
bool killed = true, stopped;
Machine *mac;
std::vector<uint> breakpoints;

Expand All @@ -61,9 +68,13 @@ class GDBServer {
inline void removeBreakpoint(const uint &addr);

void sendMsg(const int &socket, const std::string &msg);

void stepIn();
};

typedef struct thread_arg_struct {
GDBServer *gdb;
int socket;
} thread_arg_t;

#endif // GDB_SERVER_H
15 changes: 14 additions & 1 deletion src/include/qriscv/debug_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
#define QRISCV_DEBUG_SESSION_H

#include <QObject>
#include <thread>

#include "base/lang.h"
#include "qriscv/cpu_status_map.h"
#include "qriscv/stoppoint_list_model.h"
#include "uriscv/machine.h"
#include "uriscv/stoppoint.h"
#include "uriscv/symbol_table.h"
#include "gdb/gdb.h"

enum MachineStatus { MS_HALTED, MS_RUNNING, MS_STOPPED };

Expand Down Expand Up @@ -40,6 +42,7 @@ class DebugSession : public QObject {
bool isStarted() const { return status != MS_HALTED; }

void halt();
void killServer();

unsigned int getStopMask() const { return stopMask; }
int getSpeed() const { return speed; }
Expand All @@ -66,6 +69,10 @@ class DebugSession : public QObject {
QAction *debugStopAction;
QAction *debugToggleAction;

//GDB stub
void setGdbStatus(bool value);
bool isGdbEnabled() { return GdbStatus; }

public Q_SLOTS:
void setStopMask(unsigned int value);
void setSpeed(int value);
Expand All @@ -90,6 +97,8 @@ public Q_SLOTS:

void initializeMachine();

void initializeThreadServer(MachineConfig*);

void step(unsigned int steps);
void runStepIteration();
void runContIteration();
Expand Down Expand Up @@ -126,6 +135,10 @@ public Q_SLOTS:

uint32_t idleSteps;

bool GdbStatus = false;
std::thread gts;
GDBServer *gdb;

private Q_SLOTS:
void onMachineConfigChanged();

Expand All @@ -143,4 +156,4 @@ private Q_SLOTS:
void skip();
};

#endif // QRISCV_DEBUG_SESSION_H
#endif // QRISCV_DEBUG_SESSION_H
4 changes: 4 additions & 0 deletions src/include/qriscv/monitor_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ class MonitorWindow : public QMainWindow {
QAction *addTraceAction;
QAction *removeTraceAction;

QAction *enableGDBserver;

QActionGroup *speedActionGroup;
QAction *simSpeedActions[DebugSession::kNumSpeedLevels];
static const char *const simSpeedMnemonics[DebugSession::kNumSpeedLevels];
Expand Down Expand Up @@ -159,6 +161,8 @@ private Q_SLOTS:
void onAddSuspect();
void onRemoveSuspect();
void onAddTracepoint();

void onEnableGDBserver();
};

#endif // QRISCV_MONITOR_WINDOW_H

0 comments on commit 4f1a1aa

Please sign in to comment.