can handle signal

This commit is contained in:
Roy Qu 2021-11-25 09:05:45 +08:00
parent 73c88065f8
commit af1bc5f538
11 changed files with 263 additions and 67 deletions

View File

@ -135,7 +135,8 @@ SOURCES += \
widgets/qconsole.cpp \ widgets/qconsole.cpp \
widgets/qpatchedcombobox.cpp \ widgets/qpatchedcombobox.cpp \
widgets/searchdialog.cpp \ widgets/searchdialog.cpp \
widgets/searchresultview.cpp widgets/searchresultview.cpp \
widgets/signalmessagedialog.cpp
HEADERS += \ HEADERS += \
ConvertUTF.h \ ConvertUTF.h \
@ -260,7 +261,8 @@ HEADERS += \
widgets/qconsole.h \ widgets/qconsole.h \
widgets/qpatchedcombobox.h \ widgets/qpatchedcombobox.h \
widgets/searchdialog.h \ widgets/searchdialog.h \
widgets/searchresultview.h widgets/searchresultview.h \
widgets/signalmessagedialog.h
FORMS += \ FORMS += \
settingsdialog/compilerautolinkwidget.ui \ settingsdialog/compilerautolinkwidget.ui \
@ -305,7 +307,8 @@ FORMS += \
widgets/filepropertiesdialog.ui \ widgets/filepropertiesdialog.ui \
widgets/newprojectdialog.ui \ widgets/newprojectdialog.ui \
widgets/ojproblempropertywidget.ui \ widgets/ojproblempropertywidget.ui \
widgets/searchdialog.ui widgets/searchdialog.ui \
widgets/signalmessagedialog.ui
TRANSLATIONS += \ TRANSLATIONS += \
RedPandaIDE_zh_CN.ts RedPandaIDE_zh_CN.ts

View File

@ -15,6 +15,7 @@
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include "widgets/signalmessagedialog.h"
Debugger::Debugger(QObject *parent) : QObject(parent) Debugger::Debugger(QObject *parent) : QObject(parent)
{ {
@ -77,6 +78,10 @@ bool Debugger::start()
&Debugger::updateEval); &Debugger::updateEval);
connect(mReader, &DebugReader::disassemblyUpdate,this, connect(mReader, &DebugReader::disassemblyUpdate,this,
&Debugger::updateDisassembly); &Debugger::updateDisassembly);
connect(mReader, &DebugReader::registerNamesUpdated, this,
&Debugger::updateRegisterNames);
connect(mReader, &DebugReader::registerValuesUpdated, this,
&Debugger::updateRegisterValues);
connect(mReader, &DebugReader::inferiorContinued,pMainWindow, connect(mReader, &DebugReader::inferiorContinued,pMainWindow,
&MainWindow::removeActiveBreakpoints); &MainWindow::removeActiveBreakpoints);
connect(mReader, &DebugReader::inferiorStopped,pMainWindow, connect(mReader, &DebugReader::inferiorStopped,pMainWindow,
@ -133,6 +138,16 @@ void Debugger::clearUpReader()
} }
} }
void Debugger::updateRegisterNames(const QStringList &registerNames)
{
mRegisterModel->updateNames(registerNames);
}
void Debugger::updateRegisterValues(const QHash<int, QString> &values)
{
mRegisterModel->updateValues(values);
}
RegisterModel *Debugger::registerModel() const RegisterModel *Debugger::registerModel() const
{ {
return mRegisterModel; return mRegisterModel;
@ -489,31 +504,16 @@ void Debugger::syncFinishedParsing()
return; return;
} }
// Some part of the CPU form has been updated
if (pMainWindow->cpuDialog()!=nullptr && !mReader->signalReceived()) {
// if (mReader->doregistersready) {
// mRegisterModel->update(mReader->mRegisters);
// mReader->mRegisters.clear();
// mReader->doregistersready = false;
// }
// if (mReader->dodisassemblerready) {
// pMainWindow->cpuDialog()->setDisassembly(mReader->mDisassembly);
// mReader->mDisassembly.clear();
// mReader->dodisassemblerready = false;
// }
}
// if (mReader->updateExecution()) {
// if (mReader->currentCmd() && mReader->currentCmd()->source == DebugCommandSource::Console) {
// pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine(),false);
// } else {
// pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine());
// }
// refreshWatchVars(); // update variable information
// }
if (mReader->signalReceived()) { if (mReader->signalReceived()) {
SignalMessageDialog dialog(pMainWindow);
dialog.setMessage(
tr("Signal \"%1\" Received: ").arg(mReader->signalName())
+ "<br />"
+ mReader->signalMeaning());
int result = dialog.exec();
if (result == QDialog::Accepted && dialog.openCPUInfo()) {
pMainWindow->showCPUInfoDialog();
}
//SignalDialog := CreateMessageDialog(fSignal, mtError, [mbOk]); //SignalDialog := CreateMessageDialog(fSignal, mtError, [mbOk]);
//SignalCheck := TCheckBox.Create(SignalDialog); //SignalCheck := TCheckBox.Create(SignalDialog);
@ -595,7 +595,6 @@ DebugReader::DebugReader(Debugger* debugger, QObject *parent) : QThread(parent),
{ {
mDebugger = debugger; mDebugger = debugger;
mProcess = nullptr; mProcess = nullptr;
mUseUTF8 = false;
mCmdRunning = false; mCmdRunning = false;
mInvalidateAllVars = false; mInvalidateAllVars = false;
} }
@ -744,6 +743,12 @@ void DebugReader::processResult(const QByteArray &result)
case GDBMIResultType::Memory: case GDBMIResultType::Memory:
handleMemory(multiValues["memory"].array()); handleMemory(multiValues["memory"].array());
return; return;
case GDBMIResultType::RegisterNames:
handleRegisterNames(multiValues["register-names"].array());
return;
case GDBMIResultType::RegisterValues:
handleRegisterValue(multiValues["register-values"].array());
return;
} }
} }
@ -794,6 +799,8 @@ void DebugReader::processExecAsyncRecord(const QByteArray &line)
} }
if (reason == "signal-received") { if (reason == "signal-received") {
mSignalReceived = true; mSignalReceived = true;
mSignalName = multiValues["signal-name"].value();
mSignalMeaning = multiValues["signal-meaning"].value();
} }
runInferiorStoppedHook(); runInferiorStoppedHook();
if (mCurrentCmd && mCurrentCmd->source == DebugCommandSource::Console) if (mCurrentCmd && mCurrentCmd->source == DebugCommandSource::Console)
@ -1284,6 +1291,33 @@ void DebugReader::handleMemory(const QList<GDBMIResultParser::ParseValue> &rows)
emit memoryUpdated(memory); emit memoryUpdated(memory);
} }
void DebugReader::handleRegisterNames(const QList<GDBMIResultParser::ParseValue> &names)
{
QStringList nameList;
foreach (const GDBMIResultParser::ParseValue& nameValue, names) {
nameList.append(nameValue.value());
}
emit registerNamesUpdated(nameList);
}
void DebugReader::handleRegisterValue(const QList<GDBMIResultParser::ParseValue> &values)
{
QHash<int,QString> result;
foreach (const GDBMIResultParser::ParseValue& val, values) {
GDBMIResultParser::ParseObject obj = val.object();
int number = obj["number"].intValue();
QString value = obj["value"].value();
bool ok;
long long intVal;
intVal = value.toLongLong(&ok,10);
if (ok) {
value = QString("0x%1").arg(intVal,0,16);
}
result.insert(number,value);
}
emit registerValuesUpdated(result);
}
QByteArray DebugReader::removeToken(const QByteArray &line) QByteArray DebugReader::removeToken(const QByteArray &line)
{ {
int p=0; int p=0;
@ -1299,6 +1333,16 @@ QByteArray DebugReader::removeToken(const QByteArray &line)
return line; return line;
} }
const QString &DebugReader::signalMeaning() const
{
return mSignalMeaning;
}
const QString &DebugReader::signalName() const
{
return mSignalName;
}
bool DebugReader::inferiorRunning() const bool DebugReader::inferiorRunning() const
{ {
return mInferiorRunning; return mInferiorRunning;
@ -2042,32 +2086,27 @@ RegisterModel::RegisterModel(QObject *parent):QAbstractTableModel(parent)
int RegisterModel::rowCount(const QModelIndex &) const int RegisterModel::rowCount(const QModelIndex &) const
{ {
return mRegisters.count(); return mRegisterNames.count();
} }
int RegisterModel::columnCount(const QModelIndex &) const int RegisterModel::columnCount(const QModelIndex &) const
{ {
return 3; return 2;
} }
QVariant RegisterModel::data(const QModelIndex &index, int role) const QVariant RegisterModel::data(const QModelIndex &index, int role) const
{ {
if (!index.isValid()) if (!index.isValid())
return QVariant(); return QVariant();
if (index.row()<0 || index.row() >= static_cast<int>(mRegisters.size())) if (index.row()<0 || index.row() >= static_cast<int>(mRegisterNames.size()))
return QVariant();
PRegister reg = mRegisters[index.row()];
if (!reg)
return QVariant(); return QVariant();
switch (role) { switch (role) {
case Qt::DisplayRole: case Qt::DisplayRole:
switch (index.column()) { switch (index.column()) {
case 0: case 0:
return reg->name; return mRegisterNames[index.row()];
case 1: case 1:
return reg->hexValue; return mRegisterValues.value(index.row(),"");
case 2:
return reg->decValue;
default: default:
return QVariant(); return QVariant();
} }
@ -2083,26 +2122,31 @@ QVariant RegisterModel::headerData(int section, Qt::Orientation orientation, int
case 0: case 0:
return tr("Register"); return tr("Register");
case 1: case 1:
return tr("Value(Hex)"); return tr("Value");
case 2:
return tr("Value(Dec)");
} }
} }
return QVariant(); return QVariant();
} }
void RegisterModel::update(const QList<PRegister> &regs) void RegisterModel::updateNames(const QStringList &regNames)
{ {
beginResetModel(); beginResetModel();
mRegisters.clear(); mRegisterNames = regNames;
mRegisters.append(regs);
endResetModel(); endResetModel();
} }
void RegisterModel::updateValues(const QHash<int, QString> registerValues)
{
mRegisterValues= registerValues;
emit dataChanged(createIndex(0,1),
createIndex(mRegisterNames.count()-1,1));
}
void RegisterModel::clear() void RegisterModel::clear()
{ {
beginResetModel(); beginResetModel();
mRegisters.clear(); mRegisterNames.clear();
mRegisterValues.clear();
endResetModel(); endResetModel();
} }

View File

@ -60,14 +60,6 @@ struct Trace {
using PTrace = std::shared_ptr<Trace>; using PTrace = std::shared_ptr<Trace>;
struct Register {
QString name;
QString hexValue;
QString decValue;
};
using PRegister = std::shared_ptr<Register>;
class RegisterModel: public QAbstractTableModel { class RegisterModel: public QAbstractTableModel {
Q_OBJECT Q_OBJECT
public: public:
@ -76,10 +68,12 @@ public:
int columnCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
void update(const QList<PRegister>& regs); void updateNames(const QStringList& regNames);
void updateValues(const QHash<int,QString> registerValues);
void clear(); void clear();
private: private:
QList<PRegister> mRegisters; QStringList mRegisterNames;
QHash<int,QString> mRegisterValues;
}; };
class BreakpointModel: public QAbstractTableModel { class BreakpointModel: public QAbstractTableModel {
@ -246,6 +240,8 @@ private slots:
void updateDisassembly(const QString& file, const QString& func,const QStringList& value); void updateDisassembly(const QString& file, const QString& func,const QStringList& value);
void onChangeDebugConsoleLastline(const QString& text); void onChangeDebugConsoleLastline(const QString& text);
void clearUpReader(); void clearUpReader();
void updateRegisterNames(const QStringList& registerNames);
void updateRegisterValues(const QHash<int,QString>& values);
private: private:
bool mExecuting; bool mExecuting;
@ -310,6 +306,10 @@ public:
bool inferiorRunning() const; bool inferiorRunning() const;
const QString &signalName() const;
const QString &signalMeaning() const;
signals: signals:
void parseStarted(); void parseStarted();
void invalidateAllVars(); void invalidateAllVars();
@ -327,6 +327,8 @@ signals:
void evalUpdated(const QString& value); void evalUpdated(const QString& value);
void memoryUpdated(const QStringList& memoryValues); void memoryUpdated(const QStringList& memoryValues);
void disassemblyUpdate(const QString& filename, const QString& funcName, const QStringList& result); void disassemblyUpdate(const QString& filename, const QString& funcName, const QStringList& result);
void registerNamesUpdated(const QStringList& registerNames);
void registerValuesUpdated(const QHash<int,QString>& values);
private: private:
void clearCmdQueue(); void clearCmdQueue();
@ -341,6 +343,8 @@ private:
void handleLocalVariables(const QList<GDBMIResultParser::ParseValue> & variables); void handleLocalVariables(const QList<GDBMIResultParser::ParseValue> & variables);
void handleEvaluation(const QString& value); void handleEvaluation(const QString& value);
void handleMemory(const QList<GDBMIResultParser::ParseValue> & rows); void handleMemory(const QList<GDBMIResultParser::ParseValue> & rows);
void handleRegisterNames(const QList<GDBMIResultParser::ParseValue> & names);
void handleRegisterValue(const QList<GDBMIResultParser::ParseValue> & values);
void processConsoleOutput(const QByteArray& line); void processConsoleOutput(const QByteArray& line);
void processResult(const QByteArray& result); void processResult(const QByteArray& result);
void processExecAsyncRecord(const QByteArray& line); void processExecAsyncRecord(const QByteArray& line);
@ -360,15 +364,12 @@ private:
//fOnInvalidateAllVars: TInvalidateAllVarsEvent; //fOnInvalidateAllVars: TInvalidateAllVarsEvent;
bool mCmdRunning; bool mCmdRunning;
PDebugCommand mCurrentCmd; PDebugCommand mCurrentCmd;
QList<PRegister> mRegisters;
QStringList mDisassembly;
QProcess* mProcess; QProcess* mProcess;
//fWatchView: TTreeView; //fWatchView: TTreeView;
QString mSignal; QString mSignalName;
bool mUseUTF8; QString mSignalMeaning;
// //
QList<PDebugCommand> mInferiorStoppedHookCommands; QList<PDebugCommand> mInferiorStoppedHookCommands;

View File

@ -16,6 +16,8 @@ GDBMIResultParser::GDBMIResultParser()
// mResultTypes.insert("register-names",GDBMIResultType::RegisterNames); // mResultTypes.insert("register-names",GDBMIResultType::RegisterNames);
// mResultTypes.insert("register-values",GDBMIResultType::RegisterValues); // mResultTypes.insert("register-values",GDBMIResultType::RegisterValues);
mResultTypes.insert("-data-read-memory",GDBMIResultType::Memory); mResultTypes.insert("-data-read-memory",GDBMIResultType::Memory);
mResultTypes.insert("-data-list-register-names",GDBMIResultType::RegisterNames);
mResultTypes.insert("-data-list-register-values",GDBMIResultType::RegisterValues);
} }
bool GDBMIResultParser::parse(const QByteArray &record, const QString& command, GDBMIResultType &type, ParseObject& multiValues) bool GDBMIResultParser::parse(const QByteArray &record, const QString& command, GDBMIResultType &type, ParseObject& multiValues)

View File

@ -103,6 +103,7 @@ int main(int argc, char *argv[])
qRegisterMetaType<PCompileIssue>("PCompileIssue"); qRegisterMetaType<PCompileIssue>("PCompileIssue");
qRegisterMetaType<PCompileIssue>("PCompileIssue&"); qRegisterMetaType<PCompileIssue>("PCompileIssue&");
qRegisterMetaType<QVector<int>>("QVector<int>"); qRegisterMetaType<QVector<int>>("QVector<int>");
qRegisterMetaType<QHash<int,QString>>("QHash<int,QString>");
initParser(); initParser();

View File

@ -1432,6 +1432,7 @@ void MainWindow::debug()
mDebugger->sendAllBreakpointsToDebugger(); mDebugger->sendAllBreakpointsToDebugger();
// Run the debugger // Run the debugger
mDebugger->sendCommand("-data-list-register-names","");
mDebugger->sendCommand("-gdb-set", "width 0"); // don't wrap output, very annoying mDebugger->sendCommand("-gdb-set", "width 0"); // don't wrap output, very annoying
mDebugger->sendCommand("-gdb-set", "new-console on"); mDebugger->sendCommand("-gdb-set", "new-console on");
mDebugger->sendCommand("-gdb-set", "confirm off"); mDebugger->sendCommand("-gdb-set", "confirm off");
@ -1474,6 +1475,15 @@ void MainWindow::showSearchPanel(bool showReplace)
ui->tabMessages->setCurrentWidget(ui->tabSearch); ui->tabMessages->setCurrentWidget(ui->tabSearch);
} }
void MainWindow::showCPUInfoDialog()
{
if (mCPUDialog==nullptr) {
mCPUDialog = new CPUDialog(this);
connect(mCPUDialog, &CPUDialog::closed, this, &MainWindow::cleanUpCPUDialog);
}
mCPUDialog->show();
}
void MainWindow::openCloseBottomPanel(bool open) void MainWindow::openCloseBottomPanel(bool open)
{ {
// if Assigned(fReportToolWindow) then // if Assigned(fReportToolWindow) then
@ -4048,11 +4058,7 @@ void MainWindow::on_actionAdd_Watch_triggered()
void MainWindow::on_actionView_CPU_Window_triggered() void MainWindow::on_actionView_CPU_Window_triggered()
{ {
if (mCPUDialog==nullptr) { showCPUInfoDialog();
mCPUDialog = new CPUDialog(this);
connect(mCPUDialog, &CPUDialog::closed, this, &MainWindow::cleanUpCPUDialog);
}
mCPUDialog->show();
} }
void MainWindow::on_actionExit_triggered() void MainWindow::on_actionExit_triggered()

View File

@ -95,6 +95,7 @@ public:
void runExecutable(RunType runType = RunType::Normal); void runExecutable(RunType runType = RunType::Normal);
void debug(); void debug();
void showSearchPanel(bool showReplace = false); void showSearchPanel(bool showReplace = false);
void showCPUInfoDialog();
void applySettings(); void applySettings();
void applyUISettings(); void applyUISettings();

View File

@ -57,7 +57,7 @@ void CPUDialog::updateInfo()
if (pMainWindow->debugger()->executing()) { if (pMainWindow->debugger()->executing()) {
// Load the registers.. // Load the registers..
sendSyntaxCommand(); sendSyntaxCommand();
//pMainWindow->debugger()->sendCommand("info", "registers"); pMainWindow->debugger()->sendCommand("-data-list-register-values", "N");
if (ui->chkBlendMode->isChecked()) if (ui->chkBlendMode->isChecked())
pMainWindow->debugger()->sendCommand("disas", "/s"); pMainWindow->debugger()->sendCommand("disas", "/s");
else else
@ -78,7 +78,7 @@ void CPUDialog::setDisassembly(const QString& file, const QString& funcName,cons
ui->txtCode->lines()->add(line); ui->txtCode->lines()->add(line);
} }
if (activeLine!=-1) if (activeLine!=-1)
ui->txtCode->setCaretXY(BufferCoord{1,activeLine}); ui->txtCode->setCaretXYCentered(true,BufferCoord{1,activeLine});
} }
void CPUDialog::sendSyntaxCommand() void CPUDialog::sendSyntaxCommand()

View File

@ -0,0 +1,24 @@
#include "signalmessagedialog.h"
#include "ui_signalmessagedialog.h"
SignalMessageDialog::SignalMessageDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SignalMessageDialog)
{
ui->setupUi(this);
}
SignalMessageDialog::~SignalMessageDialog()
{
delete ui;
}
void SignalMessageDialog::setMessage(const QString &message)
{
ui->lblMessage->setText(message);
}
bool SignalMessageDialog::openCPUInfo()
{
return ui->chkOpenCPUInfo->isChecked();
}

View File

@ -0,0 +1,24 @@
#ifndef SIGNALMESSAGEDIALOG_H
#define SIGNALMESSAGEDIALOG_H
#include <QDialog>
namespace Ui {
class SignalMessageDialog;
}
class SignalMessageDialog : public QDialog
{
Q_OBJECT
public:
explicit SignalMessageDialog(QWidget *parent = nullptr);
~SignalMessageDialog();
void setMessage(const QString& message);
bool openCPUInfo();
private:
Ui::SignalMessageDialog *ui;
};
#endif // SIGNALMESSAGEDIALOG_H

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SignalMessageDialog</class>
<widget class="QDialog" name="SignalMessageDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>240</height>
</rect>
</property>
<property name="windowTitle">
<string>Signal Received</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="lblMessage">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkOpenCPUInfo">
<property name="text">
<string>Open CPU Info Dialog</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SignalMessageDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SignalMessageDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>