- enhancement: Add "Close window" and "Move to other view" in the "Window" menu

- enhancement: Auto open CPU info dialog, if the program in debug is stopped at a position that have no source file.
  - enhancement: "add watchpoint" when debug. It's hitted when the watch variable is modified, or it's out of scope.
  - enhancement: Switch current call stack frame in the CPU info dialog
  - fix: Shouldn't try evaluate value of the selection in the cpu info dialog.
  - enhancement: Show oct/bin/bin value in the memory view's tooltip.
  - Don't set optimization level to -Og in the Debug compiler set. (Some variable can't be view in the memory view, because they are put in registers.)
This commit is contained in:
Roy Qu 2023-03-03 17:20:33 +08:00
parent eac1077de1
commit da3dda97e3
16 changed files with 1303 additions and 965 deletions

View File

@ -7,7 +7,6 @@ Red Panda C++ Version 2.16
- enhancement: Add cfi directives for asm syntaxer in linux. - enhancement: Add cfi directives for asm syntaxer in linux.
- change: Editor option "Scroll past end of line" default to false. - change: Editor option "Scroll past end of line" default to false.
- emhancement: Improve display of disassembled codes in the cpu info dialog. - emhancement: Improve display of disassembled codes in the cpu info dialog.
- change: Set optimization level to -Og for Debug compiler settings by default.
- fix: Can't correctly parse function pointer var definition. - fix: Can't correctly parse function pointer var definition.
- enhancement: Improve support for function pointer typedefs. - enhancement: Improve support for function pointer typedefs.
- enhancement: Improve support for function pointer vars. - enhancement: Improve support for function pointer vars.
@ -15,6 +14,11 @@ Red Panda C++ Version 2.16
- change: Don't rebuild the whole project when run/debug, if only contents of project unit file is modified. - change: Don't rebuild the whole project when run/debug, if only contents of project unit file is modified.
- fix: rebuild may not work, if project's parallel build option is enabled. - fix: rebuild may not work, if project's parallel build option is enabled.
- enhancement: Add "Close window" and "Move to other view" in the "Window" menu - enhancement: Add "Close window" and "Move to other view" in the "Window" menu
- enhancement: Auto open CPU info dialog, if the program in debug is stopped at a position that have no source file.
- enhancement: "add watchpoint" when debug. It's hitted when the watch variable is modified, or it's out of scope.
- enhancement: Switch current call stack frame in the CPU info dialog
- fix: Shouldn't try evaluate value of the selection in the cpu info dialog.
- enhancement: Show oct/bin/bin value in the memory view's tooltip.
Red Panda C++ Version 2.15 Red Panda C++ Version 2.15

View File

@ -194,6 +194,8 @@ bool Debugger::start(int compilerSetIndex, const QString& inferior, const QStrin
&MainWindow::removeActiveBreakpoints); &MainWindow::removeActiveBreakpoints);
connect(mReader, &DebugReader::inferiorStopped,pMainWindow, connect(mReader, &DebugReader::inferiorStopped,pMainWindow,
&MainWindow::setActiveBreakpoint); &MainWindow::setActiveBreakpoint);
connect(mReader, &DebugReader::watchpointHitted,pMainWindow,
&MainWindow::onWatchpointHitted);
connect(mReader, &DebugReader::errorNoSymbolTable,pMainWindow, connect(mReader, &DebugReader::errorNoSymbolTable,pMainWindow,
&MainWindow::stopDebugForNoSymbolTable); &MainWindow::stopDebugForNoSymbolTable);
connect(mReader, &DebugReader::inferiorStopped,this, connect(mReader, &DebugReader::inferiorStopped,this,
@ -485,6 +487,14 @@ void Debugger::loadForProject(const QString &filename, const QString &projectFol
} }
} }
void Debugger::addWatchpoint(const QString &expression)
{
QString s=expression.trimmed();
if (!s.isEmpty()) {
sendCommand("-break-watch",s,DebugCommandSource::Other);
}
}
void Debugger::addWatchVar(const QString &expression) void Debugger::addWatchVar(const QString &expression)
{ {
// Don't allow duplicates... // Don't allow duplicates...
@ -923,7 +933,7 @@ void Debugger::updateEval(const QString &value)
void Debugger::updateDisassembly(const QString& file, const QString& func, const QStringList &value) void Debugger::updateDisassembly(const QString& file, const QString& func, const QStringList &value)
{ {
if (pMainWindow->cpuDialog()) { if (pMainWindow->cpuDialog()) {
pMainWindow->cpuDialog()->setDisassembly(file,func,value); pMainWindow->cpuDialog()->setDisassembly(file,func,value,mBacktraceModel->backtraces());
} }
} }
@ -1088,12 +1098,14 @@ void DebugReader::processResult(const QByteArray &result)
return; return;
switch(resultType) { switch(resultType) {
case GDBMIResultType::BreakpointTable: case GDBMIResultType::BreakpointTable:
case GDBMIResultType::Frame:
case GDBMIResultType::Locals: case GDBMIResultType::Locals:
break; break;
case GDBMIResultType::Breakpoint: case GDBMIResultType::Breakpoint:
handleBreakpoint(multiValues["bkpt"].object()); handleBreakpoint(multiValues["bkpt"].object());
return; return;
case GDBMIResultType::Frame:
handleFrame(multiValues["frame"]);
return;
case GDBMIResultType::FrameStack: case GDBMIResultType::FrameStack:
handleStack(multiValues["stack"].array()); handleStack(multiValues["stack"].array());
return; return;
@ -1163,27 +1175,33 @@ void DebugReader::processExecAsyncRecord(const QByteArray &line)
return; return;
} }
mUpdateCPUInfo = true; mUpdateCPUInfo = true;
GDBMIResultParser::ParseValue frame(multiValues["frame"]); handleFrame(multiValues["frame"]);
if (frame.isValid()) {
GDBMIResultParser::ParseObject frameObj = frame.object();
mCurrentAddress = frameObj["addr"].hexValue();
mCurrentLine = frameObj["line"].intValue();
if (mDebugger->forceUTF8())
mCurrentFile = frameObj["fullname"].utf8PathValue();
else
mCurrentFile = frameObj["fullname"].pathValue();
mCurrentFunc = frameObj["func"].value();
}
if (reason == "signal-received") { if (reason == "signal-received") {
mSignalReceived = true; mSignalReceived = true;
mSignalName = multiValues["signal-name"].value(); mSignalName = multiValues["signal-name"].value();
mSignalMeaning = multiValues["signal-meaning"].value(); mSignalMeaning = multiValues["signal-meaning"].value();
} else if (reason == "watchpoint-trigger") {
QString var,oldVal,newVal;
GDBMIResultParser::ParseValue wpt=multiValues["wpt"];
if (wpt.isValid()) {
GDBMIResultParser::ParseObject wptObj = wpt.object();
var=wptObj["exp"].value();
}
GDBMIResultParser::ParseValue varValue=multiValues["value"];
if (varValue.isValid()) {
GDBMIResultParser::ParseObject valueObj = varValue.object();
oldVal=valueObj["old"].value();
newVal=valueObj["new"].value();
}
if (!var.isEmpty()) {
emit watchpointHitted(var,oldVal,newVal);
}
} }
runInferiorStoppedHook(); runInferiorStoppedHook();
if (mCurrentCmd && mCurrentCmd->source == DebugCommandSource::Console) if (mCurrentCmd && mCurrentCmd->source == DebugCommandSource::Console)
emit inferiorStopped(mCurrentFile, mCurrentLine,false); emit inferiorStopped(mCurrentFile, mCurrentLine, false);
else else
emit inferiorStopped(mCurrentFile, mCurrentLine,true); emit inferiorStopped(mCurrentFile, mCurrentLine, true);
} }
} }
@ -1466,6 +1484,23 @@ void DebugReader::handleBreakpoint(const GDBMIResultParser::ParseObject& breakpo
emit breakpointInfoGetted(filename, line , number); emit breakpointInfoGetted(filename, line , number);
} }
void DebugReader::handleFrame(const GDBMIResultParser::ParseValue &frame)
{
if (frame.isValid()) {
GDBMIResultParser::ParseObject frameObj = frame.object();
bool ok;
mCurrentAddress = frameObj["addr"].hexValue(ok);
if (!ok)
mCurrentAddress=0;
mCurrentLine = frameObj["line"].intValue();
if (mDebugger->forceUTF8())
mCurrentFile = frameObj["fullname"].utf8PathValue();
else
mCurrentFile = frameObj["fullname"].pathValue();
mCurrentFunc = frameObj["func"].value();
}
}
void DebugReader::handleStack(const QList<GDBMIResultParser::ParseValue> & stack) void DebugReader::handleStack(const QList<GDBMIResultParser::ParseValue> & stack)
{ {
mDebugger->backtraceModel()->clear(); mDebugger->backtraceModel()->clear();
@ -3113,6 +3148,31 @@ QVariant MemoryModel::data(const QModelIndex &index, int role) const
return s; return s;
} else } else
return QString("%1").arg(line->datas[col],2,16,QChar('0')); return QString("%1").arg(line->datas[col],2,16,QChar('0'));
} else if (role == Qt::ToolTipRole) {
if (col<line->datas.count()) {
QString s =tr("dec: %1").arg(line->datas[col])
+"<br/>"
+tr("hex: %1").arg(line->datas[col],2,16,QChar('0'))
+"<br/>"
+tr("bin: %1").arg(line->datas[col],8,2,QChar('0'))
+"<br/>";
QString chVal;
if (line->datas[col]==0) {
chVal="\\0";
} else if (line->datas[col]=='\n') {
chVal="\\n";
} else if (line->datas[col]=='\t') {
chVal="\\t";
} else if (line->datas[col]=='\r') {
chVal="\\r";
} else if (line->datas[col]>'\n' && line->datas[col]<127) {
chVal=QChar(line->datas[col]);
}
if (!chVal.isEmpty()) {
s+=tr("ascii: \'%1\'").arg(chVal);
}
return s;
}
} }
return QVariant(); return QVariant();
} }

View File

@ -340,6 +340,7 @@ public:
void loadForNonproject(const QString &filename); void loadForNonproject(const QString &filename);
void loadForProject(const QString& filename, const QString& projectFolder); void loadForProject(const QString& filename, const QString& projectFolder);
void addWatchpoint(const QString& expression);
//watch vars //watch vars
void addWatchVar(const QString& expression); void addWatchVar(const QString& expression);
void modifyWatchVarExpression(const QString& oldExpr, const QString& newExpr); void modifyWatchVarExpression(const QString& oldExpr, const QString& newExpr);
@ -522,6 +523,7 @@ signals:
void errorNoSymbolTable(); void errorNoSymbolTable();
void breakpointInfoGetted(const QString& filename, int line, int number); void breakpointInfoGetted(const QString& filename, int line, int number);
void inferiorContinued(); void inferiorContinued();
void watchpointHitted(const QString& var, const QString& oldVal, const QString& newVal);
void inferiorStopped(const QString& filename, int line, bool setFocus); void inferiorStopped(const QString& filename, int line, bool setFocus);
void localsUpdated(const QStringList& localsValue); void localsUpdated(const QStringList& localsValue);
void evalUpdated(const QString& value); void evalUpdated(const QString& value);
@ -554,6 +556,7 @@ private:
bool outputTerminated(const QByteArray& text); bool outputTerminated(const QByteArray& text);
void handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint); void handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint);
void handleFrame(const GDBMIResultParser::ParseValue &frame);
void handleStack(const QList<GDBMIResultParser::ParseValue> & stack); void handleStack(const QList<GDBMIResultParser::ParseValue> & stack);
void handleLocalVariables(const QList<GDBMIResultParser::ParseValue> & variables); void handleLocalVariables(const QList<GDBMIResultParser::ParseValue> & variables);
void handleEvaluation(const QString& value); void handleEvaluation(const QString& value);
@ -606,7 +609,7 @@ private:
bool mReceivedSFWarning; bool mReceivedSFWarning;
int mCurrentLine; int mCurrentLine;
int mCurrentAddress; qulonglong mCurrentAddress;
QString mCurrentFunc; QString mCurrentFunc;
QString mCurrentFile; QString mCurrentFile;
QStringList mConsoleOutput; QStringList mConsoleOutput;

View File

@ -1903,8 +1903,7 @@ void Editor::onTooltipTimer()
break; break;
case TipType::Identifier: case TipType::Identifier:
if (pMainWindow->debugger()->executing() && !pMainWindow->debugger()->inferiorRunning()) { if (pMainWindow->debugger()->executing() && !pMainWindow->debugger()->inferiorRunning()) {
if (mParentPageControl) s = getWordAtPosition(this,p, pBeginPos,pEndPos, WordPurpose::wpEvaluation); // debugging
s = getWordAtPosition(this,p, pBeginPos,pEndPos, WordPurpose::wpEvaluation); // debugging
} else if (!mCompletionPopup->isVisible() } else if (!mCompletionPopup->isVisible()
&& !mHeaderCompletionPopup->isVisible()) { && !mHeaderCompletionPopup->isVisible()) {
expression = getExpressionAtPosition(p); expression = getExpressionAtPosition(p);
@ -1977,7 +1976,9 @@ void Editor::onTooltipTimer()
&& !mHeaderCompletionPopup->isVisible()) { && !mHeaderCompletionPopup->isVisible()) {
if (pMainWindow->debugger()->executing() if (pMainWindow->debugger()->executing()
&& (pSettings->editor().enableDebugTooltips())) { && (pSettings->editor().enableDebugTooltips())) {
showDebugHint(s,p.line); if (mParentPageControl) {
showDebugHint(s,p.line);
}
} else if (pSettings->editor().enableIdentifierToolTips()) { } else if (pSettings->editor().enableIdentifierToolTips()) {
hint = getParserHint(expression, s, p.line); hint = getParserHint(expression, s, p.line);
} }
@ -3851,7 +3852,7 @@ Editor::TipType Editor::getTipType(QPoint point, QSynedit::BufferCoord& pos)
return TipType::Selection; return TipType::Selection;
} else if (mParser && mParser->isIncludeLine(document()->getLine(pos.line-1))) { } else if (mParser && mParser->isIncludeLine(document()->getLine(pos.line-1))) {
return TipType::Preprocessor; return TipType::Preprocessor;
}else if (attr->tokenType() == QSynedit::TokenType::Identifier) { } else if (attr->tokenType() == QSynedit::TokenType::Identifier) {
return TipType::Identifier; return TipType::Identifier;
} else if (attr->tokenType() == QSynedit::TokenType::Keyword) { } else if (attr->tokenType() == QSynedit::TokenType::Keyword) {
return TipType::Keyword; return TipType::Keyword;

View File

@ -37,6 +37,7 @@ GDBMIResultParser::GDBMIResultParser()
mResultTypes.insert("-var-create",GDBMIResultType::CreateVar); mResultTypes.insert("-var-create",GDBMIResultType::CreateVar);
mResultTypes.insert("-var-list-children",GDBMIResultType::ListVarChildren); mResultTypes.insert("-var-list-children",GDBMIResultType::ListVarChildren);
mResultTypes.insert("-var-update",GDBMIResultType::UpdateVarValue); mResultTypes.insert("-var-update",GDBMIResultType::UpdateVarValue);
mResultTypes.insert("-stack-info-frame",GDBMIResultType::Frame);
} }
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)
@ -349,26 +350,22 @@ const GDBMIResultParser::ParseObject &GDBMIResultParser::ParseValue::object() co
return mObject; return mObject;
} }
int GDBMIResultParser::ParseValue::intValue(int defaultValue) const int64_t GDBMIResultParser::ParseValue::intValue(int defaultValue) const
{ {
//Q_ASSERT(mType == ParseValueType::Value); //Q_ASSERT(mType == ParseValueType::Value);
bool ok; bool ok;
int value = QString(mValue).toInt(&ok); qlonglong value = QString(mValue).toLongLong(&ok);
if (ok) if (ok)
return value; return value;
else else
return defaultValue; return defaultValue;
} }
int GDBMIResultParser::ParseValue::hexValue(int defaultValue) const qulonglong GDBMIResultParser::ParseValue::hexValue(bool &ok) const
{ {
//Q_ASSERT(mType == ParseValueType::Value); //Q_ASSERT(mType == ParseValueType::Value);
bool ok; qulonglong value = QString(mValue).toULongLong(&ok,16);
int value = QString(mValue).toInt(&ok,16); return value;
if (ok)
return value;
else
return defaultValue;
} }
QString GDBMIResultParser::ParseValue::pathValue() const QString GDBMIResultParser::ParseValue::pathValue() const

View File

@ -74,8 +74,8 @@ public:
const QByteArray &value() const; const QByteArray &value() const;
const QList<ParseValue> &array() const; const QList<ParseValue> &array() const;
const ParseObject &object() const; const ParseObject &object() const;
int intValue(int defaultValue=-1) const; qlonglong intValue(int defaultValue=-1) const;
int hexValue(int defaultValue=-1) const; qulonglong hexValue(bool &ok) const;
QString pathValue() const; QString pathValue() const;
QString utf8PathValue() const; QString utf8PathValue() const;

View File

@ -1019,16 +1019,17 @@ void MainWindow::removeActiveBreakpoints()
void MainWindow::setActiveBreakpoint(QString fileName, int Line, bool setFocus) void MainWindow::setActiveBreakpoint(QString fileName, int Line, bool setFocus)
{ {
removeActiveBreakpoints(); removeActiveBreakpoints();
if (!fileExists(fileName))
return;
// Then active the current line in the current file // Then active the current line in the current file
Editor *e = openFile(fileName); Editor *e = openFile(fileName);
if (e!=nullptr) { if (e!=nullptr) {
e->setActiveBreakpointFocus(Line,setFocus); e->setActiveBreakpointFocus(Line,setFocus);
if (setFocus) {
activateWindow();
}
} else {
pMainWindow->showCPUInfoDialog();
} }
if (setFocus) { return;
activateWindow();
}
} }
void MainWindow::updateDPI(int oldDPI, int /*newDPI*/) void MainWindow::updateDPI(int oldDPI, int /*newDPI*/)
@ -4892,6 +4893,7 @@ void MainWindow::onEditorContextMenu(const QPoint& pos)
menu.addSeparator(); menu.addSeparator();
if (canDebug) { if (canDebug) {
menu.addAction(ui->actionAdd_Watch); menu.addAction(ui->actionAdd_Watch);
menu.addAction(ui->actionAdd_Watchpoint);
menu.addAction(ui->actionToggle_Breakpoint); menu.addAction(ui->actionToggle_Breakpoint);
menu.addAction(ui->actionClear_all_breakpoints); menu.addAction(ui->actionClear_all_breakpoints);
menu.addSeparator(); menu.addSeparator();
@ -4981,6 +4983,7 @@ void MainWindow::disableDebugActions()
ui->actionStep_Out->setEnabled(false); ui->actionStep_Out->setEnabled(false);
ui->actionRun_To_Cursor->setEnabled(false); ui->actionRun_To_Cursor->setEnabled(false);
ui->actionContinue->setEnabled(false); ui->actionContinue->setEnabled(false);
ui->actionAdd_Watchpoint->setEnabled(false);
ui->cbEvaluate->setEnabled(false); ui->cbEvaluate->setEnabled(false);
ui->cbMemoryAddress->setEnabled(false); ui->cbMemoryAddress->setEnabled(false);
if (mCPUDialog) { if (mCPUDialog) {
@ -4997,6 +5000,7 @@ void MainWindow::enableDebugActions()
ui->actionStep_Out->setEnabled(!mDebugger->inferiorRunning()); ui->actionStep_Out->setEnabled(!mDebugger->inferiorRunning());
ui->actionRun_To_Cursor->setEnabled(!mDebugger->inferiorRunning()); ui->actionRun_To_Cursor->setEnabled(!mDebugger->inferiorRunning());
ui->actionContinue->setEnabled(!mDebugger->inferiorRunning()); ui->actionContinue->setEnabled(!mDebugger->inferiorRunning());
ui->actionAdd_Watchpoint->setEnabled(!mDebugger->inferiorRunning());
ui->cbEvaluate->setEnabled(!mDebugger->inferiorRunning()); ui->cbEvaluate->setEnabled(!mDebugger->inferiorRunning());
ui->cbMemoryAddress->setEnabled(!mDebugger->inferiorRunning()); ui->cbMemoryAddress->setEnabled(!mDebugger->inferiorRunning());
if (mCPUDialog) { if (mCPUDialog) {
@ -5034,6 +5038,17 @@ void MainWindow::onTodoParseFinished()
{ {
} }
void MainWindow::onWatchpointHitted(const QString &var, const QString &oldVal, const QString &newVal)
{
QMessageBox::information(this,
tr("Watchpoint hitted"),
tr("Value of \"%1\" has changed:").arg(var)
+"<br />"
+tr("Old value: %1").arg(oldVal)
+"<br />"
+tr("New value: %1").arg(newVal));
}
void MainWindow::prepareProjectForCompile() void MainWindow::prepareProjectForCompile()
{ {
if (!mProject) if (!mProject)
@ -6698,19 +6713,7 @@ void MainWindow::on_searchView_doubleClicked(const QModelIndex &index)
void MainWindow::on_tblStackTrace_doubleClicked(const QModelIndex &index) void MainWindow::on_tblStackTrace_doubleClicked(const QModelIndex &index)
{ {
PTrace trace = mDebugger->backtraceModel()->backtrace(index.row()); switchCurrentStackTrace(index.row());
if (trace) {
Editor *e = openFile(trace->filename);
if (e) {
e->setCaretPositionAndActivate(trace->line,1);
}
mDebugger->sendCommand("-stack-select-frame", QString("%1").arg(trace->level));
mDebugger->sendCommand("-stack-list-variables", "--all-values");
mDebugger->sendCommand("-var-update", "--all-values *");
if (this->mCPUDialog) {
this->mCPUDialog->updateInfo();
}
}
} }
@ -7637,8 +7640,12 @@ void MainWindow::updateVCSActions()
canBranch =!mFileSystemModelIconProvider.VCSRepository()->hasChangedFiles() canBranch =!mFileSystemModelIconProvider.VCSRepository()->hasChangedFiles()
&& !mFileSystemModelIconProvider.VCSRepository()->hasStagedFiles(); && !mFileSystemModelIconProvider.VCSRepository()->hasStagedFiles();
} }
ui->actionGit_Remotes->setEnabled(hasRepository && shouldEnable); ui->actionGit_Remotes->setEnabled(hasRepository && shouldEnable);
ui->actionGit_Create_Repository->setEnabled(!hasRepository && shouldEnable); ui->actionGit_Create_Repository->setEnabled(!hasRepository && shouldEnable);
ui->actionGit_Push->setEnabled(hasRepository && shouldEnable);
ui->actionGit_Pull->setEnabled(hasRepository && shouldEnable);
ui->actionGit_Fetch->setEnabled(hasRepository && shouldEnable);
ui->actionGit_Log->setEnabled(hasRepository && shouldEnable); ui->actionGit_Log->setEnabled(hasRepository && shouldEnable);
ui->actionGit_Commit->setEnabled(hasRepository && shouldEnable); ui->actionGit_Commit->setEnabled(hasRepository && shouldEnable);
ui->actionGit_Branch->setEnabled(hasRepository && shouldEnable && canBranch); ui->actionGit_Branch->setEnabled(hasRepository && shouldEnable && canBranch);
@ -8468,6 +8475,27 @@ QList<QAction *> MainWindow::listShortCutableActions()
return actions; return actions;
} }
void MainWindow::switchCurrentStackTrace(int idx)
{
PTrace trace = mDebugger->backtraceModel()->backtrace(idx);
if (trace) {
Editor *e = openFile(trace->filename);
if (e) {
e->setCaretPositionAndActivate(trace->line,1);
}
mDebugger->sendCommand("-stack-select-frame", QString("%1").arg(trace->level));
mDebugger->sendCommand("-stack-list-variables", "--all-values");
mDebugger->sendCommand("-var-update", "--all-values *");
if (this->mCPUDialog) {
this->mCPUDialog->updateInfo();
}
if (idx!=ui->tblStackTrace->currentIndex().row()) {
ui->tblStackTrace->setCurrentIndex(ui->tblStackTrace->model()->index(idx,0));
}
}
}
void MainWindow::on_actionTool_Window_Bars_triggered() void MainWindow::on_actionTool_Window_Bars_triggered()
{ {
@ -9595,3 +9623,19 @@ void MainWindow::on_actionIA_32_Assembly_Language_Reference_Manual_triggered()
QDesktopServices::openUrl(QUrl("https://docs.oracle.com/cd/E19455-01/806-3773/index.html")); QDesktopServices::openUrl(QUrl("https://docs.oracle.com/cd/E19455-01/806-3773/index.html"));
} }
void MainWindow::on_actionAdd_Watchpoint_triggered()
{
QString s = "";
bool isOk;
s=QInputDialog::getText(this,
tr("Watchpoint variable name"),
tr("Stop execution when the following variable is modified (it must be visible from the currect scope):"),
QLineEdit::Normal,
s,&isOk);
if (!isOk)
return;
s = s.trimmed();
mDebugger->addWatchpoint(s);
}

View File

@ -229,6 +229,8 @@ public:
QList<QAction*> listShortCutableActions(); QList<QAction*> listShortCutableActions();
void switchCurrentStackTrace(int idx);
public slots: public slots:
void logToolsOutput(const QString& msg); void logToolsOutput(const QString& msg);
void onCompileIssue(PCompileIssue issue); void onCompileIssue(PCompileIssue issue);
@ -267,6 +269,7 @@ public slots:
void onTodoParseStarted(); void onTodoParseStarted();
void onTodoFound(const QString& filename, int lineNo, int ch, const QString& line); void onTodoFound(const QString& filename, int lineNo, int ch, const QString& line);
void onTodoParseFinished(); void onTodoParseFinished();
void onWatchpointHitted(const QString& var, const QString& oldVal, const QString& newVal);
void setActiveBreakpoint(QString FileName, int Line, bool setFocus); void setActiveBreakpoint(QString FileName, int Line, bool setFocus);
void updateDPI(int oldDPI, int newDPI); void updateDPI(int oldDPI, int newDPI);
void onFileSaved(const QString& path, bool inProject); void onFileSaved(const QString& path, bool inProject);
@ -795,6 +798,8 @@ private slots:
void on_actionIA_32_Assembly_Language_Reference_Manual_triggered(); void on_actionIA_32_Assembly_Language_Reference_Manual_triggered();
void on_actionAdd_Watchpoint_triggered();
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
bool mFullInitialized; bool mFullInitialized;

View File

@ -170,6 +170,7 @@
<addaction name="actionStop_Execution"/> <addaction name="actionStop_Execution"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionAdd_Watch"/> <addaction name="actionAdd_Watch"/>
<addaction name="actionAdd_Watchpoint"/>
<addaction name="actionView_CPU_Window"/> <addaction name="actionView_CPU_Window"/>
</widget> </widget>
<widget class="QMenu" name="menuEdit"> <widget class="QMenu" name="menuEdit">
@ -935,7 +936,7 @@
<enum>QTabWidget::South</enum> <enum>QTabWidget::South</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>3</number> <number>2</number>
</property> </property>
<property name="iconSize"> <property name="iconSize">
<size> <size>
@ -1131,7 +1132,7 @@
<enum>QTabWidget::North</enum> <enum>QTabWidget::North</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>3</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="tabDebugConsole"> <widget class="QWidget" name="tabDebugConsole">
<attribute name="title"> <attribute name="title">
@ -3290,6 +3291,9 @@
<property name="text"> <property name="text">
<string>Generate Assembly</string> <string>Generate Assembly</string>
</property> </property>
<property name="shortcut">
<string>Ctrl+F9</string>
</property>
</action> </action>
<action name="actionTrim_trailing_spaces"> <action name="actionTrim_trailing_spaces">
<property name="text"> <property name="text">
@ -3334,6 +3338,14 @@
<string>IA-32 Assembly Language Reference Manual</string> <string>IA-32 Assembly Language Reference Manual</string>
</property> </property>
</action> </action>
<action name="actionAdd_Watchpoint">
<property name="text">
<string>Add Watchpoint...</string>
</property>
<property name="toolTip">
<string>Add a watchpoint that's triggered when it's modified.</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -2728,7 +2728,7 @@ static void setReleaseOptions(Settings::PCompilerSet pSet) {
} }
static void setDebugOptions(Settings::PCompilerSet pSet, bool enableAsan = false) { static void setDebugOptions(Settings::PCompilerSet pSet, bool enableAsan = false) {
pSet->setCompileOption(CC_CMD_OPT_OPTIMIZE,"g"); //pSet->setCompileOption(CC_CMD_OPT_OPTIMIZE,"g");
pSet->setCompileOption(CC_CMD_OPT_DEBUG_INFO, COMPILER_OPTION_ON); pSet->setCompileOption(CC_CMD_OPT_DEBUG_INFO, COMPILER_OPTION_ON);
pSet->setCompileOption(CC_CMD_OPT_WARNING_ALL, COMPILER_OPTION_ON); pSet->setCompileOption(CC_CMD_OPT_WARNING_ALL, COMPILER_OPTION_ON);
//pSet->setCompileOption(CC_CMD_OPT_WARNING_EXTRA, COMPILER_OPTION_ON); //pSet->setCompileOption(CC_CMD_OPT_WARNING_EXTRA, COMPILER_OPTION_ON);

View File

@ -5079,6 +5079,57 @@
<source>IA-32 Assembly Language Reference Manual</source> <source>IA-32 Assembly Language Reference Manual</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Add Watchpoint...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add a watchpoint that&apos;s triggered when it&apos;s modified.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Old value: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Watchpoint variable name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Stop execution when the following variable is modified (it must be visible from the currect scope):</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Watchpoint hitted</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Value of &quot;%1&quot; has changed:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>New value: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MemoryModel</name>
<message>
<source>dec: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>hex: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>bin: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>ascii: &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>NewClassDialog</name> <name>NewClassDialog</name>

File diff suppressed because it is too large Load Diff

View File

@ -4832,6 +4832,57 @@
<source>IA-32 Assembly Language Reference Manual</source> <source>IA-32 Assembly Language Reference Manual</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Add Watchpoint...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add a watchpoint that&apos;s triggered when it&apos;s modified.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Old value: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Watchpoint variable name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Stop execution when the following variable is modified (it must be visible from the currect scope):</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Watchpoint hitted</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Value of &quot;%1&quot; has changed:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>New value: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MemoryModel</name>
<message>
<source>dec: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>hex: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>bin: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>ascii: &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>NewClassDialog</name> <name>NewClassDialog</name>

View File

@ -27,7 +27,8 @@
CPUDialog::CPUDialog(QWidget *parent) : CPUDialog::CPUDialog(QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::CPUDialog), ui(new Ui::CPUDialog),
mInited(false) mInited(false),
mSetting(false)
{ {
setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
setWindowFlag(Qt::WindowContextHelpButtonHint,false); setWindowFlag(Qt::WindowContextHelpButtonHint,false);
@ -84,6 +85,7 @@ CPUDialog::~CPUDialog()
void CPUDialog::updateInfo() void CPUDialog::updateInfo()
{ {
if (pMainWindow->debugger()->executing()) { if (pMainWindow->debugger()->executing()) {
pMainWindow->debugger()->sendCommand("-stack-info-frame", "");
// Load the registers.. // Load the registers..
sendSyntaxCommand(); sendSyntaxCommand();
pMainWindow->debugger()->sendCommand("-data-list-register-values", "N"); pMainWindow->debugger()->sendCommand("-data-list-register-values", "N");
@ -114,9 +116,17 @@ void CPUDialog::updateDPI(float dpi)
onUpdateIcons(); onUpdateIcons();
} }
void CPUDialog::setDisassembly(const QString& file, const QString& funcName,const QStringList& lines) void CPUDialog::setDisassembly(const QString& file, const QString& funcName,const QStringList& lines,const QList<PTrace>& traces)
{ {
ui->txtFunctionName->setText(QString("%1:%2").arg(file, funcName)); mSetting=true;
ui->cbCallStack->clear();
int currentIndex=-1;
for (int i=0;i<traces.count();i++) {
ui->cbCallStack->addItem(QString("%1:%2").arg(traces[i]->filename, traces[i]->funcname));
if (file==traces[i]->filename && funcName == traces[i]->funcname)
currentIndex=i;
}
ui->cbCallStack->setCurrentIndex(currentIndex);
int activeLine = -1; int activeLine = -1;
for (int i=0;i<lines.size();i++) { for (int i=0;i<lines.size();i++) {
QString line = lines[i]; QString line = lines[i];
@ -127,6 +137,7 @@ void CPUDialog::setDisassembly(const QString& file, const QString& funcName,cons
ui->txtCode->document()->setContents(lines); ui->txtCode->document()->setContents(lines);
if (activeLine!=-1) if (activeLine!=-1)
ui->txtCode->setCaretXYCentered(QSynedit::BufferCoord{1,activeLine+1}); ui->txtCode->setCaretXYCentered(QSynedit::BufferCoord{1,activeLine+1});
mSetting=false;
} }
void CPUDialog::resetEditorFont(float dpi) void CPUDialog::resetEditorFont(float dpi)
@ -216,3 +227,11 @@ void CPUDialog::showEvent(QShowEvent *event)
} }
} }
void CPUDialog::on_cbCallStack_currentIndexChanged(int index)
{
if (mSetting)
return ;
pMainWindow->switchCurrentStackTrace(index);
}

View File

@ -18,6 +18,7 @@
#define CPUDIALOG_H #define CPUDIALOG_H
#include <QDialog> #include <QDialog>
#include "../debugger.h"
namespace Ui { namespace Ui {
class CPUDialog; class CPUDialog;
@ -34,7 +35,7 @@ public:
void updateButtonStates(bool enable); void updateButtonStates(bool enable);
public slots: public slots:
void updateDPI(float dpi); void updateDPI(float dpi);
void setDisassembly(const QString& file, const QString& funcName,const QStringList& lines); void setDisassembly(const QString& file, const QString& funcName,const QStringList& linesconst,const QList<PTrace>& traces);
void resetEditorFont(float dpi); void resetEditorFont(float dpi);
signals: signals:
void closed(); void closed();
@ -43,6 +44,7 @@ private:
private: private:
Ui::CPUDialog *ui; Ui::CPUDialog *ui;
bool mInited; bool mInited;
bool mSetting;
// QWidget interface // QWidget interface
protected: protected:
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
@ -55,6 +57,8 @@ private slots:
void onUpdateIcons(); void onUpdateIcons();
// QWidget interface // QWidget interface
void on_cbCallStack_currentIndexChanged(int index);
protected: protected:
void showEvent(QShowEvent *event) override; void showEvent(QShowEvent *event) override;
}; };

View File

@ -74,7 +74,17 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="txtFunctionName"/> <widget class="QComboBox" name="cbCallStack">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="insertPolicy">
<enum>QComboBox::NoInsert</enum>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>