2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
#include "valgrindsettings.h"
|
2022-07-08 16:08:27 +02:00
|
|
|
|
|
|
|
|
#include "callgrindcostdelegate.h"
|
|
|
|
|
#include "valgrindtr.h"
|
2023-08-16 22:43:41 +02:00
|
|
|
#include "xmlprotocol/error.h"
|
2021-02-18 14:18:34 +01:00
|
|
|
|
2023-07-19 10:47:51 +02:00
|
|
|
#include <coreplugin/dialogs/ioptionspage.h>
|
2023-08-16 22:43:41 +02:00
|
|
|
|
2023-07-19 10:47:51 +02:00
|
|
|
#include <debugger/analyzer/analyzericons.h>
|
|
|
|
|
#include <debugger/debuggertr.h>
|
|
|
|
|
|
2022-05-17 14:59:01 +02:00
|
|
|
#include <utils/algorithm.h>
|
2021-03-09 17:40:29 +01:00
|
|
|
#include <utils/layoutbuilder.h>
|
2011-03-04 12:15:18 +01:00
|
|
|
#include <utils/qtcassert.h>
|
2021-02-18 14:18:34 +01:00
|
|
|
#include <utils/utilsicons.h>
|
|
|
|
|
|
2021-03-09 17:40:29 +01:00
|
|
|
#include <QListView>
|
2023-07-25 16:29:36 +02:00
|
|
|
#include <QMetaEnum>
|
2021-03-09 17:40:29 +01:00
|
|
|
#include <QPushButton>
|
|
|
|
|
#include <QStandardItemModel>
|
2011-07-12 16:47:32 +02:00
|
|
|
|
2021-02-18 14:18:34 +01:00
|
|
|
using namespace Utils;
|
2011-03-04 12:15:18 +01:00
|
|
|
|
2022-07-08 16:08:27 +02:00
|
|
|
namespace Valgrind::Internal {
|
2011-07-12 16:47:32 +02:00
|
|
|
|
2021-03-09 17:40:29 +01:00
|
|
|
//
|
|
|
|
|
// SuppressionAspect
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
class SuppressionAspectPrivate : public QObject
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
SuppressionAspectPrivate(SuppressionAspect *q, bool global) : q(q), isGlobal(global) {}
|
|
|
|
|
|
|
|
|
|
void slotAddSuppression();
|
|
|
|
|
void slotRemoveSuppression();
|
|
|
|
|
void slotSuppressionSelectionChanged();
|
|
|
|
|
|
|
|
|
|
SuppressionAspect *q;
|
|
|
|
|
const bool isGlobal;
|
|
|
|
|
|
|
|
|
|
QPointer<QPushButton> addEntry;
|
|
|
|
|
QPointer<QPushButton> removeEntry;
|
|
|
|
|
QPointer<QListView> entryList;
|
|
|
|
|
|
|
|
|
|
QStandardItemModel m_model; // The volatile value of this aspect.
|
|
|
|
|
};
|
|
|
|
|
|
2021-09-30 17:12:10 +02:00
|
|
|
void SuppressionAspect::addSuppressionFile(const FilePath &suppression)
|
2021-03-09 17:40:29 +01:00
|
|
|
{
|
2021-09-30 17:12:10 +02:00
|
|
|
FilePaths val = value();
|
2021-09-14 12:37:35 +02:00
|
|
|
val.append(suppression);
|
|
|
|
|
setValue(val);
|
2021-03-09 17:40:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SuppressionAspectPrivate::slotAddSuppression()
|
|
|
|
|
{
|
2021-08-17 16:36:42 +02:00
|
|
|
const FilePaths files =
|
|
|
|
|
FileUtils::getOpenFilePaths(nullptr,
|
2022-07-08 16:08:27 +02:00
|
|
|
Tr::tr("Valgrind Suppression Files"),
|
2023-07-19 09:59:00 +02:00
|
|
|
globalSettings().lastSuppressionDirectory(),
|
2022-07-08 16:08:27 +02:00
|
|
|
Tr::tr("Valgrind Suppression File (*.supp);;All Files (*)"));
|
2021-03-09 17:40:29 +01:00
|
|
|
//dialog.setHistory(conf->lastSuppressionDialogHistory());
|
|
|
|
|
if (!files.isEmpty()) {
|
2021-08-17 16:36:42 +02:00
|
|
|
for (const FilePath &file : files)
|
|
|
|
|
m_model.appendRow(new QStandardItem(file.toString()));
|
2023-07-19 09:59:00 +02:00
|
|
|
globalSettings().lastSuppressionDirectory.setValue(files.at(0).absolutePath());
|
2021-03-09 17:40:29 +01:00
|
|
|
//conf->setLastSuppressionDialogHistory(dialog.history());
|
|
|
|
|
if (!isGlobal)
|
|
|
|
|
q->apply();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SuppressionAspectPrivate::slotRemoveSuppression()
|
|
|
|
|
{
|
|
|
|
|
// remove from end so no rows get invalidated
|
|
|
|
|
QList<int> rows;
|
|
|
|
|
|
|
|
|
|
QStringList removed;
|
|
|
|
|
const QModelIndexList selected = entryList->selectionModel()->selectedIndexes();
|
|
|
|
|
for (const QModelIndex &index : selected) {
|
|
|
|
|
rows << index.row();
|
|
|
|
|
removed << index.data().toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Utils::sort(rows, std::greater<int>());
|
|
|
|
|
|
2022-10-07 14:46:06 +02:00
|
|
|
for (int row : std::as_const(rows))
|
2021-03-09 17:40:29 +01:00
|
|
|
m_model.removeRow(row);
|
|
|
|
|
|
|
|
|
|
if (!isGlobal)
|
|
|
|
|
q->apply();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SuppressionAspectPrivate::slotSuppressionSelectionChanged()
|
|
|
|
|
{
|
|
|
|
|
removeEntry->setEnabled(entryList->selectionModel()->hasSelection());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// SuppressionAspect
|
|
|
|
|
//
|
|
|
|
|
|
2023-05-23 18:30:44 +02:00
|
|
|
SuppressionAspect::SuppressionAspect(AspectContainer *container, bool global)
|
2023-06-26 11:02:42 +02:00
|
|
|
: TypedAspect(container)
|
2021-03-09 17:40:29 +01:00
|
|
|
{
|
|
|
|
|
d = new SuppressionAspectPrivate(this, global);
|
2021-09-14 12:37:35 +02:00
|
|
|
setSettingsKey("Analyzer.Valgrind.SuppressionFiles");
|
2021-03-09 17:40:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SuppressionAspect::~SuppressionAspect()
|
|
|
|
|
{
|
|
|
|
|
delete d;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-14 10:33:01 +02:00
|
|
|
void SuppressionAspect::addToLayout(Layouting::Layout &parent)
|
2021-03-09 17:40:29 +01:00
|
|
|
{
|
|
|
|
|
QTC_CHECK(!d->addEntry);
|
|
|
|
|
QTC_CHECK(!d->removeEntry);
|
|
|
|
|
QTC_CHECK(!d->entryList);
|
|
|
|
|
|
|
|
|
|
using namespace Layouting;
|
|
|
|
|
|
2022-07-08 16:08:27 +02:00
|
|
|
d->addEntry = new QPushButton(Tr::tr("Add..."));
|
|
|
|
|
d->removeEntry = new QPushButton(Tr::tr("Remove"));
|
2021-03-09 17:40:29 +01:00
|
|
|
|
2021-09-14 12:37:35 +02:00
|
|
|
d->entryList = createSubWidget<QListView>();
|
2021-03-09 17:40:29 +01:00
|
|
|
d->entryList->setModel(&d->m_model);
|
|
|
|
|
d->entryList->setSelectionMode(QAbstractItemView::MultiSelection);
|
|
|
|
|
|
|
|
|
|
connect(d->addEntry, &QPushButton::clicked,
|
|
|
|
|
d, &SuppressionAspectPrivate::slotAddSuppression);
|
|
|
|
|
connect(d->removeEntry, &QPushButton::clicked,
|
|
|
|
|
d, &SuppressionAspectPrivate::slotRemoveSuppression);
|
|
|
|
|
connect(d->entryList->selectionModel(), &QItemSelectionModel::selectionChanged,
|
|
|
|
|
d, &SuppressionAspectPrivate::slotSuppressionSelectionChanged);
|
|
|
|
|
|
2023-05-02 17:20:57 +02:00
|
|
|
parent.addItem(Column { Tr::tr("Suppression files:"), st });
|
2021-03-11 19:02:42 +01:00
|
|
|
Row group {
|
|
|
|
|
d->entryList.data(),
|
2022-07-22 18:54:04 +02:00
|
|
|
Column { d->addEntry.data(), d->removeEntry.data(), st }
|
2021-03-09 17:40:29 +01:00
|
|
|
};
|
2023-05-02 17:20:57 +02:00
|
|
|
parent.addItem(Span { 2, group });
|
2021-03-09 17:40:29 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-23 16:53:06 +02:00
|
|
|
void SuppressionAspect::fromMap(const Store &map)
|
2021-03-09 17:40:29 +01:00
|
|
|
{
|
2023-07-20 14:25:13 +02:00
|
|
|
BaseAspect::fromMap(map); // FIXME Looks wrong, as it skips the intermediate level
|
2021-03-09 17:40:29 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-23 16:53:06 +02:00
|
|
|
void SuppressionAspect::toMap(Store &map) const
|
2021-03-09 17:40:29 +01:00
|
|
|
{
|
2021-09-14 12:37:35 +02:00
|
|
|
BaseAspect::toMap(map);
|
2021-03-09 17:40:29 +01:00
|
|
|
}
|
|
|
|
|
|
2023-07-20 14:25:13 +02:00
|
|
|
bool SuppressionAspect::guiToBuffer()
|
2021-03-09 17:40:29 +01:00
|
|
|
{
|
2023-07-20 14:25:13 +02:00
|
|
|
const FilePaths old = m_buffer;
|
2023-07-12 15:41:06 +02:00
|
|
|
m_buffer.clear();
|
2021-03-09 17:40:29 +01:00
|
|
|
for (int i = 0; i < d->m_model.rowCount(); ++i)
|
2023-07-12 15:41:06 +02:00
|
|
|
m_buffer.append(FilePath::fromUserInput(d->m_model.item(i)->text()));
|
2023-07-20 14:25:13 +02:00
|
|
|
return m_buffer != old;
|
2021-03-09 17:40:29 +01:00
|
|
|
}
|
|
|
|
|
|
2023-07-12 15:41:06 +02:00
|
|
|
void SuppressionAspect::bufferToGui()
|
2021-03-09 17:40:29 +01:00
|
|
|
{
|
|
|
|
|
d->m_model.clear();
|
2023-07-12 15:41:06 +02:00
|
|
|
for (const FilePath &file : m_buffer)
|
2023-06-26 11:02:42 +02:00
|
|
|
d->m_model.appendRow(new QStandardItem(file.toUserOutput()));
|
2021-03-09 17:40:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-07-12 16:47:32 +02:00
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// ValgrindBaseSettings
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2023-07-25 13:07:40 +02:00
|
|
|
ValgrindSettings::ValgrindSettings(bool global)
|
2023-05-23 18:30:44 +02:00
|
|
|
: suppressions(this, global)
|
2021-02-18 14:18:34 +01:00
|
|
|
{
|
2023-07-25 13:07:40 +02:00
|
|
|
setSettingsGroup("Analyzer");
|
|
|
|
|
setAutoApply(false);
|
|
|
|
|
|
2021-02-18 14:18:34 +01:00
|
|
|
// Note that this is used twice, once for project settings in the .user files
|
|
|
|
|
// and once for global settings in QtCreator.ini. This uses intentionally
|
|
|
|
|
// the same key to facilitate copying using fromMap/toMap.
|
2023-08-25 13:19:26 +02:00
|
|
|
Key base = "Analyzer.Valgrind.";
|
2021-02-18 14:18:34 +01:00
|
|
|
|
|
|
|
|
valgrindExecutable.setSettingsKey(base + "ValgrindExecutable");
|
|
|
|
|
valgrindExecutable.setDefaultValue("valgrind");
|
|
|
|
|
valgrindExecutable.setExpectedKind(PathChooser::Command);
|
|
|
|
|
valgrindExecutable.setHistoryCompleter("Valgrind.Command.History");
|
2022-07-08 16:08:27 +02:00
|
|
|
valgrindExecutable.setDisplayName(Tr::tr("Valgrind Command"));
|
|
|
|
|
valgrindExecutable.setLabelText(Tr::tr("Valgrind executable:"));
|
2021-02-18 14:18:34 +01:00
|
|
|
if (Utils::HostOsInfo::isWindowsHost()) {
|
|
|
|
|
// On Window we know that we don't have a local valgrind
|
|
|
|
|
// executable, so having the "Browse" button in the path chooser
|
|
|
|
|
// (which is needed for the remote executable) is confusing.
|
|
|
|
|
// FIXME: not deadly, still...
|
|
|
|
|
//valgrindExecutable. ... buttonAtIndex(0)->hide();
|
2011-07-12 16:47:32 +02:00
|
|
|
}
|
|
|
|
|
|
2021-02-18 14:18:34 +01:00
|
|
|
valgrindArguments.setSettingsKey(base + "ValgrindArguments");
|
|
|
|
|
valgrindArguments.setDisplayStyle(StringAspect::LineEditDisplay);
|
2022-07-08 16:08:27 +02:00
|
|
|
valgrindArguments.setLabelText(Tr::tr("Valgrind arguments:"));
|
2021-02-18 14:18:34 +01:00
|
|
|
|
|
|
|
|
selfModifyingCodeDetection.setSettingsKey(base + "SelfModifyingCodeDetection");
|
|
|
|
|
selfModifyingCodeDetection.setDefaultValue(DetectSmcStackOnly);
|
|
|
|
|
selfModifyingCodeDetection.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox);
|
|
|
|
|
selfModifyingCodeDetection.addOption("No");
|
|
|
|
|
selfModifyingCodeDetection.addOption("Only on Stack");
|
|
|
|
|
selfModifyingCodeDetection.addOption("Everywhere");
|
|
|
|
|
selfModifyingCodeDetection.addOption("Everywhere Except in File-backend Mappings");
|
2022-07-08 16:08:27 +02:00
|
|
|
selfModifyingCodeDetection.setLabelText(Tr::tr("Detect self-modifying code:"));
|
2011-07-12 16:47:32 +02:00
|
|
|
|
|
|
|
|
// Memcheck
|
2021-02-18 14:18:34 +01:00
|
|
|
memcheckArguments.setSettingsKey(base + "Memcheck.Arguments");
|
|
|
|
|
memcheckArguments.setDisplayStyle(StringAspect::LineEditDisplay);
|
2023-06-13 15:21:50 +02:00
|
|
|
memcheckArguments.setLabelText(Tr::tr("Extra Memcheck arguments:"));
|
2021-02-18 14:18:34 +01:00
|
|
|
|
|
|
|
|
filterExternalIssues.setSettingsKey(base + "FilterExternalIssues");
|
|
|
|
|
filterExternalIssues.setDefaultValue(true);
|
|
|
|
|
filterExternalIssues.setIcon(Icons::FILTER.icon());
|
2023-05-23 17:49:52 +02:00
|
|
|
filterExternalIssues.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
2022-07-08 16:08:27 +02:00
|
|
|
filterExternalIssues.setLabelText(Tr::tr("Show Project Costs Only"));
|
|
|
|
|
filterExternalIssues.setToolTip(Tr::tr("Show only profiling info that originated from this project source."));
|
2021-02-18 14:18:34 +01:00
|
|
|
|
|
|
|
|
trackOrigins.setSettingsKey(base + "TrackOrigins");
|
|
|
|
|
trackOrigins.setDefaultValue(true);
|
2023-05-23 17:49:52 +02:00
|
|
|
trackOrigins.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
2022-07-08 16:08:27 +02:00
|
|
|
trackOrigins.setLabelText(Tr::tr("Track origins of uninitialized memory"));
|
2021-02-18 14:18:34 +01:00
|
|
|
|
|
|
|
|
showReachable.setSettingsKey(base + "ShowReachable");
|
2023-05-23 17:49:52 +02:00
|
|
|
showReachable.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
2022-07-08 16:08:27 +02:00
|
|
|
showReachable.setLabelText(Tr::tr("Show reachable and indirectly lost blocks"));
|
2021-02-18 14:18:34 +01:00
|
|
|
|
|
|
|
|
leakCheckOnFinish.setSettingsKey(base + "LeakCheckOnFinish");
|
|
|
|
|
leakCheckOnFinish.setDefaultValue(LeakCheckOnFinishSummaryOnly);
|
|
|
|
|
leakCheckOnFinish.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox);
|
2022-07-08 16:08:27 +02:00
|
|
|
leakCheckOnFinish.addOption(Tr::tr("No"));
|
|
|
|
|
leakCheckOnFinish.addOption(Tr::tr("Summary Only"));
|
|
|
|
|
leakCheckOnFinish.addOption(Tr::tr("Full"));
|
|
|
|
|
leakCheckOnFinish.setLabelText(Tr::tr("Check for leaks on finish:"));
|
2021-02-18 14:18:34 +01:00
|
|
|
|
|
|
|
|
numCallers.setSettingsKey(base + "NumCallers");
|
|
|
|
|
numCallers.setDefaultValue(25);
|
2022-07-08 16:08:27 +02:00
|
|
|
numCallers.setLabelText(Tr::tr("Backtrace frame count:"));
|
2011-07-12 16:47:32 +02:00
|
|
|
|
2023-07-25 13:07:40 +02:00
|
|
|
lastSuppressionDirectory.setSettingsKey(base + "LastSuppressionDirectory");
|
|
|
|
|
lastSuppressionDirectory.setVisible(global);
|
|
|
|
|
|
|
|
|
|
lastSuppressionHistory.setSettingsKey(base + "LastSuppressionHistory");
|
|
|
|
|
lastSuppressionHistory.setVisible(global);
|
|
|
|
|
|
2011-07-12 16:47:32 +02:00
|
|
|
// Callgrind
|
|
|
|
|
|
2021-02-18 14:18:34 +01:00
|
|
|
kcachegrindExecutable.setSettingsKey(base + "KCachegrindExecutable");
|
|
|
|
|
kcachegrindExecutable.setDefaultValue("kcachegrind");
|
2022-07-08 16:08:27 +02:00
|
|
|
kcachegrindExecutable.setLabelText(Tr::tr("KCachegrind executable:"));
|
2021-02-18 14:18:34 +01:00
|
|
|
kcachegrindExecutable.setExpectedKind(Utils::PathChooser::Command);
|
2022-07-08 16:08:27 +02:00
|
|
|
kcachegrindExecutable.setDisplayName(Tr::tr("KCachegrind Command"));
|
2021-02-18 14:18:34 +01:00
|
|
|
|
|
|
|
|
callgrindArguments.setSettingsKey(base + "Callgrind.Arguments");
|
|
|
|
|
callgrindArguments.setDisplayStyle(StringAspect::LineEditDisplay);
|
2023-06-13 15:21:50 +02:00
|
|
|
callgrindArguments.setLabelText(Tr::tr("Extra Callgrind arguments:"));
|
2021-02-18 14:18:34 +01:00
|
|
|
|
|
|
|
|
enableEventToolTips.setDefaultValue(true);
|
|
|
|
|
enableEventToolTips.setSettingsKey(base + "Callgrind.EnableEventToolTips");
|
2023-05-23 17:49:52 +02:00
|
|
|
enableEventToolTips.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
2022-07-08 16:08:27 +02:00
|
|
|
enableEventToolTips.setLabelText(Tr::tr("Show additional information for events in tooltips"));
|
2021-02-18 14:18:34 +01:00
|
|
|
|
|
|
|
|
enableCacheSim.setSettingsKey(base + "Callgrind.EnableCacheSim");
|
2023-05-23 17:49:52 +02:00
|
|
|
enableCacheSim.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
2022-07-08 16:08:27 +02:00
|
|
|
enableCacheSim.setLabelText(Tr::tr("Enable cache simulation"));
|
|
|
|
|
enableCacheSim.setToolTip("<html><head/><body>" + Tr::tr(
|
2021-02-18 14:18:34 +01:00
|
|
|
"<p>Does full cache simulation.</p>\n"
|
|
|
|
|
"<p>By default, only instruction read accesses will be counted (\"Ir\").</p>\n"
|
|
|
|
|
"<p>\n"
|
|
|
|
|
"With cache simulation, further event counters are enabled:\n"
|
|
|
|
|
"<ul><li>Cache misses on instruction reads (\"I1mr\"/\"I2mr\").</li>\n"
|
|
|
|
|
"<li>Data read accesses (\"Dr\") and related cache misses (\"D1mr\"/\"D2mr\").</li>\n"
|
|
|
|
|
"<li>Data write accesses (\"Dw\") and related cache misses (\"D1mw\"/\"D2mw\").</li></ul>\n"
|
|
|
|
|
"</p>") + "</body></html>");
|
|
|
|
|
|
|
|
|
|
enableBranchSim.setSettingsKey(base + "Callgrind.EnableBranchSim");
|
2023-05-23 17:49:52 +02:00
|
|
|
enableBranchSim.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
2022-07-08 16:08:27 +02:00
|
|
|
enableBranchSim.setLabelText(Tr::tr("Enable branch prediction simulation"));
|
|
|
|
|
enableBranchSim.setToolTip("<html><head/><body>\n" + Tr::tr(
|
2021-02-18 14:18:34 +01:00
|
|
|
"<p>Does branch prediction simulation.</p>\n"
|
|
|
|
|
"<p>Further event counters are enabled: </p>\n"
|
|
|
|
|
"<ul><li>Number of executed conditional branches and related predictor misses (\n"
|
|
|
|
|
"\"Bc\"/\"Bcm\").</li>\n"
|
|
|
|
|
"<li>Executed indirect jumps and related misses of the jump address predictor (\n"
|
|
|
|
|
"\"Bi\"/\"Bim\").)</li></ul>") + "</body></html>");
|
|
|
|
|
|
|
|
|
|
collectSystime.setSettingsKey(base + "Callgrind.CollectSystime");
|
2023-05-23 17:49:52 +02:00
|
|
|
collectSystime.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
2022-07-08 16:08:27 +02:00
|
|
|
collectSystime.setLabelText(Tr::tr("Collect system call time"));
|
|
|
|
|
collectSystime.setToolTip(Tr::tr("Collects information for system call times."));
|
2021-02-18 14:18:34 +01:00
|
|
|
|
2023-05-23 17:49:52 +02:00
|
|
|
collectBusEvents.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
2021-02-18 14:18:34 +01:00
|
|
|
collectBusEvents.setSettingsKey(base + "Callgrind.CollectBusEvents");
|
2022-07-08 16:08:27 +02:00
|
|
|
collectBusEvents.setLabelText(Tr::tr("Collect global bus events"));
|
|
|
|
|
collectBusEvents.setToolTip(Tr::tr("Collect the number of global bus events that are executed. "
|
2021-02-18 14:18:34 +01:00
|
|
|
"The event type \"Ge\" is used for these events."));
|
|
|
|
|
|
|
|
|
|
minimumInclusiveCostRatio.setSettingsKey(base + "Callgrind.MinimumCostRatio");
|
|
|
|
|
minimumInclusiveCostRatio.setDefaultValue(0.01);
|
2022-07-08 16:08:27 +02:00
|
|
|
minimumInclusiveCostRatio.setSuffix(Tr::tr("%"));
|
|
|
|
|
minimumInclusiveCostRatio.setLabelText(Tr::tr("Result view: Minimum event cost:"));
|
|
|
|
|
minimumInclusiveCostRatio.setToolTip(Tr::tr("Limits the amount of results the profiler gives you. "
|
2021-02-18 14:18:34 +01:00
|
|
|
"A lower limit will likely increase performance."));
|
|
|
|
|
|
|
|
|
|
visualizationMinimumInclusiveCostRatio.setSettingsKey(base + "Callgrind.VisualisationMinimumCostRatio");
|
|
|
|
|
visualizationMinimumInclusiveCostRatio.setDefaultValue(10.0);
|
2022-07-08 16:08:27 +02:00
|
|
|
visualizationMinimumInclusiveCostRatio.setLabelText(Tr::tr("Visualization: Minimum event cost:"));
|
|
|
|
|
visualizationMinimumInclusiveCostRatio.setSuffix(Tr::tr("%"));
|
2021-02-18 14:18:34 +01:00
|
|
|
|
|
|
|
|
visibleErrorKinds.setSettingsKey(base + "VisibleErrorKinds");
|
|
|
|
|
QList<int> defaultErrorKinds;
|
2023-07-25 16:29:36 +02:00
|
|
|
const QMetaEnum memcheckErrorEnum = QMetaEnum::fromType<XmlProtocol::MemcheckError>();
|
|
|
|
|
for (int i = 0; i < memcheckErrorEnum.keyCount(); ++i)
|
|
|
|
|
defaultErrorKinds << memcheckErrorEnum.value(i);
|
2021-02-18 14:18:34 +01:00
|
|
|
visibleErrorKinds.setDefaultValue(defaultErrorKinds);
|
2023-07-19 10:47:51 +02:00
|
|
|
|
2023-07-25 13:07:40 +02:00
|
|
|
detectCycles.setSettingsKey(base + "Callgrind.CycleDetection");
|
|
|
|
|
detectCycles.setDefaultValue(true);
|
|
|
|
|
detectCycles.setLabelText("O"); // FIXME: Create a real icon
|
|
|
|
|
detectCycles.setToolTip(Tr::tr("Enable cycle detection to properly handle recursive "
|
|
|
|
|
"or circular function calls."));
|
|
|
|
|
detectCycles.setVisible(global);
|
|
|
|
|
|
|
|
|
|
costFormat.setSettingsKey(base + "Callgrind.CostFormat");
|
|
|
|
|
costFormat.setDefaultValue(CostDelegate::FormatRelative);
|
|
|
|
|
costFormat.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox);
|
|
|
|
|
costFormat.setVisible(global);
|
|
|
|
|
|
|
|
|
|
shortenTemplates.setSettingsKey(base + "Callgrind.ShortenTemplates");
|
|
|
|
|
shortenTemplates.setDefaultValue(true);
|
|
|
|
|
shortenTemplates.setLabelText("<>"); // FIXME: Create a real icon
|
|
|
|
|
shortenTemplates.setToolTip(Tr::tr("Remove template parameter lists when displaying function names."));
|
|
|
|
|
shortenTemplates.setVisible(global);
|
|
|
|
|
|
2023-07-19 10:47:51 +02:00
|
|
|
setLayouter([this] {
|
|
|
|
|
using namespace Layouting;
|
|
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
|
Grid generic {
|
|
|
|
|
valgrindExecutable, br,
|
|
|
|
|
valgrindArguments, br,
|
|
|
|
|
selfModifyingCodeDetection, br
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Grid memcheck {
|
|
|
|
|
memcheckArguments, br,
|
|
|
|
|
trackOrigins, br,
|
|
|
|
|
showReachable, br,
|
|
|
|
|
leakCheckOnFinish, br,
|
|
|
|
|
numCallers, br,
|
|
|
|
|
filterExternalIssues, br,
|
|
|
|
|
suppressions
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Grid callgrind {
|
|
|
|
|
callgrindArguments, br,
|
|
|
|
|
kcachegrindExecutable, br,
|
|
|
|
|
minimumInclusiveCostRatio, br,
|
|
|
|
|
visualizationMinimumInclusiveCostRatio, br,
|
|
|
|
|
enableEventToolTips, br,
|
|
|
|
|
Span {
|
|
|
|
|
2,
|
|
|
|
|
Group {
|
|
|
|
|
Column {
|
|
|
|
|
enableCacheSim,
|
|
|
|
|
enableBranchSim,
|
|
|
|
|
collectSystime,
|
|
|
|
|
collectBusEvents,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return Column {
|
|
|
|
|
Group { title(Tr::tr("Valgrind Generic Settings")), generic },
|
|
|
|
|
Group { title(Tr::tr("Memcheck Memory Analysis Options")), memcheck },
|
|
|
|
|
Group { title(Tr::tr("Callgrind Profiling Options")), callgrind },
|
|
|
|
|
st,
|
|
|
|
|
};
|
|
|
|
|
// clang-format on
|
|
|
|
|
});
|
2011-07-12 16:47:32 +02:00
|
|
|
|
2023-07-25 13:07:40 +02:00
|
|
|
if (global) {
|
|
|
|
|
readSettings();
|
|
|
|
|
} else {
|
|
|
|
|
// FIXME: Is this needed?
|
|
|
|
|
connect(this, &AspectContainer::fromMapFinished, [this] {
|
|
|
|
|
// FIXME: Update project page e.g. on "Restore Global", aspects
|
|
|
|
|
// there are 'autoapply', and Aspect::cancel() is normally part of
|
|
|
|
|
// the 'manual apply' machinery.
|
|
|
|
|
setAutoApply(false);
|
|
|
|
|
cancel();
|
|
|
|
|
setAutoApply(true);
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-02-18 14:18:34 +01:00
|
|
|
}
|
|
|
|
|
|
2023-07-25 13:07:40 +02:00
|
|
|
ValgrindSettings &globalSettings()
|
2019-08-28 08:55:28 +02:00
|
|
|
{
|
2023-07-25 13:07:40 +02:00
|
|
|
static ValgrindSettings theSettings{true};
|
|
|
|
|
return theSettings;
|
2011-07-12 16:47:32 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-25 13:23:37 +02:00
|
|
|
// ValgrindSettingsPage
|
2023-07-19 10:47:51 +02:00
|
|
|
|
2023-07-25 13:23:37 +02:00
|
|
|
class ValgrindSettingsPage final : public Core::IOptionsPage
|
2023-07-19 10:47:51 +02:00
|
|
|
{
|
|
|
|
|
public:
|
2023-07-25 13:23:37 +02:00
|
|
|
ValgrindSettingsPage()
|
2023-07-19 10:47:51 +02:00
|
|
|
{
|
|
|
|
|
setId(ANALYZER_VALGRIND_SETTINGS);
|
|
|
|
|
setDisplayName(Tr::tr("Valgrind"));
|
|
|
|
|
setCategory("T.Analyzer");
|
|
|
|
|
setDisplayCategory(::Debugger::Tr::tr("Analyzer"));
|
|
|
|
|
setCategoryIconPath(Analyzer::Icons::SETTINGSCATEGORY_ANALYZER);
|
|
|
|
|
setSettingsProvider([] { return &globalSettings(); });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2023-07-25 13:23:37 +02:00
|
|
|
const ValgrindSettingsPage settingsPage;
|
2023-07-19 10:47:51 +02:00
|
|
|
|
2022-07-08 16:08:27 +02:00
|
|
|
} // Valgrind::Internal
|