// 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 "error.h" #include "frame.h" #include "stack.h" #include "suppression.h" #include #include #include #include #include namespace Valgrind { namespace XmlProtocol { class Error::Private : public QSharedData { public: qint64 unique = 0; qint64 tid = 0; QString what; int kind = 0; QVector stacks; Suppression suppression; quint64 leakedBytes = 0; qint64 leakedBlocks = 0; qint64 hThreadId = -1; bool operator==(const Private &other) const { return unique == other.unique && tid == other.tid && what == other.what && kind == other.kind && stacks == other.stacks && suppression == other.suppression && leakedBytes == other.leakedBytes && leakedBlocks == other.leakedBlocks && hThreadId == other.hThreadId; } }; Error::Error() : d(new Private) { } Error::~Error() = default; Error::Error(const Error &other) = default; void Error::swap(Error &other) { std::swap(d, other.d); } Error &Error::operator=(const Error &other) { Error tmp(other); swap(tmp); return *this; } bool Error::operator ==(const Error &other) const { return *d == *other.d; } bool Error::operator !=(const Error &other) const { return !(*d == *other.d); } Suppression Error::suppression() const { return d->suppression; } void Error::setSuppression(const Suppression &supp) { d->suppression = supp; } qint64 Error::unique() const { return d->unique; } void Error::setUnique(qint64 unique) { d->unique = unique; } qint64 Error::tid() const { return d->tid; } void Error::setTid(qint64 tid) { d->tid = tid; } quint64 Error::leakedBytes() const { return d->leakedBytes; } void Error::setLeakedBytes(quint64 l) { d->leakedBytes = l; } qint64 Error::leakedBlocks() const { return d->leakedBlocks; } void Error::setLeakedBlocks(qint64 b) { d->leakedBlocks = b; } QString Error::what() const { return d->what; } void Error::setWhat(const QString &what) { d->what = what; } int Error::kind() const { return d->kind; } void Error::setKind(int k) { d->kind = k; } QVector Error::stacks() const { return d->stacks; } void Error::setStacks(const QVector &stacks) { d->stacks = stacks; } void Error::setHelgrindThreadId(qint64 id) { d->hThreadId = id; } qint64 Error::helgrindThreadId() const { return d->hThreadId; } QString Error::toXml() const { QString xml; QTextStream stream(&xml); stream << "\n"; stream << " " << d->unique << "\n"; stream << " " << d->tid << "\n"; stream << " " << d->kind << "\n"; if (d->leakedBlocks > 0 && d->leakedBytes > 0) { stream << " \n" << " " << d->what << "\n" << " " << d->leakedBytes << "\n" << " " << d->leakedBlocks << "\n" << " \n"; } else { stream << " " << d->what << "\n"; } for (const Stack &stack : std::as_const(d->stacks)) { if (!stack.auxWhat().isEmpty()) stream << " " << stack.auxWhat() << "\n"; stream << " \n"; const QVector frames = stack.frames(); for (const Frame &frame : frames) { stream << " \n"; stream << " 0x" << QString::number(frame.instructionPointer(), 16) << "\n"; if (!frame.object().isEmpty()) stream << " " << frame.object() << "\n"; if (!frame.functionName().isEmpty()) stream << " " << frame.functionName() << "\n"; if (!frame.directory().isEmpty()) stream << " " << frame.directory() << "\n"; if (!frame.fileName().isEmpty()) stream << " " << frame.fileName() << "\n"; if (frame.line() != -1) stream << " " << frame.line() << ""; stream << " \n"; } stream << " \n"; } stream << "\n"; return xml; } } // namespace XmlProtocol } // namespace Valgrind