summaryrefslogtreecommitdiff
path: root/src/plugins/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/debugger')
-rw-r--r--src/plugins/debugger/breakhandler.cpp21
-rw-r--r--src/plugins/debugger/breakhandler.h1
-rw-r--r--src/plugins/debugger/cdb/cdbengine.cpp68
-rw-r--r--src/plugins/debugger/cdb/stringinputstream.h1
-rw-r--r--src/plugins/debugger/commonoptionspage.cpp2
-rw-r--r--src/plugins/debugger/debuggeractions.cpp4
-rw-r--r--src/plugins/debugger/debuggerdialogs.cpp12
-rw-r--r--src/plugins/debugger/debuggerengine.cpp4
-rw-r--r--src/plugins/debugger/debuggeritem.cpp8
-rw-r--r--src/plugins/debugger/debuggeritemmanager.cpp10
-rw-r--r--src/plugins/debugger/debuggermainwindow.cpp10
-rw-r--r--src/plugins/debugger/debuggerrunconfigurationaspect.cpp16
-rw-r--r--src/plugins/debugger/debuggerruncontrol.cpp24
-rw-r--r--src/plugins/debugger/debuggerruncontrol.h5
-rw-r--r--src/plugins/debugger/debuggertooltipmanager.cpp3
-rw-r--r--src/plugins/debugger/disassembleragent.cpp2
-rw-r--r--src/plugins/debugger/enginemanager.cpp2
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp1
-rw-r--r--src/plugins/debugger/lldb/lldbengine.cpp11
-rw-r--r--src/plugins/debugger/loadcoredialog.cpp10
-rw-r--r--src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp2
-rw-r--r--src/plugins/debugger/shared/symbolpathsdialog.cpp2
-rw-r--r--src/plugins/debugger/stackhandler.cpp3
-rw-r--r--src/plugins/debugger/unstartedappwatcherdialog.cpp8
-rw-r--r--src/plugins/debugger/uvsc/uvscclient.cpp193
-rw-r--r--src/plugins/debugger/uvsc/uvscclient.h8
-rw-r--r--src/plugins/debugger/uvsc/uvscdatatypes.h4
-rw-r--r--src/plugins/debugger/uvsc/uvscengine.cpp41
-rw-r--r--src/plugins/debugger/uvsc/uvscengine.h4
-rw-r--r--src/plugins/debugger/uvsc/uvscutils.cpp36
-rw-r--r--src/plugins/debugger/uvsc/uvscutils.h5
-rw-r--r--src/plugins/debugger/watchhandler.cpp24
32 files changed, 422 insertions, 123 deletions
diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp
index 75782ae6d5..13db44f7ca 100644
--- a/src/plugins/debugger/breakhandler.cpp
+++ b/src/plugins/debugger/breakhandler.cpp
@@ -665,7 +665,7 @@ void BreakpointDialog::getParts(unsigned partsMask, BreakpointParameters *data)
if (partsMask & FileAndLinePart) {
data->lineNumber = m_lineEditLineNumber->text().toInt();
data->pathUsage = static_cast<BreakpointPathUsage>(m_comboBoxPathUsage->currentIndex());
- data->fileName = FilePath::fromUserInput(m_pathChooserFileName->path());
+ data->fileName = m_pathChooserFileName->filePath();
}
if (partsMask & FunctionPart)
data->functionName = m_lineEditFunction->text();
@@ -702,7 +702,7 @@ void BreakpointDialog::setParts(unsigned mask, const BreakpointParameters &data)
m_lineEditMessage->setText(data.message);
if (mask & FileAndLinePart) {
- m_pathChooserFileName->setFileName(data.fileName);
+ m_pathChooserFileName->setFilePath(data.fileName);
m_lineEditLineNumber->setText(QString::number(data.lineNumber));
}
@@ -1174,19 +1174,19 @@ void BreakHandler::removeAlienBreakpoint(const QString &rid)
void BreakHandler::requestBreakpointInsertion(const Breakpoint &bp)
{
bp->gotoState(BreakpointInsertionRequested, BreakpointNew);
- QTimer::singleShot(0, m_engine, [this, bp] { m_engine->insertBreakpoint(bp); });
+ m_engine->insertBreakpoint(bp);
}
void BreakHandler::requestBreakpointUpdate(const Breakpoint &bp)
{
bp->gotoState(BreakpointUpdateRequested, BreakpointInserted);
- QTimer::singleShot(0, m_engine, [this, bp] { m_engine->updateBreakpoint(bp); });
+ m_engine->updateBreakpoint(bp);
}
void BreakHandler::requestBreakpointRemoval(const Breakpoint &bp)
{
bp->gotoState(BreakpointRemoveRequested, BreakpointInserted);
- QTimer::singleShot(0, m_engine, [this, bp] { m_engine->removeBreakpoint(bp); });
+ m_engine->removeBreakpoint(bp);
}
void BreakHandler::requestBreakpointEnabling(const Breakpoint &bp, bool enabled)
@@ -1330,7 +1330,12 @@ void DebuggerEngine::notifyBreakpointInsertOk(const Breakpoint &bp)
void DebuggerEngine::notifyBreakpointInsertFailed(const Breakpoint &bp)
{
QTC_ASSERT(bp, return);
+ GlobalBreakpoint gbp = bp->globalBreakpoint();
bp->gotoState(BreakpointDead, BreakpointInsertionProceeding);
+ breakHandler()->removeDisassemblerMarker(bp);
+ breakHandler()->destroyItem(bp);
+ QTC_ASSERT(gbp, return);
+ gbp->updateMarker();
}
void DebuggerEngine::notifyBreakpointRemoveProceeding(const Breakpoint &bp)
@@ -1509,7 +1514,7 @@ bool BreakHandler::setData(const QModelIndex &idx, const QVariant &value, int ro
return contextMenuEvent(ev);
if (auto kev = ev.as<QKeyEvent>(QEvent::KeyPress)) {
- if (kev->key() == Qt::Key_Delete) {
+ if (kev->key() == Qt::Key_Delete || kev->key() == Qt::Key_Backspace) {
QModelIndexList si = ev.currentOrSelectedRows();
const Breakpoints bps = findBreakpointsByIndex(si);
for (Breakpoint bp : bps) {
@@ -2490,7 +2495,7 @@ GlobalBreakpoint BreakpointManager::findBreakpointFromContext(const ContextData
matchLevel = 2;
bestMatch = gbp;
} else if (matchLevel < 2) {
- for (const QPointer<DebuggerEngine> engine : EngineManager::engines()) {
+ for (const QPointer<DebuggerEngine> &engine : EngineManager::engines()) {
BreakHandler *handler = engine->breakHandler();
for (Breakpoint bp : handler->breakpoints()) {
if (bp->globalBreakpoint() == gbp) {
@@ -2547,7 +2552,7 @@ bool BreakpointManager::setData(const QModelIndex &idx, const QVariant &value, i
return contextMenuEvent(ev);
if (auto kev = ev.as<QKeyEvent>(QEvent::KeyPress)) {
- if (kev->key() == Qt::Key_Delete) {
+ if (kev->key() == Qt::Key_Delete || kev->key() == Qt::Key_Backspace) {
QModelIndexList si = ev.currentOrSelectedRows();
const GlobalBreakpoints gbps = findBreakpointsByIndex(si);
for (GlobalBreakpoint gbp : gbps)
diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h
index 55a4bfd9bd..f0ee77b872 100644
--- a/src/plugins/debugger/breakhandler.h
+++ b/src/plugins/debugger/breakhandler.h
@@ -93,6 +93,7 @@ private:
friend class BreakHandler;
friend class BreakpointManager;
friend class BreakpointMarker;
+ friend class DebuggerEngine;
void updateMarker();
void updateMarkerIcon();
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index a98ee3e9a7..056991b06b 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -966,6 +966,13 @@ void CdbEngine::executeDebuggerCommand(const QString &command)
// Post command to the cdb process
void CdbEngine::runCommand(const DebuggerCommand &dbgCmd)
{
+ constexpr int maxCommandLength = 4096;
+ constexpr int maxTokenLength = 4 /*" -t "*/
+ + 5 /* 99999 tokens should be enough for a single qc run time*/
+ + 1 /* token part splitter '.' */
+ + 3 /* 1000 parts should also be more than enough */
+ + 1 /* final space */;
+
QString cmd = dbgCmd.function + dbgCmd.argsToString();
if (!m_accessible) {
doInterruptInferior([this, dbgCmd](){
@@ -977,11 +984,26 @@ void CdbEngine::runCommand(const DebuggerCommand &dbgCmd)
return;
}
+ if (dbgCmd.flags == ScriptCommand) {
+ // repack script command into an extension command
+ DebuggerCommand newCmd("script", ExtensionCommand, dbgCmd.callback);
+ if (!dbgCmd.args.isNull())
+ newCmd.args = QString{dbgCmd.function + '(' + dbgCmd.argsToPython() + ')'};
+ else
+ newCmd.args = dbgCmd.function;
+ runCommand(newCmd);
+ return;
+ }
+
QString fullCmd;
if (dbgCmd.flags == NoFlags) {
- fullCmd = cmd;
+ fullCmd = cmd + '\n';
+ if (fullCmd.length() > maxCommandLength) {
+ showMessage("Command is longer than 4096 characters execution will likely fail.",
+ LogWarning);
+ }
} else {
- const int token = m_nextCommandToken++;
+ const int token = ++m_nextCommandToken;
StringInputStream str(fullCmd);
if (dbgCmd.flags == BuiltinCommand) {
// Post a built-in-command producing free-format output with a callback.
@@ -989,23 +1011,35 @@ void CdbEngine::runCommand(const DebuggerCommand &dbgCmd)
// printing a specially formatted token to be identifiable in the output.
str << ".echo \"" << m_tokenPrefix << token << "<\"\n"
<< cmd << "\n"
- << ".echo \"" << m_tokenPrefix << token << ">\"";
+ << ".echo \"" << m_tokenPrefix << token << ">\"" << '\n';
+ if (fullCmd.length() > maxCommandLength) {
+ showMessage("Command is longer than 4096 characters execution will likely fail.",
+ LogWarning);
+ }
} else if (dbgCmd.flags == ExtensionCommand) {
+
// Post an extension command producing one-line output with a callback,
// pass along token for identification in hash.
- str << m_extensionCommandPrefix << dbgCmd.function << "%1%2";
- if (dbgCmd.args.isString())
- str << ' ' << dbgCmd.argsToString();
- cmd = fullCmd.arg("", "");
- fullCmd = fullCmd.arg(" -t ").arg(token);
- } else if (dbgCmd.flags == ScriptCommand) {
- // Add extension prefix and quotes the script command
- // pass along token for identification in hash.
- str << m_extensionCommandPrefix + "script %1%2 " << dbgCmd.function;
- if (!dbgCmd.args.isNull())
- str << '(' << dbgCmd.argsToPython() << ')';
- cmd = fullCmd.arg("", "");
- fullCmd = fullCmd.arg(" -t ").arg(token);
+ const QString prefix = m_extensionCommandPrefix + dbgCmd.function;
+ QList<QStringRef> splittedArguments;
+ if (dbgCmd.args.isString()) {
+ const QString &arguments = dbgCmd.argsToString();
+ cmd = prefix + arguments;
+ int argumentSplitPos = 0;
+ QList<QStringRef> splittedArguments;
+ int maxArgumentSize = maxCommandLength - prefix.length() - maxTokenLength;
+ while (argumentSplitPos < arguments.size()) {
+ splittedArguments << arguments.midRef(argumentSplitPos, maxArgumentSize);
+ argumentSplitPos += splittedArguments.last().length();
+ }
+ QTC_CHECK(argumentSplitPos == arguments.size());
+ int tokenPart = splittedArguments.size();
+ for (const QStringRef &part : qAsConst(splittedArguments))
+ str << prefix << " -t " << token << '.' << --tokenPart << ' ' << part << '\n';
+ } else {
+ cmd = prefix;
+ str << prefix << " -t " << token << '.' << 0 << '\n';
+ }
}
m_commandForToken.insert(token, dbgCmd);
}
@@ -1018,7 +1052,7 @@ void CdbEngine::runCommand(const DebuggerCommand &dbgCmd)
qDebug("CdbEngine::postCommand: resulting command '%s'\n", qPrintable(fullCmd));
}
showMessage(cmd, LogInput);
- m_process.write(fullCmd.toLocal8Bit() + '\n');
+ m_process.write(fullCmd.toLocal8Bit());
}
void CdbEngine::activateFrame(int index)
diff --git a/src/plugins/debugger/cdb/stringinputstream.h b/src/plugins/debugger/cdb/stringinputstream.h
index 61c78c7a0a..21f4ccd14e 100644
--- a/src/plugins/debugger/cdb/stringinputstream.h
+++ b/src/plugins/debugger/cdb/stringinputstream.h
@@ -42,6 +42,7 @@ public:
StringInputStream &operator<<(char a) { m_target.append(a); return *this; }
StringInputStream &operator<<(const char *a) { m_target.append(QString::fromUtf8(a)); return *this; }
StringInputStream &operator<<(const QString &a) { m_target.append(a); return *this; }
+ StringInputStream &operator<<(const QStringRef &a) { m_target.append(a); return *this; }
StringInputStream &operator<<(int i) { appendInt(i); return *this; }
StringInputStream &operator<<(unsigned i) { appendInt(i); return *this; }
diff --git a/src/plugins/debugger/commonoptionspage.cpp b/src/plugins/debugger/commonoptionspage.cpp
index 2f21805d27..24138b192c 100644
--- a/src/plugins/debugger/commonoptionspage.cpp
+++ b/src/plugins/debugger/commonoptionspage.cpp
@@ -296,7 +296,7 @@ public:
label->setText("<html><head/><body>\n<p>"
+ tr("The debugging helpers are used to produce a nice "
"display of objects of certain types like QString or "
- "std::map in the &quot;Locals and Expressions&quot; view.")
+ "std::map in the &quot;Locals&quot; and &quot;Expressions&quot; views.")
+ "</p></body></html>");
auto groupBoxCustomDumperCommands = new QGroupBox(debuggingHelperGroupBox);
diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp
index f47dc28937..9df57cb430 100644
--- a/src/plugins/debugger/debuggeractions.cpp
+++ b/src/plugins/debugger/debuggeractions.cpp
@@ -169,7 +169,7 @@ DebuggerSettings::DebuggerSettings()
item->setCheckable(true);
item->setDefaultValue(true);
item->setSettingsKey(debugModeGroup, "AutoDerefPointers");
- item->setToolTip(tr("<p>This switches the Locals and Expressions view to "
+ item->setToolTip(tr("<p>This switches the Locals and Expressions views to "
"automatically dereference pointers. This saves a level in the "
"tree view, but also loses data for the now-missing intermediate "
"level."));
@@ -587,7 +587,7 @@ DebuggerSettings::DebuggerSettings()
item = new SavedAction;
item->setSettingsKey(debugModeGroup, "DisplayStringLimit");
item->setToolTip(tr("<p>The maximum length of string entries in the "
- "Locals and Expressions pane. Longer than that are cut off "
+ "Locals and Expressions views. Longer than that are cut off "
"and displayed with an ellipsis attached."));
item->setDefaultValue(100);
insertItem(DisplayStringLimit, item);
diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp
index 226026f99c..afaaf6af56 100644
--- a/src/plugins/debugger/debuggerdialogs.cpp
+++ b/src/plugins/debugger/debuggerdialogs.cpp
@@ -479,14 +479,14 @@ StartApplicationParameters StartApplicationDialog::parameters() const
StartApplicationParameters result;
result.serverPort = d->serverPortSpinBox->value();
result.serverAddress = d->channelOverrideEdit->text();
- result.runnable.executable = d->localExecutablePathChooser->fileName();
- result.serverStartScript = d->serverStartScriptPathChooser->fileName();
+ result.runnable.executable = d->localExecutablePathChooser->filePath();
+ result.serverStartScript = d->serverStartScriptPathChooser->filePath();
result.serverInitCommands = d->serverInitCommandsTextEdit->toPlainText();
result.serverResetCommands = d->serverResetCommandsTextEdit->toPlainText();
result.kitId = d->kitChooser->currentKitId();
- result.debugInfoLocation = d->debuginfoPathChooser->path();
+ result.debugInfoLocation = d->debuginfoPathChooser->filePath().toString();
result.runnable.commandLineArguments = d->arguments->text();
- result.runnable.workingDirectory = d->workingDirectory->path();
+ result.runnable.workingDirectory = d->workingDirectory->filePath().toString();
result.breakAtMain = d->breakAtMainCheckBox->isChecked();
result.runInTerminal = d->runInTerminalCheckBox->isChecked();
return result;
@@ -497,8 +497,8 @@ void StartApplicationDialog::setParameters(const StartApplicationParameters &p)
d->kitChooser->setCurrentKitId(p.kitId);
d->serverPortSpinBox->setValue(p.serverPort);
d->channelOverrideEdit->setText(p.serverAddress);
- d->localExecutablePathChooser->setFileName(p.runnable.executable);
- d->serverStartScriptPathChooser->setFileName(p.serverStartScript);
+ d->localExecutablePathChooser->setFilePath(p.runnable.executable);
+ d->serverStartScriptPathChooser->setFilePath(p.serverStartScript);
d->serverInitCommandsTextEdit->setPlainText(p.serverInitCommands);
d->serverResetCommandsTextEdit->setPlainText(p.serverResetCommands);
d->debuginfoPathChooser->setPath(p.debugInfoLocation);
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index ff3bc70788..bda6442e6b 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -1760,11 +1760,11 @@ void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) c
case AppOutput:
case AppStuff:
d->m_logWindow->showOutput(channel, msg);
- emit appendMessageRequested(msg, StdOutFormatSameLine, false);
+ emit appendMessageRequested(msg, StdOutFormat, false);
break;
case AppError:
d->m_logWindow->showOutput(channel, msg);
- emit appendMessageRequested(msg, StdErrFormatSameLine, false);
+ emit appendMessageRequested(msg, StdErrFormat, false);
break;
default:
d->m_logWindow->showOutput(channel, msg);
diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp
index bb31684a54..a0775c2da6 100644
--- a/src/plugins/debugger/debuggeritem.cpp
+++ b/src/plugins/debugger/debuggeritem.cpp
@@ -107,8 +107,8 @@ DebuggerItem::DebuggerItem(const QVariant &id)
DebuggerItem::DebuggerItem(const QVariantMap &data)
{
m_id = data.value(DEBUGGER_INFORMATION_ID).toString();
- m_command = FilePath::fromUserInput(data.value(DEBUGGER_INFORMATION_COMMAND).toString());
- m_workingDirectory = FilePath::fromUserInput(data.value(DEBUGGER_INFORMATION_WORKINGDIRECTORY).toString());
+ m_command = FilePath::fromVariant(data.value(DEBUGGER_INFORMATION_COMMAND));
+ m_workingDirectory = FilePath::fromVariant(data.value(DEBUGGER_INFORMATION_WORKINGDIRECTORY));
m_unexpandedDisplayName = data.value(DEBUGGER_INFORMATION_DISPLAYNAME).toString();
m_isAutoDetected = data.value(DEBUGGER_INFORMATION_AUTODETECTED, false).toBool();
m_version = data.value(DEBUGGER_INFORMATION_VERSION).toString();
@@ -309,8 +309,8 @@ QVariantMap DebuggerItem::toMap() const
QVariantMap data;
data.insert(DEBUGGER_INFORMATION_DISPLAYNAME, m_unexpandedDisplayName);
data.insert(DEBUGGER_INFORMATION_ID, m_id);
- data.insert(DEBUGGER_INFORMATION_COMMAND, m_command.toString());
- data.insert(DEBUGGER_INFORMATION_WORKINGDIRECTORY, m_workingDirectory.toString());
+ data.insert(DEBUGGER_INFORMATION_COMMAND, m_command.toVariant());
+ data.insert(DEBUGGER_INFORMATION_WORKINGDIRECTORY, m_workingDirectory.toVariant());
data.insert(DEBUGGER_INFORMATION_ENGINETYPE, int(m_engineType));
data.insert(DEBUGGER_INFORMATION_AUTODETECTED, m_isAutoDetected);
data.insert(DEBUGGER_INFORMATION_VERSION, m_version);
diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp
index 34ea3b46cd..4be3de93a9 100644
--- a/src/plugins/debugger/debuggeritemmanager.cpp
+++ b/src/plugins/debugger/debuggeritemmanager.cpp
@@ -348,8 +348,8 @@ DebuggerItem DebuggerItemConfigWidget::item() const
{
DebuggerItem item(m_id);
item.setUnexpandedDisplayName(m_displayNameLineEdit->text());
- item.setCommand(m_binaryChooser->fileName());
- item.setWorkingDirectory(m_workingDirectoryChooser->fileName());
+ item.setCommand(m_binaryChooser->filePath());
+ item.setWorkingDirectory(m_workingDirectoryChooser->filePath());
item.setAutoDetected(m_autodetected);
Abis abiList;
const QStringList abis = m_abis->text().split(QRegExp("[^A-Za-z0-9-_]+"));
@@ -390,10 +390,10 @@ void DebuggerItemConfigWidget::load(const DebuggerItem *item)
m_typeLineEdit->setText(item->engineTypeName());
m_binaryChooser->setReadOnly(item->isAutoDetected());
- m_binaryChooser->setFileName(item->command());
+ m_binaryChooser->setFilePath(item->command());
m_workingDirectoryChooser->setReadOnly(item->isAutoDetected());
- m_workingDirectoryChooser->setFileName(item->workingDirectory());
+ m_workingDirectoryChooser->setFilePath(item->workingDirectory());
QString text;
QString versionCommand;
@@ -427,7 +427,7 @@ void DebuggerItemConfigWidget::binaryPathHasChanged()
return;
DebuggerItem tmp;
- QFileInfo fi = QFileInfo(m_binaryChooser->path());
+ QFileInfo fi = QFileInfo(m_binaryChooser->filePath().toString());
if (fi.isExecutable()) {
tmp = item();
tmp.reinitializeFromFile();
diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp
index 1c404a22b2..53e37ecc1a 100644
--- a/src/plugins/debugger/debuggermainwindow.cpp
+++ b/src/plugins/debugger/debuggermainwindow.cpp
@@ -250,8 +250,8 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent)
m_toolBarDock = dock;
q->addDockWidget(Qt::BottomDockWidgetArea, m_toolBarDock);
- connect(viewButton, &QAbstractButton::clicked, this, [this, viewButton] {
- ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS);
+ connect(viewButton, &QAbstractButton::clicked, this, [viewButton] {
+ ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_VIEW_VIEWS);
viewsMenu->menu()->exec(viewButton->mapToGlobal(QPoint()));
});
@@ -277,7 +277,7 @@ DebuggerMainWindow::DebuggerMainWindow()
Context debugcontext(Debugger::Constants::C_DEBUGMODE);
- ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS);
+ ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_VIEW_VIEWS);
Command *cmd = ActionManager::registerAction(showCentralWidgetAction(),
"Debugger.Views.ShowCentralWidget", debugcontext);
cmd->setAttribute(Command::CA_Hide);
@@ -315,7 +315,7 @@ DebuggerMainWindow::~DebuggerMainWindow()
void DebuggerMainWindow::contextMenuEvent(QContextMenuEvent *ev)
{
- ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS);
+ ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_VIEW_VIEWS);
viewsMenu->menu()->exec(ev->globalPos());
}
@@ -896,7 +896,7 @@ void Perspective::addWindow(QWidget *widget,
Command *cmd = ActionManager::registerAction(op.toggleViewAction, op.commandId, d->context());
cmd->setAttribute(Command::CA_Hide);
- ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS)->addAction(cmd);
+ ActionManager::actionContainer(Core::Constants::M_VIEW_VIEWS)->addAction(cmd);
}
d->m_dockOperations.append(op);
diff --git a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
index 91c32a15c1..076fd9723d 100644
--- a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
+++ b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
@@ -27,17 +27,18 @@
#include "debuggerconstants.h"
+#include <coreplugin/helpmanager.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
-#include <coreplugin/helpmanager.h>
+#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/buildstep.h>
+#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/target.h>
-#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/buildstep.h>
-#include <projectexplorer/buildsteplist.h>
+#include <qtsupport/qtbuildaspects.h>
#include <QCheckBox>
#include <QDebug>
@@ -243,12 +244,9 @@ bool DebuggerRunConfigurationAspect::useQmlDebugger() const
//
// Try to find a build configuration to check whether qml debugging is enabled there
- // (Using the Qt metatype system to avoid a hard build system dependency)
- //
if (BuildConfiguration *bc = m_target->activeBuildConfiguration()) {
- const QVariant linkProperty = bc->property("linkQmlDebuggingLibrary");
- if (linkProperty.isValid() && linkProperty.canConvert(QVariant::Bool))
- return linkProperty.toBool();
+ const auto aspect = bc->aspect<QtSupport::QmlDebuggingAspect>();
+ return aspect && aspect->setting() == TriState::Enabled;
}
return !languages.contains(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp
index 463342357b..ee7c5dab36 100644
--- a/src/plugins/debugger/debuggerruncontrol.cpp
+++ b/src/plugins/debugger/debuggerruncontrol.cpp
@@ -128,14 +128,14 @@ public:
{
const QByteArray ba = m_proc.readAllStandardOutput();
const QString msg = QString::fromLocal8Bit(ba, ba.length());
- m_runTool->appendMessage(msg, StdOutFormatSameLine);
+ m_runTool->appendMessage(msg, StdOutFormat);
}
void handleStandardError()
{
const QByteArray ba = m_proc.readAllStandardError();
const QString msg = QString::fromLocal8Bit(ba, ba.length());
- m_runTool->appendMessage(msg, StdErrFormatSameLine);
+ m_runTool->appendMessage(msg, StdErrFormat);
}
void handleFinished()
@@ -508,6 +508,11 @@ void DebuggerRunTool::addQmlServerInferiorCommandLineArgumentIfNeeded()
d->addQmlServerInferiorCommandLineArgumentIfNeeded = true;
}
+void DebuggerRunTool::modifyDebuggerEnvironment(const EnvironmentItems &items)
+{
+ m_runParameters.debugger.environment.modify(items);
+}
+
void DebuggerRunTool::setCrashParameter(const QString &event)
{
m_runParameters.crashParameter = event;
@@ -689,10 +694,10 @@ void DebuggerRunTool::start()
if (m_runParameters.startMode == StartInternal) {
QStringList unhandledIds;
- for (const GlobalBreakpoint bp : BreakpointManager::globalBreakpoints()) {
+// for (const GlobalBreakpoint &bp : BreakpointManager::globalBreakpoints()) {
// if (bp->isEnabled() && !m_engine->acceptsBreakpoint(bp))
// unhandledIds.append(bp.id().toString());
- }
+// }
if (!unhandledIds.isEmpty()) {
QString warningMessage =
DebuggerPlugin::tr("Some breakpoints cannot be handled by the debugger "
@@ -895,6 +900,11 @@ Internal::TerminalRunner *DebuggerRunTool::terminalRunner() const
return d->terminalRunner;
}
+DebuggerEngineType DebuggerRunTool::cppEngineType() const
+{
+ return m_runParameters.cppEngineType;
+}
+
DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerminal)
: RunWorker(runControl), d(new DebuggerRunToolPrivate)
{
@@ -972,7 +982,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
const Tasks tasks = DebuggerKitAspect::validateDebugger(kit);
for (const Task &t : tasks) {
if (t.type != Task::Warning)
- m_runParameters.validationErrors.append(t.description);
+ m_runParameters.validationErrors.append(t.description());
}
RunConfiguration *runConfig = runControl->runConfiguration();
@@ -1030,10 +1040,10 @@ void DebuggerRunTool::showMessage(const QString &msg, int channel, int timeout)
m_engine->showMessage(msg, channel, timeout);
switch (channel) {
case AppOutput:
- appendMessage(msg, StdOutFormatSameLine);
+ appendMessage(msg, StdOutFormat);
break;
case AppError:
- appendMessage(msg, StdErrFormatSameLine);
+ appendMessage(msg, StdErrFormat);
break;
case AppStuff:
appendMessage(msg, DebugFormat);
diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h
index adc9de8fef..a971c25807 100644
--- a/src/plugins/debugger/debuggerruncontrol.h
+++ b/src/plugins/debugger/debuggerruncontrol.h
@@ -33,6 +33,8 @@
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
+#include <utils/environmentfwd.h>
+
namespace Debugger {
namespace Internal {
@@ -78,7 +80,7 @@ public:
void setRunControlName(const QString &name);
void setStartMessage(const QString &msg);
void addQmlServerInferiorCommandLineArgumentIfNeeded();
-
+ void modifyDebuggerEnvironment(const Utils::EnvironmentItems &item);
void setCrashParameter(const QString &event);
void addExpectedSignal(const QString &signal);
@@ -127,6 +129,7 @@ public:
void setAbi(const ProjectExplorer::Abi &abi);
Internal::TerminalRunner *terminalRunner() const;
+ DebuggerEngineType cppEngineType() const;
private:
bool fixupParameters();
diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp
index 49aa316571..58ec3663ab 100644
--- a/src/plugins/debugger/debuggertooltipmanager.cpp
+++ b/src/plugins/debugger/debuggertooltipmanager.cpp
@@ -586,7 +586,8 @@ DebuggerToolTipWidget::DebuggerToolTipWidget()
<< item->name << '\t' << item->value << '\t' << item->type << '\n';
});
QClipboard *clipboard = QApplication::clipboard();
- clipboard->setText(text, QClipboard::Selection);
+ if (clipboard->supportsSelection())
+ clipboard->setText(text, QClipboard::Selection);
clipboard->setText(text, QClipboard::Clipboard);
});
diff --git a/src/plugins/debugger/disassembleragent.cpp b/src/plugins/debugger/disassembleragent.cpp
index 97e08b47fe..baa5e7c84d 100644
--- a/src/plugins/debugger/disassembleragent.cpp
+++ b/src/plugins/debugger/disassembleragent.cpp
@@ -337,7 +337,7 @@ void DisassemblerAgent::setContentsToDocument(const DisassemblerLines &contents)
.arg(d->location.functionName()));
const Breakpoints bps = d->engine->breakHandler()->breakpoints();
- for (const Breakpoint bp : bps)
+ for (const Breakpoint &bp : bps)
updateBreakpointMarker(bp);
updateLocationMarker();
diff --git a/src/plugins/debugger/enginemanager.cpp b/src/plugins/debugger/enginemanager.cpp
index 8c2bbca146..1770758b11 100644
--- a/src/plugins/debugger/enginemanager.cpp
+++ b/src/plugins/debugger/enginemanager.cpp
@@ -310,7 +310,7 @@ bool EngineItem::setData(int row, const QVariant &value, int role)
}
if (auto kev = ev.as<QKeyEvent>(QEvent::KeyPress)) {
- if (kev->key() == Qt::Key_Delete && m_engine) {
+ if ((kev->key() == Qt::Key_Delete || kev->key() == Qt::Key_Backspace) && m_engine) {
m_engine->quitDebugger();
} else if (kev->key() == Qt::Key_Return || kev->key() == Qt::Key_Enter) {
d->activateEngineByIndex(row);
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 0fadcc150a..c1cb8c7bad 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -3637,7 +3637,6 @@ void GdbEngine::setupEngine()
//runCommand("define hookpost-stop\nprint 5\nend");
//runCommand("define hook-call\nprint 6\nend");
//runCommand("define hookpost-call\nprint 7\nend");
- runCommand({"set print object on"});
//runCommand("set step-mode on"); // we can't work with that yes
//runCommand("set exec-done-display on");
//runCommand("set print pretty on");
diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp
index 61d9012ccb..03c6bdf7fa 100644
--- a/src/plugins/debugger/lldb/lldbengine.cpp
+++ b/src/plugins/debugger/lldb/lldbengine.cpp
@@ -314,6 +314,11 @@ void LldbEngine::setupEngine()
const bool success = response.data["success"].toInt();
if (success) {
BreakpointManager::claimBreakpointsForEngine(this);
+ // Some extra roundtrip to make sure we end up behind all commands triggered
+ // from claimBreakpointsForEngine().
+ DebuggerCommand cmd3("executeRoundtrip");
+ cmd3.callback = [this](const DebuggerResponse &) { notifyEngineSetupOk(); };
+ runCommand(cmd3);
} else {
notifyEngineSetupFailed();
}
@@ -402,6 +407,8 @@ void LldbEngine::handleResponse(const QString &response)
notifyInferiorPid(item.toProcessHandle());
else if (name == "breakpointmodified")
handleInterpreterBreakpointModified(item);
+ else if (name == "bridgemessage")
+ showMessage(item["msg"].data(), item["channel"].toInt());
}
}
@@ -673,7 +680,7 @@ void LldbEngine::requestModuleSymbols(const QString &moduleName)
{
DebuggerCommand cmd("fetchSymbols");
cmd.arg("module", moduleName);
- cmd.callback = [this, moduleName](const DebuggerResponse &response) {
+ cmd.callback = [moduleName](const DebuggerResponse &response) {
const GdbMi &symbols = response.data["symbols"];
QString moduleName = response.data["module"].data();
Symbols syms;
@@ -903,8 +910,6 @@ void LldbEngine::handleStateNotification(const GdbMi &item)
notifyInferiorStopFailed();
else if (newState == "inferiorill")
notifyInferiorIll();
- else if (newState == "enginesetupok")
- notifyEngineSetupOk();
else if (newState == "enginesetupfailed") {
Core::AsynchronousMessageBox::critical(adapterStartFailed(),
item["error"].data());
diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp
index d4af42714d..550fdc2d20 100644
--- a/src/plugins/debugger/loadcoredialog.cpp
+++ b/src/plugins/debugger/loadcoredialog.cpp
@@ -370,9 +370,9 @@ void AttachCoreDialog::coreFileChanged(const QString &core)
Runnable debugger = DebuggerKitAspect::runnable(k);
CoreInfo cinfo = CoreInfo::readExecutableNameFromCore(debugger, core);
if (!cinfo.foundExecutableName.isEmpty())
- d->symbolFileName->setFileName(FilePath::fromString(cinfo.foundExecutableName));
+ d->symbolFileName->setFilePath(FilePath::fromString(cinfo.foundExecutableName));
else if (!d->symbolFileName->isValid() && !cinfo.rawStringFromCore.isEmpty())
- d->symbolFileName->setFileName(FilePath::fromString(cinfo.rawStringFromCore));
+ d->symbolFileName->setFilePath(FilePath::fromString(cinfo.rawStringFromCore));
}
changed();
}
@@ -412,12 +412,12 @@ void AttachCoreDialog::selectRemoteCoreFile()
QString AttachCoreDialog::localCoreFile() const
{
- return d->localCoreFileName->path();
+ return d->localCoreFileName->filePath().toString();
}
FilePath AttachCoreDialog::symbolFile() const
{
- return d->symbolFileName->fileName();
+ return d->symbolFileName->filePath();
}
void AttachCoreDialog::setSymbolFile(const QString &symbolFileName)
@@ -462,7 +462,7 @@ Kit *AttachCoreDialog::kit() const
QString AttachCoreDialog::overrideStartScript() const
{
- return d->overrideStartScriptFileName->path();
+ return d->overrideStartScriptFileName->filePath().toString();
}
void AttachCoreDialog::setOverrideStartScript(const QString &scriptName)
diff --git a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
index 0bd667f457..ae5e38366c 100644
--- a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
+++ b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
@@ -75,7 +75,7 @@ void CacheDirectoryDialog::setPath(const QString &p)
QString CacheDirectoryDialog::path() const
{
- return m_chooser->path();
+ return m_chooser->filePath().toString();
}
void CacheDirectoryDialog::accept()
diff --git a/src/plugins/debugger/shared/symbolpathsdialog.cpp b/src/plugins/debugger/shared/symbolpathsdialog.cpp
index eb396c2c9b..db0354cca4 100644
--- a/src/plugins/debugger/shared/symbolpathsdialog.cpp
+++ b/src/plugins/debugger/shared/symbolpathsdialog.cpp
@@ -56,7 +56,7 @@ bool SymbolPathsDialog::useSymbolServer() const
QString SymbolPathsDialog::path() const
{
- return ui->pathChooser->path();
+ return ui->pathChooser->filePath().toString();
}
void SymbolPathsDialog::setUseSymbolCache(bool useSymbolCache)
diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp
index 51d27228d1..d1af61e2c7 100644
--- a/src/plugins/debugger/stackhandler.cpp
+++ b/src/plugins/debugger/stackhandler.cpp
@@ -479,7 +479,8 @@ void StackHandler::copyContentsToClipboard()
});
QClipboard *clipboard = QApplication::clipboard();
- clipboard->setText(str, QClipboard::Selection);
+ if (clipboard->supportsSelection())
+ clipboard->setText(str, QClipboard::Selection);
clipboard->setText(str, QClipboard::Clipboard);
}
diff --git a/src/plugins/debugger/unstartedappwatcherdialog.cpp b/src/plugins/debugger/unstartedappwatcherdialog.cpp
index c27ff5f72e..2ef8c67588 100644
--- a/src/plugins/debugger/unstartedappwatcherdialog.cpp
+++ b/src/plugins/debugger/unstartedappwatcherdialog.cpp
@@ -121,7 +121,7 @@ UnstartedAppWatcherDialog::UnstartedAppWatcherDialog(QWidget *parent)
if (isLocal(runConfig)) {
resetExecutable->setEnabled(true);
connect(resetExecutable, &QPushButton::clicked, this, [this, runnable] {
- m_pathChooser->setFileName(runnable.executable);
+ m_pathChooser->setFilePath(runnable.executable);
});
}
}
@@ -256,7 +256,7 @@ void UnstartedAppWatcherDialog::startStopTimer(bool start)
void UnstartedAppWatcherDialog::findProcess()
{
- const QString &appName = Utils::FileUtils::normalizePathName(m_pathChooser->path());
+ const QString &appName = Utils::FileUtils::normalizePathName(m_pathChooser->filePath().toString());
DeviceProcessItem fallback;
foreach (const DeviceProcessItem &p, DeviceProcessList::localProcesses()) {
if (Utils::FileUtils::normalizePathName(p.exe) == appName) {
@@ -291,8 +291,8 @@ void UnstartedAppWatcherDialog::kitChanged()
bool UnstartedAppWatcherDialog::checkExecutableString() const
{
- if (!m_pathChooser->path().isEmpty()) {
- QFileInfo fileInfo(m_pathChooser->path());
+ if (!m_pathChooser->filePath().toString().isEmpty()) {
+ QFileInfo fileInfo(m_pathChooser->filePath().toString());
return (fileInfo.exists() && fileInfo.isFile());
}
return false;
diff --git a/src/plugins/debugger/uvsc/uvscclient.cpp b/src/plugins/debugger/uvsc/uvscclient.cpp
index 33889646ed..3b4aa43765 100644
--- a/src/plugins/debugger/uvsc/uvscclient.cpp
+++ b/src/plugins/debugger/uvsc/uvscclient.cpp
@@ -43,7 +43,7 @@ constexpr int kMaximumRegisterGroupsCount = 128;
constexpr int kMaximumRegisterEnumsCount = 512;
constexpr int kMaximumVarinfosCount = 256;
constexpr int kMaximumValueBitsSize = 32;
-constexpr int kMaximumBreakpointResponseSize = 1024;
+constexpr int kMaximumBreakpointEnumsCount = 128;
constexpr int kMaximumDisassembledBytesCount = 1024;
const QEvent::Type kUvscMsgEventType = static_cast<QEvent::Type>(QEvent::User + 1);
@@ -691,6 +691,41 @@ bool UvscClient::inspectWatcher(const QStringList &expandedWatcherINames,
return true;
}
+bool UvscClient::fetchMemory(quint64 address, QByteArray &data)
+{
+ if (data.isEmpty())
+ data.resize(sizeof(quint8));
+
+ QByteArray amem = UvscUtils::encodeAmem(address, data);
+ const auto amemPtr = reinterpret_cast<AMEM *>(amem.data());
+ const UVSC_STATUS st = ::UVSC_DBG_MEM_READ(m_descriptor, amemPtr, amem.size());
+ if (st != UVSC_STATUS_SUCCESS) {
+ setError(RuntimeError);
+ return false;
+ }
+
+ data = QByteArray(reinterpret_cast<char *>(&amemPtr->bytes),
+ amemPtr->bytesCount);
+ return true;
+}
+
+bool UvscClient::changeMemory(quint64 address, const QByteArray &data)
+{
+ if (data.isEmpty()) {
+ setError(RuntimeError);
+ return false;
+ }
+
+ QByteArray amem = UvscUtils::encodeAmem(address, data);
+ const auto amemPtr = reinterpret_cast<AMEM *>(amem.data());
+ const UVSC_STATUS st = ::UVSC_DBG_MEM_WRITE(m_descriptor, amemPtr, amem.size());
+ if (st != UVSC_STATUS_SUCCESS) {
+ setError(RuntimeError);
+ return false;
+ }
+ return true;
+}
+
bool UvscClient::disassemblyAddress(quint64 address, QByteArray &result)
{
if (!checkConnection())
@@ -764,22 +799,32 @@ bool UvscClient::createBreakpoint(const QString &exp, quint32 &tickMark, quint64
if (!checkConnection())
return false;
- QByteArray bkparm = UvscUtils::encodeBreakPoint(BRKTYPE_EXEC, exp);
- QByteArray bkrsp(kMaximumBreakpointResponseSize, 0);
- qint32 bkrspLength = bkrsp.size();
- const UVSC_STATUS st = ::UVSC_DBG_CREATE_BP(m_descriptor,
- reinterpret_cast<BKPARM *>(bkparm.data()),
- bkparm.size(),
- reinterpret_cast<BKRSP *>(bkrsp.data()),
- &bkrspLength);
- if (st != UVSC_STATUS_SUCCESS) {
- setError(RuntimeError);
+ // Magic workaround to prevent the stalling.
+ if (!controlHiddenBreakpoint(exp))
+ return false;
+
+ // Execute command to create the BP.
+ const QString setCmd = QStringLiteral("BS %1").arg(exp);
+ QString setCmdOutput;
+ if (!executeCommand(setCmd, setCmdOutput))
+ return false;
+
+ std::vector<BKRSP> bpenums;
+ if (!enumerateBreakpoints(bpenums))
+ return false;
+
+ const auto bpenumBegin = bpenums.cbegin();
+ const auto bpenumEnd = bpenums.cend();
+ const auto bpenumIt = std::find_if(bpenumBegin, bpenumEnd, [exp](const BKRSP &bpenum) {
+ const QString bpexp = QString::fromLatin1(reinterpret_cast<const char *>(bpenum.expressionBuffer),
+ bpenum.expressionLength).trimmed();
+ return bpexp.contains(exp);
+ });
+ if (bpenumIt == bpenumEnd)
return false;
- }
- const auto bkrspPtr = reinterpret_cast<const BKRSP *>(bkrsp.constData());
- tickMark = bkrspPtr->tickMark;
- address = bkrspPtr->address;
+ tickMark = bpenumIt->tickMark;
+ address = bpenumIt->address;
if (!addressToFileLine(address, fileName, function, line))
return false;
@@ -794,11 +839,9 @@ bool UvscClient::deleteBreakpoint(quint32 tickMark)
BKCHG bkchg = {};
bkchg.type = CHG_KILLBP;
bkchg.tickMark = tickMark;
- QByteArray bkrsp(kMaximumBreakpointResponseSize, 0);
- qint32 bkrspLength = bkrsp.size();
- const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg),
- reinterpret_cast<BKRSP *>(bkrsp.data()),
- &bkrspLength);
+ BKRSP bkrsp = {};
+ qint32 bkrspLength = sizeof(bkrsp);
+ const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg), &bkrsp, &bkrspLength);
if (st != UVSC_STATUS_SUCCESS) {
setError(RuntimeError);
return false;
@@ -814,11 +857,9 @@ bool UvscClient::enableBreakpoint(quint32 tickMark)
BKCHG bkchg = {};
bkchg.type = CHG_ENABLEBP;
bkchg.tickMark = tickMark;
- QByteArray bkrsp(kMaximumBreakpointResponseSize, 0);
- qint32 bkrspLength = bkrsp.size();
- const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg),
- reinterpret_cast<BKRSP *>(bkrsp.data()),
- &bkrspLength);
+ BKRSP bkrsp = {};
+ qint32 bkrspLength = sizeof(bkrsp);
+ const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg), &bkrsp, &bkrspLength);
if (st != UVSC_STATUS_SUCCESS) {
setError(RuntimeError);
return false;
@@ -834,11 +875,9 @@ bool UvscClient::disableBreakpoint(quint32 tickMark)
BKCHG bkchg = {};
bkchg.type = CHG_DISABLEBP;
bkchg.tickMark = tickMark;
- QByteArray bkrsp(kMaximumBreakpointResponseSize, 0);
- qint32 bkrspLength = bkrsp.size();
- const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg),
- reinterpret_cast<BKRSP *>(bkrsp.data()),
- &bkrspLength);
+ BKRSP bkrsp = {};
+ qint32 bkrspLength = sizeof(bkrsp);
+ const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg), &bkrsp, &bkrspLength);
if (st != UVSC_STATUS_SUCCESS) {
setError(RuntimeError);
return false;
@@ -846,6 +885,69 @@ bool UvscClient::disableBreakpoint(quint32 tickMark)
return true;
}
+bool UvscClient::controlHiddenBreakpoint(const QString &exp)
+{
+ if (!checkConnection())
+ return false;
+
+ // It is a magic workaround to prevent the UVSC bug when the break-point
+ // creation may stall. A problem is that sometime the UVSC_DBG_CREATE_BP
+ // function blocks and returns then with the timeout error when the original
+ // break-point contains the full expression including the line number.
+ //
+ // It can be avoided with helps of creation and then deletion of the
+ // 'fake hidden' break-point with the same expression excluding the line
+ // number, before creation of an original break-point.
+
+ const int slashIndex = exp.lastIndexOf('\\');
+ if (slashIndex == -1 || (slashIndex + 1) == exp.size())
+ return true;
+
+ BKRSP bkrsp = {};
+
+ const QString hiddenExp = exp.mid(0, slashIndex);
+ QByteArray bkparm = UvscUtils::encodeBreakPoint(BRKTYPE_EXEC, hiddenExp);
+ qint32 bkrspLength = sizeof(bkrsp);
+ UVSC_STATUS st = ::UVSC_DBG_CREATE_BP(m_descriptor,
+ reinterpret_cast<BKPARM *>(bkparm.data()),
+ bkparm.size(),
+ &bkrsp, &bkrspLength);
+ if (st != UVSC_STATUS_SUCCESS) {
+ setError(RuntimeError);
+ return false;
+ }
+
+ BKCHG bkchg = {};
+ bkchg.type = CHG_KILLBP;
+ bkchg.tickMark = bkrsp.tickMark;
+ bkrspLength = sizeof(bkrsp);
+ st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg), &bkrsp, &bkrspLength);
+ if (st != UVSC_STATUS_SUCCESS) {
+ setError(RuntimeError);
+ return false;
+ }
+
+ return true;
+}
+
+bool UvscClient::enumerateBreakpoints(std::vector<BKRSP> &bpenums)
+{
+ if (!checkConnection())
+ return false;
+
+ bpenums.resize(kMaximumBreakpointEnumsCount);
+ qint32 bpenumsCount = kMaximumBreakpointEnumsCount;
+ std::vector<qint32> indexes(bpenumsCount, 0);
+ const UVSC_STATUS st = ::UVSC_DBG_ENUMERATE_BP(m_descriptor, bpenums.data(),
+ indexes.data(), &bpenumsCount);
+ if (st != UVSC_STATUS_SUCCESS) {
+ setError(RuntimeError);
+ return false;
+ }
+ bpenums.resize(bpenumsCount);
+ return true;
+}
+
bool UvscClient::calculateExpression(const QString &exp, QByteArray &)
{
if (!checkConnection())
@@ -1097,5 +1199,36 @@ bool UvscClient::addressToFileLine(quint64 address, QString &fileName,
return true;
}
+bool UvscClient::executeCommand(const QString &cmd, QString &output)
+{
+ if (!checkConnection())
+ return false;
+
+ EXECCMD exeCmd = UvscUtils::encodeCommand(cmd);
+ UVSC_STATUS st = ::UVSC_DBG_EXEC_CMD(m_descriptor, &exeCmd, sizeof(exeCmd.command));
+ if (st != UVSC_STATUS_SUCCESS) {
+ setError(RuntimeError);
+ return false;
+ }
+
+ qint32 outputLength = 0;
+ st = ::UVSC_GetCmdOutputSize(m_descriptor, &outputLength);
+ if (st != UVSC_STATUS_SUCCESS) {
+ setError(RuntimeError);
+ return false;
+ }
+
+ QByteArray data(outputLength, 0);
+ st = UVSC_GetCmdOutput(m_descriptor, reinterpret_cast<qint8 *>(data.data()), data.size());
+ if (st != UVSC_STATUS_SUCCESS) {
+ setError(RuntimeError);
+ return false;
+ }
+
+ // Note: UVSC API support only ASCII!
+ output = QString::fromLatin1(data);
+ return true;
+}
+
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/uvsc/uvscclient.h b/src/plugins/debugger/uvsc/uvscclient.h
index a602622a2b..98b001ac4e 100644
--- a/src/plugins/debugger/uvsc/uvscclient.h
+++ b/src/plugins/debugger/uvsc/uvscclient.h
@@ -36,6 +36,7 @@ QT_END_NAMESPACE
// From UVSC api.
struct STACKENUM;
+struct BKRSP;
namespace Utils { class FilePath; }
@@ -87,6 +88,9 @@ public:
bool fetchWatchers(const QStringList &expandedWatcherINames,
const std::vector<std::pair<QString, QString>> &rootWatchers, GdbMi &data);
+ bool fetchMemory(quint64 address, QByteArray &data);
+ bool changeMemory(quint64 address, const QByteArray &data);
+
bool disassemblyAddress(quint64 address, QByteArray &result);
bool setRegisterValue(int index, const QString &value);
@@ -138,6 +142,10 @@ private:
void updateLocation(const QByteArray &bpreason);
bool addressToFileLine(quint64 address, QString &fileName, QString &function, quint32 &line);
+ bool controlHiddenBreakpoint(const QString &exp);
+ bool enumerateBreakpoints(std::vector<BKRSP> &bpenums);
+ bool executeCommand(const QString &cmd, QString &output);
+
qint32 m_descriptor = -1;
quint64 m_exitAddress = 0;
UvscError m_error = NoError;
diff --git a/src/plugins/debugger/uvsc/uvscdatatypes.h b/src/plugins/debugger/uvsc/uvscdatatypes.h
index c2ef9d7712..4392d81644 100644
--- a/src/plugins/debugger/uvsc/uvscdatatypes.h
+++ b/src/plugins/debugger/uvsc/uvscdatatypes.h
@@ -610,9 +610,9 @@ struct BKRSP {
quint32 tickMark;
quint64 address;
quint32 expressionLength;
- qint8 expressionBuffer[1];
+ qint8 expressionBuffer[512];
};
-static_assert(sizeof(BKRSP) == 29, "BKRSP size is not 29 bytes");
+static_assert(sizeof(BKRSP) == 540, "BKRSP size is not 540 bytes");
// Breakpoint change data.
struct BKCHG {
diff --git a/src/plugins/debugger/uvsc/uvscengine.cpp b/src/plugins/debugger/uvsc/uvscengine.cpp
index bc796172c1..23b657ac58 100644
--- a/src/plugins/debugger/uvsc/uvscengine.cpp
+++ b/src/plugins/debugger/uvsc/uvscengine.cpp
@@ -32,6 +32,7 @@
#include <debugger/disassemblerlines.h>
#include <debugger/memoryagent.h>
#include <debugger/moduleshandler.h>
+#include <debugger/peripheralregisterhandler.h>
#include <debugger/registerhandler.h>
#include <debugger/stackhandler.h>
#include <debugger/threadshandler.h>
@@ -162,6 +163,9 @@ void UvscEngine::setupEngine()
if (!configureProject(rp))
return;
+
+ // Reload peripheral register description.
+ peripheralRegisterHandler()->updateRegisterGroups();
}
void UvscEngine::runEngine()
@@ -231,6 +235,14 @@ void UvscEngine::setRegisterValue(const QString &name, const QString &value)
reloadRegisters();
}
+void UvscEngine::setPeripheralRegisterValue(quint64 address, quint64 value)
+{
+ const QByteArray data = UvscUtils::encodeU32(value);
+ if (!m_client->changeMemory(address, data))
+ return;
+ reloadPeripheralRegisters();
+}
+
void UvscEngine::executeStepOver(bool byInstruction)
{
notifyInferiorRunRequested();
@@ -332,6 +344,7 @@ void UvscEngine::activateFrame(int index)
gotoCurrentLocation();
updateLocals();
reloadRegisters();
+ reloadPeripheralRegisters();
}
bool UvscEngine::stateAcceptsBreakpointChanges() const
@@ -469,6 +482,17 @@ void UvscEngine::reloadRegisters()
handleReloadRegisters();
}
+void UvscEngine::reloadPeripheralRegisters()
+{
+ if (!isPeripheralRegistersWindowVisible())
+ return;
+
+ const QList<quint64> addresses = peripheralRegisterHandler()->activeRegisters();
+ if (addresses.isEmpty())
+ return; // Nothing to update.
+ handleReloadPeripheralRegisters(addresses);
+}
+
void UvscEngine::reloadFullStack()
{
resetLocation();
@@ -496,6 +520,7 @@ void UvscEngine::updateAll()
handleThreadInfo();
reloadRegisters();
+ reloadPeripheralRegisters();
updateLocals();
}
@@ -608,6 +633,8 @@ void UvscEngine::handleUpdateLocation(quint64 address)
void UvscEngine::handleStartExecution()
{
+ if (state() != InferiorRunRequested)
+ notifyInferiorRunRequested();
notifyInferiorRunOk();
}
@@ -653,6 +680,7 @@ void UvscEngine::handleReloadStack(bool isFull)
if (!m_client->fetchStackFrames(taskId, m_address, data)) {
m_address = 0;
reloadRegisters();
+ reloadPeripheralRegisters();
return;
}
@@ -678,6 +706,19 @@ void UvscEngine::handleReloadRegisters()
}
}
+void UvscEngine::handleReloadPeripheralRegisters(const QList<quint64> &addresses)
+{
+ for (const quint64 address : addresses) {
+ QByteArray data = UvscUtils::encodeU32(0);
+ if (!m_client->fetchMemory(address, data)) {
+ showMessage(tr("UVSC: Fetching peripheral register failed"), LogMisc);
+ } else {
+ const quint32 value = UvscUtils::decodeU32(data);
+ peripheralRegisterHandler()->updateRegister(address, value);
+ }
+ }
+}
+
void UvscEngine::handleUpdateLocals(bool partial)
{
m_inUpdateLocals = false;
diff --git a/src/plugins/debugger/uvsc/uvscengine.h b/src/plugins/debugger/uvsc/uvscengine.h
index 97f843f44c..ace70fd5c5 100644
--- a/src/plugins/debugger/uvsc/uvscengine.h
+++ b/src/plugins/debugger/uvsc/uvscengine.h
@@ -49,6 +49,7 @@ public:
bool hasCapability(unsigned cap) const final;
void setRegisterValue(const QString &name, const QString &value) final;
+ void setPeripheralRegisterValue(quint64 address, quint64 value) final;
void executeStepOver(bool byInstruction) final;
void executeStepIn(bool byInstruction) final;
@@ -72,6 +73,8 @@ public:
void fetchDisassembler(DisassemblerAgent *agent) final;
void reloadRegisters() final;
+ void reloadPeripheralRegisters() final;
+
void reloadFullStack() final;
private slots:
@@ -84,6 +87,7 @@ private slots:
void handleThreadInfo();
void handleReloadStack(bool isFull);
void handleReloadRegisters();
+ void handleReloadPeripheralRegisters(const QList<quint64> &addresses);
void handleUpdateLocals(bool partial);
void handleInsertBreakpoint(const QString &exp, const Breakpoint &bp);
void handleRemoveBreakpoint(const Breakpoint &bp);
diff --git a/src/plugins/debugger/uvsc/uvscutils.cpp b/src/plugins/debugger/uvsc/uvscutils.cpp
index e3b7e8799a..a8e7d97e62 100644
--- a/src/plugins/debugger/uvsc/uvscutils.cpp
+++ b/src/plugins/debugger/uvsc/uvscutils.cpp
@@ -110,6 +110,24 @@ QByteArray encodeAmem(quint64 address, quint32 bytesCount)
return buffer;
}
+QByteArray encodeAmem(quint64 address, const QByteArray &data)
+{
+ QByteArray buffer(sizeof(AMEM) - 1, 0);
+ buffer.append(data);
+ const auto amem = reinterpret_cast<AMEM *>(buffer.data());
+ amem->address = address;
+ amem->bytesCount = data.size();
+ return buffer;
+}
+
+EXECCMD encodeCommand(const QString &cmd)
+{
+ EXECCMD exeCmd = {};
+ exeCmd.useEcho = false;
+ exeCmd.command = encodeSstr(cmd);
+ return exeCmd;
+}
+
TVAL encodeVoidTval()
{
TVAL tval = {};
@@ -238,6 +256,24 @@ QString adjustHexValue(QString hex, const QString &type)
return {};
}
+QByteArray encodeU32(quint32 value)
+{
+ QByteArray data;
+ QDataStream out(&data, QIODevice::WriteOnly);
+ out.setByteOrder(QDataStream::LittleEndian);
+ out << value;
+ return data;
+}
+
+quint32 decodeU32(const QByteArray &data)
+{
+ QDataStream in(data);
+ in.setByteOrder(QDataStream::LittleEndian);
+ quint32 value = 0;
+ in >> value;
+ return value;
+}
+
QString buildLocalId(const VARINFO &varinfo)
{
return QString::number(varinfo.id);
diff --git a/src/plugins/debugger/uvsc/uvscutils.h b/src/plugins/debugger/uvsc/uvscutils.h
index 6295912839..61778f11e5 100644
--- a/src/plugins/debugger/uvsc/uvscutils.h
+++ b/src/plugins/debugger/uvsc/uvscutils.h
@@ -56,6 +56,8 @@ QString decodeAscii(const qint8 *ascii);
QByteArray encodeProjectData(const QStringList &someNames);
QByteArray encodeBreakPoint(BKTYPE type, const QString &exp, const QString &cmd = QString());
QByteArray encodeAmem(quint64 address, quint32 bytesCount);
+QByteArray encodeAmem(quint64 address, const QByteArray &data);
+EXECCMD encodeCommand(const QString &cmd);
TVAL encodeVoidTval();
TVAL encodeIntTval(int value);
TVAL encodeU64Tval(quint64 value);
@@ -65,6 +67,9 @@ VSET encodeU64Vset(quint64 index, const QString &value);
bool isKnownRegister(int type);
QString adjustHexValue(QString hex, const QString &type);
+QByteArray encodeU32(quint32 value);
+quint32 decodeU32(const QByteArray &data);
+
QString buildLocalId(const VARINFO &varinfo);
QString buildLocalEditable(const VARINFO &varinfo);
QString buildLocalNumchild(const VARINFO &varinfo);
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index 066f9be23b..bd473776ef 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -1108,7 +1108,8 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role
}
if (auto kev = ev.as<QKeyEvent>(QEvent::KeyPress)) {
- if (item && kev->key() == Qt::Key_Delete && item->isWatcher()) {
+ if (item && (kev->key() == Qt::Key_Delete || kev->key() == Qt::Key_Backspace)
+ && item->isWatcher()) {
foreach (const QModelIndex &idx, ev.selectedRows())
removeWatchItem(itemForIndex(idx));
return true;
@@ -1595,7 +1596,8 @@ static QString removeWatchActionText(QString exp)
static void copyToClipboard(const QString &clipboardText)
{
QClipboard *clipboard = QApplication::clipboard();
- clipboard->setText(clipboardText, QClipboard::Selection);
+ if (clipboard->supportsSelection())
+ clipboard->setText(clipboardText, QClipboard::Selection);
clipboard->setText(clipboardText, QClipboard::Clipboard);
}
@@ -1909,12 +1911,18 @@ QMenu *WatchModel::createFormatMenu(WatchItem *item, QWidget *parent)
});
}
+ addAction(menu, tr("Reset All Individual Formats"), true, [this]() {
+ theIndividualFormats.clear();
+ saveFormats();
+ m_engine->updateLocals();
+ });
+
menu->addSeparator();
addAction(menu, tr("Change Display for Type \"%1\":").arg(item->type), false);
addCheckableAction(menu, spacer + tr("Automatic"), true, typeFormat == AutomaticFormat,
[this, item] {
- //const QModelIndexList active = activeRows();
+ //const QModelIndexList active = activeRows();
//for (const QModelIndex &idx : active)
// setModelData(LocalsTypeFormatRole, AutomaticFormat, idx);
setTypeFormat(item->type, AutomaticFormat);
@@ -1924,11 +1932,17 @@ QMenu *WatchModel::createFormatMenu(WatchItem *item, QWidget *parent)
for (int format : alternativeFormats) {
addCheckableAction(menu, spacer + nameForFormat(format), true, format == typeFormat,
[this, format, item] {
- setTypeFormat(item->type, format);
- m_engine->updateLocals();
+ setTypeFormat(item->type, format);
+ m_engine->updateLocals();
});
}
+ addAction(menu, tr("Reset All Formats for Types"), true, [this]() {
+ theTypeFormats.clear();
+ saveFormats();
+ m_engine->updateLocals();
+ });
+
return menu;
}