Files
qt-creator/src/plugins/debugger/debuggeractions.cpp
hjk b9e4c98f1d Debugger: Add a settings for gdb's debuginfod feature
Fixes: QTCREATORBUG-28868
Change-Id: I216dbf8b46329c64607c869b5a8e090ef67fabb0
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
2024-02-21 09:31:02 +00:00

311 lines
13 KiB
C++

// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "debuggeractions.h"
#include "commonoptionspage.h"
#include "debuggericons.h"
#include "debuggerinternalconstants.h"
#include "debuggertr.h"
#include "gdb/gdbsettings.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
#include <QDebug>
#include <QGuiApplication>
using namespace Utils;
namespace Debugger::Internal {
// DebuggerSettings
DebuggerSettings &settings()
{
static DebuggerSettings settings;
return settings;
}
DebuggerSettings::DebuggerSettings() :
useAlternatingRowColors{commonSettings().useAlternatingRowColors},
useAnnotationsInMainEditor{commonSettings().useAnnotationsInMainEditor},
useToolTipsInMainEditor{commonSettings().useToolTipsInMainEditor},
closeSourceBuffersOnExit{commonSettings().closeSourceBuffersOnExit},
closeMemoryBuffersOnExit{commonSettings().closeMemoryBuffersOnExit},
raiseOnInterrupt{commonSettings().raiseOnInterrupt},
breakpointsFullPathByDefault{commonSettings().breakpointsFullPathByDefault},
warnOnReleaseBuilds{commonSettings().warnOnReleaseBuilds},
maximalStackDepth{commonSettings().maximalStackDepth},
fontSizeFollowsEditor{commonSettings().fontSizeFollowsEditor},
switchModeOnExit{commonSettings().switchModeOnExit},
showQmlObjectTree{commonSettings().showQmlObjectTree},
stationaryEditorWhileStepping{commonSettings().stationaryEditorWhileStepping},
forceLoggingToConsole{commonSettings().forceLoggingToConsole},
sourcePathMap{commonSettings().sourcePathMap},
registerForPostMortem{*commonSettings().registerForPostMortem},
gdbWatchdogTimeout{gdbSettings().gdbWatchdogTimeout},
skipKnownFrames{gdbSettings().skipKnownFrames},
useMessageBoxForSignals{gdbSettings().useMessageBoxForSignals},
adjustBreakpointLocations{gdbSettings().adjustBreakpointLocations},
useDynamicType{gdbSettings().useDynamicType},
loadGdbInit{gdbSettings().loadGdbInit},
loadGdbDumpers{gdbSettings().loadGdbDumpers},
intelFlavor{gdbSettings().intelFlavor},
usePseudoTracepoints{gdbSettings().usePseudoTracepoints},
useIndexCache{gdbSettings().useIndexCache},
useDebugInfoD{gdbSettings().useDebugInfoD},
gdbStartupCommands{gdbSettings().gdbStartupCommands},
gdbPostAttachCommands{gdbSettings().gdbPostAttachCommands},
targetAsync{gdbSettings().targetAsync},
autoEnrichParameters{gdbSettings().autoEnrichParameters},
breakOnThrow{gdbSettings().breakOnThrow},
breakOnCatch{gdbSettings().breakOnCatch},
breakOnWarning{gdbSettings().breakOnWarning},
breakOnFatal{gdbSettings().breakOnFatal},
breakOnAbort{gdbSettings().breakOnAbort},
enableReverseDebugging{gdbSettings().enableReverseDebugging},
multiInferior{gdbSettings().multiInferior},
// Page 4
useDebuggingHelpers{localsAndExpressionSettings().useDebuggingHelpers},
useCodeModel{localsAndExpressionSettings().useCodeModel},
showThreadNames{localsAndExpressionSettings().showThreadNames},
extraDumperFile{localsAndExpressionSettings().extraDumperFile}, // For loading a file. Recommended.
extraDumperCommands{localsAndExpressionSettings().extraDumperCommands}, // To modify an existing setup.
showStdNamespace{localsAndExpressionSettings().showStdNamespace},
showQtNamespace{localsAndExpressionSettings().showQtNamespace},
showQObjectNames{localsAndExpressionSettings().showQObjectNames},
maximalStringLength{localsAndExpressionSettings().maximalStringLength},
displayStringLimit{localsAndExpressionSettings().displayStringLimit},
defaultArraySize{localsAndExpressionSettings().defaultArraySize}
{
const Key debugModeGroup("DebugMode");
const Key cdbSettingsGroup("CDB2");
settingsDialog.setLabelText(Tr::tr("Configure Debugger..."));
/*
groupBoxPluginDebugging = new QGroupBox(q);
groupBoxPluginDebugging->setTitle(Tr::tr(
"Behavior of Breakpoint Setting in Plugins"));
radioButtonAllPluginBreakpoints = new QRadioButton(groupBoxPluginDebugging);
radioButtonAllPluginBreakpoints->setText(Tr::tr(
"Always try to set breakpoints in plugins automatically"));
radioButtonAllPluginBreakpoints->setToolTip(Tr::tr(
"This is the slowest but safest option."));
radioButtonSelectedPluginBreakpoints = new QRadioButton(groupBoxPluginDebugging);
radioButtonSelectedPluginBreakpoints->setText(Tr::tr(
"Try to set breakpoints in selected plugins"));
radioButtonNoPluginBreakpoints = new QRadioButton(groupBoxPluginDebugging);
radioButtonNoPluginBreakpoints->setText(Tr::tr(
"Never set breakpoints in plugins automatically"));
lineEditSelectedPluginBreakpointsPattern = new QLineEdit(groupBoxPluginDebugging);
labelSelectedPluginBreakpoints = new QLabel(groupBoxPluginDebugging);
labelSelectedPluginBreakpoints->setText(Tr::tr(
"Matching regular expression: "));
*/
//
// View
//
alwaysAdjustColumnWidths.setLabelText(Tr::tr("Always Adjust View Column Widths to Contents"));
alwaysAdjustColumnWidths.setSettingsKey(debugModeGroup, "AlwaysAdjustColumnWidths");
alwaysAdjustColumnWidths.setDefaultValue(true);
logTimeStamps.setLabelText(Tr::tr("Log Time Stamps"));
logTimeStamps.setSettingsKey(debugModeGroup, "LogTimeStamps");
autoDerefPointers.setLabelText(Tr::tr("Dereference Pointers Automatically"));
autoDerefPointers.setDefaultValue(true);
autoDerefPointers.setSettingsKey(debugModeGroup, "AutoDerefPointers");
autoDerefPointers.setToolTip(
"<p>"
+ Tr::tr("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."));
//
// Cdb Options
//
cdbAdditionalArguments.setSettingsKey(cdbSettingsGroup, "AdditionalArguments");
cdbAdditionalArguments.setDisplayStyle(StringAspect::LineEditDisplay);
cdbAdditionalArguments.setLabelText(Tr::tr("Additional arguments:"));
cdbSymbolPaths.setSettingsKey(cdbSettingsGroup, "SymbolPaths");
cdbSourcePaths.setSettingsKey(cdbSettingsGroup, "SourcePaths");
cdbBreakEvents.setSettingsKey(cdbSettingsGroup, "BreakEvent");
cdbBreakOnCrtDbgReport.setSettingsKey(cdbSettingsGroup, "BreakOnCrtDbgReport");
cdbBreakOnCrtDbgReport.setLabelText(msgSetBreakpointAtFunction(Constants::CRT_DEBUG_REPORT));
cdbBreakOnCrtDbgReport.setToolTip(msgSetBreakpointAtFunctionToolTip(Constants::CRT_DEBUG_REPORT,
Tr::tr("Catches runtime error messages caused by assert(), for example.")));
useCdbConsole.setSettingsKey(cdbSettingsGroup, "CDB_Console");
useCdbConsole.setToolTip("<html><head/><body><p>" + Tr::tr(
"Uses CDB's native console for console applications. "
"This overrides the setting in Environment > System. "
"The native console does not prompt on application exit. "
"It is suitable for diagnosing cases in which the application does not "
"start up properly in the configured console and the subsequent attach fails.")
+ "</p></body></html>");
useCdbConsole.setLabelText(Tr::tr("Use CDB &console"));
cdbBreakPointCorrection.setSettingsKey(cdbSettingsGroup, "BreakpointCorrection");
cdbBreakPointCorrection.setDefaultValue(true);
cdbBreakPointCorrection.setToolTip("<html><head/><body><p>" + Tr::tr(
"Attempts to correct the location of a breakpoint based on file and line number should "
"it be in a comment or in a line for which no code is generated. "
"The correction is based on the code model.") + "</p></body></html>");
cdbBreakPointCorrection.setLabelText(Tr::tr("Correct breakpoint location"));
cdbUsePythonDumper.setSettingsKey(cdbSettingsGroup, "UsePythonDumper");
cdbUsePythonDumper.setDefaultValue(true);
cdbUsePythonDumper.setLabelText(Tr::tr("Use Python dumper"));
firstChanceExceptionTaskEntry.setSettingsKey(cdbSettingsGroup, "FirstChanceExceptionTaskEntry");
firstChanceExceptionTaskEntry.setDefaultValue(true);
firstChanceExceptionTaskEntry.setLabelText(Tr::tr("First chance exceptions"));
secondChanceExceptionTaskEntry.setSettingsKey(cdbSettingsGroup, "SecondChanceExceptionTaskEntry");
secondChanceExceptionTaskEntry.setDefaultValue(true);
secondChanceExceptionTaskEntry.setLabelText(Tr::tr("Second chance exceptions"));
ignoreFirstChanceAccessViolation.setSettingsKey(cdbSettingsGroup, "IgnoreFirstChanceAccessViolation");
ignoreFirstChanceAccessViolation.setLabelText(Tr::tr("Ignore first chance access violations"));
//
// Locals & Watchers
sortStructMembers.setSettingsKey(debugModeGroup, "SortStructMembers");
sortStructMembers.setDisplayName(Tr::tr("Sort Members of Classes and Structs Alphabetically"));
sortStructMembers.setLabelText(Tr::tr("Sort members of classes and structs alphabetically"));
sortStructMembers.setDefaultValue(true);
//
// Breakpoints
//
synchronizeBreakpoints.setLabelText(Tr::tr("Synchronize Breakpoints"));
autoQuit.setSettingsKey(debugModeGroup, "AutoQuit");
autoQuit.setLabelText(Tr::tr("Automatically Quit Debugger"));
useToolTipsInLocalsView.setSettingsKey(debugModeGroup, "UseToolTipsInLocalsView");
useToolTipsInLocalsView.setLabelText(Tr::tr("Use Tooltips in Locals View when Debugging"));
useToolTipsInLocalsView.setToolTip("<p>"
+ Tr::tr("Enables tooltips in the locals "
"view during debugging."));
useToolTipsInBreakpointsView.setSettingsKey(debugModeGroup, "UseToolTipsInBreakpointsView");
useToolTipsInBreakpointsView.setLabelText(Tr::tr("Use Tooltips in Breakpoints View when Debugging"));
useToolTipsInBreakpointsView.setToolTip("<p>"
+ Tr::tr("Enables tooltips in the breakpoints "
"view during debugging."));
useToolTipsInStackView.setSettingsKey(debugModeGroup, "UseToolTipsInStackView");
useToolTipsInStackView.setLabelText(Tr::tr("Use Tooltips in Stack View when Debugging"));
useToolTipsInStackView.setToolTip("<p>"
+ Tr::tr("Enables tooltips in the stack "
"view during debugging."));
useToolTipsInStackView.setDefaultValue(true);
allPluginBreakpoints.setSettingsKey(debugModeGroup, "AllPluginBreakpoints");
allPluginBreakpoints.setDefaultValue(true);
selectedPluginBreakpoints.setSettingsKey(debugModeGroup, "SelectedPluginBreakpoints");
noPluginBreakpoints.setSettingsKey(debugModeGroup, "NoPluginBreakpoints");
selectedPluginBreakpointsPattern.setSettingsKey(debugModeGroup, "SelectedPluginBreakpointsPattern");
selectedPluginBreakpointsPattern.setDefaultValue(QString(".*"));
expandStack.setLabelText(Tr::tr("Reload Full Stack"));
createFullBacktrace.setLabelText(Tr::tr("Create Full Backtrace"));
//
// QML Tools
//
const Key qmlInspectorGroup = "QML.Inspector";
showAppOnTop.setSettingsKey(qmlInspectorGroup, "QmlInspector.ShowAppOnTop");
// Page 5
page5.registerAspect(&cdbAdditionalArguments);
page5.registerAspect(&cdbBreakEvents);
page5.registerAspect(&cdbBreakOnCrtDbgReport);
page5.registerAspect(&useCdbConsole);
page5.registerAspect(&cdbBreakPointCorrection);
page5.registerAspect(&cdbUsePythonDumper);
page5.registerAspect(&firstChanceExceptionTaskEntry);
page5.registerAspect(&secondChanceExceptionTaskEntry);
page5.registerAspect(&ignoreFirstChanceAccessViolation);
// Page 6
page6.registerAspect(&cdbSymbolPaths);
page6.registerAspect(&cdbSourcePaths);
// Pageless
all.registerAspect(&autoDerefPointers);
all.registerAspect(&useToolTipsInLocalsView);
all.registerAspect(&alwaysAdjustColumnWidths);
all.registerAspect(&useToolTipsInBreakpointsView);
all.registerAspect(&useToolTipsInStackView);
all.registerAspect(&logTimeStamps);
all.registerAspect(&sortStructMembers);
// Collect all
all.registerAspects(page5);
all.registerAspects(page6);
all.forEachAspect([](BaseAspect *aspect) {
aspect->setAutoApply(false);
// FIXME: Make the positioning part of the LayoutBuilder later
if (auto boolAspect = dynamic_cast<BoolAspect *>(aspect))
boolAspect->setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
});
all.readSettings();
QObject::connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested,
&all, &AspectContainer::writeSettings);
}
QString DebuggerSettings::dump()
{
QStringList msg;
settings().all.forEachAspect([&msg](BaseAspect *aspect) {
Key key = aspect->settingsKey();
if (!key.isEmpty()) {
const int pos = key.view().indexOf('/');
if (pos >= 0)
key = key.toByteArray().mid(pos);
const QString current = aspect->variantValue().toString();
const QString default_ = aspect->defaultVariantValue().toString();
QString setting = stringFromKey(key) + ": " + current + " (default: " + default_ + ')';
if (current != default_)
setting += " ***";
msg << setting;
}
});
msg.sort();
return "Debugger settings:\n" + msg.join('\n');
}
} // Debugger::Internal