forked from qt-creator/qt-creator
Debugger: Sanitize Datatypes, part 1: Breakpoints.
Make address a quint64, linnumber and ignoreCounts int. Reviewed-by: hjk
This commit is contained in:
@@ -139,11 +139,11 @@ BreakpointData *BreakHandler::findBreakpointByNumber(int bpNumber) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BreakHandler::findWatchPointIndexByAddress(const QByteArray &a) const
|
||||
int BreakHandler::findWatchPointIndexByAddress(quint64 address) const
|
||||
{
|
||||
for (int index = size() - 1; index >= 0; --index) {
|
||||
BreakpointData *bd = at(index);
|
||||
if (bd->type == BreakpointData::WatchpointType && bd->address == a)
|
||||
if (bd->type == BreakpointData::WatchpointType && bd->address == address)
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
@@ -151,8 +151,7 @@ int BreakHandler::findWatchPointIndexByAddress(const QByteArray &a) const
|
||||
|
||||
bool BreakHandler::watchPointAt(quint64 address) const
|
||||
{
|
||||
const QByteArray addressBA = QByteArray("0x") + QByteArray::number(address, 16);
|
||||
return findWatchPointIndexByAddress(addressBA) != -1;
|
||||
return findWatchPointIndexByAddress(address) != -1;
|
||||
}
|
||||
|
||||
void BreakHandler::saveBreakpoints()
|
||||
@@ -170,16 +169,16 @@ void BreakHandler::saveBreakpoints()
|
||||
map.insert(_("type"), data->type);
|
||||
if (!data->fileName.isEmpty())
|
||||
map.insert(_("filename"), data->fileName);
|
||||
if (!data->lineNumber.isEmpty())
|
||||
map.insert(_("linenumber"), data->lineNumber);
|
||||
if (data->lineNumber)
|
||||
map.insert(_("linenumber"), QVariant(data->lineNumber));
|
||||
if (!data->funcName.isEmpty())
|
||||
map.insert(_("funcname"), data->funcName);
|
||||
if (!data->address.isEmpty())
|
||||
if (data->address)
|
||||
map.insert(_("address"), data->address);
|
||||
if (!data->condition.isEmpty())
|
||||
map.insert(_("condition"), data->condition);
|
||||
if (!data->ignoreCount.isEmpty())
|
||||
map.insert(_("ignorecount"), data->ignoreCount);
|
||||
if (data->ignoreCount)
|
||||
map.insert(_("ignorecount"), QVariant(data->ignoreCount));
|
||||
if (!data->threadSpec.isEmpty())
|
||||
map.insert(_("threadspec"), data->threadSpec);
|
||||
if (!data->enabled)
|
||||
@@ -207,16 +206,16 @@ void BreakHandler::loadBreakpoints()
|
||||
data->fileName = v.toString();
|
||||
v = map.value(_("linenumber"));
|
||||
if (v.isValid())
|
||||
data->lineNumber = v.toString().toLatin1();
|
||||
data->lineNumber = v.toString().toInt();
|
||||
v = map.value(_("condition"));
|
||||
if (v.isValid())
|
||||
data->condition = v.toString().toLatin1();
|
||||
v = map.value(_("address"));
|
||||
if (v.isValid())
|
||||
data->address = v.toString().toLatin1();
|
||||
data->address = v.toString().toULongLong();
|
||||
v = map.value(_("ignorecount"));
|
||||
if (v.isValid())
|
||||
data->ignoreCount = v.toString().toLatin1();
|
||||
data->ignoreCount = v.toString().toInt();
|
||||
v = map.value(_("threadspec"));
|
||||
if (v.isValid())
|
||||
data->threadSpec = v.toString().toLatin1();
|
||||
@@ -233,7 +232,7 @@ void BreakHandler::loadBreakpoints()
|
||||
if (v.isValid())
|
||||
data->type = BreakpointData::Type(v.toInt());
|
||||
data->setMarkerFileName(data->fileName);
|
||||
data->setMarkerLineNumber(data->lineNumber.toInt());
|
||||
data->setMarkerLineNumber(data->lineNumber);
|
||||
append(data);
|
||||
}
|
||||
//qDebug() << "LOADED BREAKPOINTS" << this << list.size();
|
||||
@@ -302,7 +301,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
|
||||
return data->condition;
|
||||
|
||||
if (role == BreakpointIgnoreCountRole)
|
||||
return data->ignoreCount;
|
||||
return data->ignoreCount ? QVariant(data->ignoreCount) : QVariant(QString());
|
||||
|
||||
if (role == BreakpointThreadSpecRole)
|
||||
return data->threadSpec;
|
||||
@@ -345,8 +344,8 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
|
||||
// FIXME: better?
|
||||
//if (data->bpMultiple && str.isEmpty() && !data->markerFileName.isEmpty())
|
||||
// str = data->markerLineNumber;
|
||||
const QString str = data->pending ? data->lineNumber : data->bpLineNumber;
|
||||
return str.isEmpty() ? empty : str;
|
||||
const int nr = data->pending ? data->lineNumber : data->bpLineNumber;
|
||||
return nr ? QString::number(nr) : empty;
|
||||
}
|
||||
if (role == Qt::UserRole + 1)
|
||||
return data->lineNumber;
|
||||
@@ -360,8 +359,10 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
|
||||
return data->condition;
|
||||
break;
|
||||
case 5:
|
||||
if (role == Qt::DisplayRole)
|
||||
return data->pending ? data->ignoreCount : data->bpIgnoreCount;
|
||||
if (role == Qt::DisplayRole) {
|
||||
const int ignoreCount = data->pending ? data->ignoreCount : data->bpIgnoreCount;
|
||||
return ignoreCount ? QVariant(ignoreCount) : QVariant(QString());
|
||||
}
|
||||
if (role == Qt::ToolTipRole)
|
||||
return tr("Breakpoint will only be hit after being ignored so many times.");
|
||||
if (role == Qt::UserRole + 1)
|
||||
@@ -381,9 +382,17 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
|
||||
break;
|
||||
case 7:
|
||||
if (role == Qt::DisplayRole) {
|
||||
if (data->type == BreakpointData::WatchpointType)
|
||||
return data->address;
|
||||
return data->bpAddress;
|
||||
QString displayValue;
|
||||
const quint64 effectiveAddress = data->type == BreakpointData::WatchpointType ?
|
||||
data->address : data->bpAddress;
|
||||
if (effectiveAddress)
|
||||
displayValue += QString::fromAscii("0x%1").arg(effectiveAddress, 0, 16);
|
||||
if (!data->bpState.isEmpty()) {
|
||||
if (!displayValue.isEmpty())
|
||||
displayValue += QLatin1Char(' ');
|
||||
displayValue += QString::fromAscii(data->bpState);
|
||||
}
|
||||
return displayValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -462,9 +471,9 @@ bool BreakHandler::setData(const QModelIndex &index, const QVariant &value, int
|
||||
return true;
|
||||
|
||||
case BreakpointIgnoreCountRole: {
|
||||
QByteArray val = value.toString().toLatin1();
|
||||
if (val != data->ignoreCount) {
|
||||
data->ignoreCount = val;
|
||||
const int ignoreCount = value.toInt();
|
||||
if (ignoreCount != data->ignoreCount) {
|
||||
data->ignoreCount = ignoreCount;
|
||||
emit layoutChanged();
|
||||
}
|
||||
}
|
||||
@@ -580,6 +589,14 @@ void BreakHandler::removeAllBreakpoints()
|
||||
updateMarkers();
|
||||
}
|
||||
|
||||
BreakpointData *BreakHandler::findBreakpoint(quint64 address) const
|
||||
{
|
||||
foreach (BreakpointData *data, m_bp)
|
||||
if (data->address == address)
|
||||
return data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
BreakpointData *BreakHandler::findBreakpoint(const QString &fileName,
|
||||
int lineNumber, bool useMarkerPosition)
|
||||
{
|
||||
@@ -589,17 +606,30 @@ BreakpointData *BreakHandler::findBreakpoint(const QString &fileName,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BreakHandler::toggleBreakpoint(const QString &fileName, int lineNumber)
|
||||
void BreakHandler::toggleBreakpoint(const QString &fileName, int lineNumber,
|
||||
quint64 address /* = 0 */)
|
||||
{
|
||||
BreakpointData *data = findBreakpoint(fileName, lineNumber, true);
|
||||
if (!data)
|
||||
data = findBreakpoint(fileName, lineNumber, false);
|
||||
BreakpointData *data = 0;
|
||||
do {
|
||||
if (address) {
|
||||
data = findBreakpoint(address);
|
||||
break;
|
||||
}
|
||||
data = findBreakpoint(fileName, lineNumber, true);
|
||||
if (!data)
|
||||
data = findBreakpoint(fileName, lineNumber, false);
|
||||
} while (false);
|
||||
|
||||
if (data) {
|
||||
removeBreakpoint(data);
|
||||
} else {
|
||||
data = new BreakpointData;
|
||||
data->fileName = fileName;
|
||||
data->lineNumber = QByteArray::number(lineNumber);
|
||||
if (address) {
|
||||
data->address = address;
|
||||
} else {
|
||||
data->fileName = fileName;
|
||||
data->lineNumber = lineNumber;
|
||||
}
|
||||
data->pending = true;
|
||||
data->setMarkerFileName(fileName);
|
||||
data->setMarkerLineNumber(lineNumber);
|
||||
@@ -629,7 +659,7 @@ void BreakHandler::breakByFunction(const QString &functionName)
|
||||
const BreakpointData *data = at(index);
|
||||
QTC_ASSERT(data, break);
|
||||
if (data->funcName == functionName && data->condition.isEmpty()
|
||||
&& data->ignoreCount.isEmpty())
|
||||
&& data->ignoreCount == 0)
|
||||
return;
|
||||
}
|
||||
BreakpointData *data = new BreakpointData;
|
||||
@@ -658,7 +688,7 @@ void BreakHandler::initializeFromTemplate(BreakHandler *other)
|
||||
void BreakHandler::storeToTemplate(BreakHandler *other)
|
||||
{
|
||||
other->removeAllBreakpoints();
|
||||
foreach (BreakpointData *data, m_bp)
|
||||
foreach (const BreakpointData *data, m_bp)
|
||||
other->append(data->clone());
|
||||
removeAllBreakpoints();
|
||||
other->updateMarkers();
|
||||
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
// Find a breakpoint matching approximately the data in needle.
|
||||
BreakpointData *findSimilarBreakpoint(const BreakpointData *needle) const;
|
||||
BreakpointData *findBreakpointByNumber(int bpNumber) const;
|
||||
int findWatchPointIndexByAddress(const QByteArray &a) const;
|
||||
int findWatchPointIndexByAddress(quint64 address) const;
|
||||
bool watchPointAt(quint64 address) const;
|
||||
void updateMarkers();
|
||||
bool isActive() const;
|
||||
@@ -91,10 +91,11 @@ public:
|
||||
|
||||
void initializeFromTemplate(BreakHandler *other);
|
||||
void storeToTemplate(BreakHandler *other);
|
||||
void toggleBreakpoint(const QString &fileName, int lineNumber);
|
||||
void toggleBreakpoint(const QString &fileName, int lineNumber, quint64 address = 0);
|
||||
void toggleBreakpointEnabled(const QString &fileName, int lineNumber);
|
||||
BreakpointData *findBreakpoint(const QString &fileName, int lineNumber,
|
||||
bool useMarkerPosition = true);
|
||||
BreakpointData *findBreakpoint(quint64 address) const;
|
||||
|
||||
public slots:
|
||||
void appendBreakpoint(BreakpointData *data);
|
||||
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
// FIXME: Should we tell gdb about the change?
|
||||
// Ignore it for now, as we would require re-compilation
|
||||
// and debugger re-start anyway.
|
||||
if (0 && !m_data->bpLineNumber.isEmpty()) {
|
||||
if (0 && m_data->bpLineNumber) {
|
||||
if (!m_data->bpNumber.trimmed().isEmpty()) {
|
||||
m_data->pending = true;
|
||||
}
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
// the next line that generated code.
|
||||
// FIXME: Do we need yet another data member?
|
||||
if (m_data->bpNumber.trimmed().isEmpty()) {
|
||||
m_data->lineNumber = QByteArray::number(lineNumber);
|
||||
m_data->lineNumber = lineNumber;
|
||||
m_data->handler()->updateMarkers();
|
||||
}
|
||||
}
|
||||
@@ -159,17 +159,16 @@ private:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
BreakpointData::BreakpointData()
|
||||
BreakpointData::BreakpointData() :
|
||||
m_handler(0), enabled(true),
|
||||
pending(true), type(BreakpointType),
|
||||
ignoreCount(0), lineNumber(0), address(0),
|
||||
useFullPath(false),
|
||||
bpIgnoreCount(0), bpLineNumber(0),
|
||||
bpCorrectedLineNumber(0), bpAddress(0),
|
||||
bpMultiple(false), bpEnabled(true),
|
||||
m_markerLineNumber(0), marker(0)
|
||||
{
|
||||
m_handler = 0;
|
||||
enabled = true;
|
||||
pending = true;
|
||||
type = BreakpointType;
|
||||
marker = 0;
|
||||
m_markerLineNumber = 0;
|
||||
bpMultiple = false;
|
||||
bpEnabled = true;
|
||||
useFullPath = false;
|
||||
}
|
||||
|
||||
BreakpointData *BreakpointData::clone() const
|
||||
@@ -193,7 +192,7 @@ BreakpointData *BreakpointData::clone() const
|
||||
data->m_markerLineNumber = m_markerLineNumber;
|
||||
} else {
|
||||
data->m_markerFileName = fileName;
|
||||
data->m_markerLineNumber = lineNumber.toInt();
|
||||
data->m_markerLineNumber = lineNumber;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@@ -233,6 +232,16 @@ void BreakpointData::setMarkerLineNumber(int lineNumber)
|
||||
m_markerLineNumber = lineNumber;
|
||||
}
|
||||
|
||||
static inline void formatAddress(QTextStream &str, quint64 address)
|
||||
{
|
||||
if (address) {
|
||||
str << "0x";
|
||||
str.setIntegerBase(16);
|
||||
str << address;
|
||||
str.setIntegerBase(10);
|
||||
}
|
||||
}
|
||||
|
||||
QString BreakpointData::toToolTip() const
|
||||
{
|
||||
QString rc;
|
||||
@@ -250,6 +259,8 @@ QString BreakpointData::toToolTip() const
|
||||
: type == WatchpointType ? BreakHandler::tr("Watchpoint")
|
||||
: BreakHandler::tr("Unknown breakpoint type"))
|
||||
<< "</td></tr>"
|
||||
<< "<tr><td>" << BreakHandler::tr("State:")
|
||||
<< "</td><td>" << bpState << "</td></tr>"
|
||||
<< "</table><br><hr><table>"
|
||||
<< "<tr><th>" << BreakHandler::tr("Property")
|
||||
<< "</th><th>" << BreakHandler::tr("Requested")
|
||||
@@ -260,54 +271,46 @@ QString BreakpointData::toToolTip() const
|
||||
<< "</td><td>" << fileName << "</td><td>" << QDir::toNativeSeparators(bpFileName) << "</td></tr>"
|
||||
<< "<tr><td>" << BreakHandler::tr("Function Name:")
|
||||
<< "</td><td>" << funcName << "</td><td>" << bpFuncName << "</td></tr>"
|
||||
<< "<tr><td>" << BreakHandler::tr("Line Number:")
|
||||
<< "</td><td>" << lineNumber << "</td><td>" << bpLineNumber << "</td></tr>"
|
||||
<< "<tr><td>" << BreakHandler::tr("Line Number:") << "</td><td>";
|
||||
if (lineNumber)
|
||||
str << lineNumber;
|
||||
str << "</td><td>";
|
||||
if (bpLineNumber)
|
||||
str << bpLineNumber;
|
||||
str << "</td></tr>"
|
||||
<< "<tr><td>" << BreakHandler::tr("Breakpoint Address:")
|
||||
<< "</td><td>" << address << "</td><td>" << bpAddress << "</td></tr>"
|
||||
<< "</td><td>";
|
||||
formatAddress(str, address);
|
||||
str << "</td><td>";
|
||||
formatAddress(str, bpAddress);
|
||||
str << "</td></tr>"
|
||||
<< "<tr><td>" << BreakHandler::tr("Corrected Line Number:")
|
||||
<< "</td><td>-</td><td>" << bpCorrectedLineNumber << "</td></tr>"
|
||||
<< "</td><td>-</td><td>";
|
||||
if (bpCorrectedLineNumber > 0) {
|
||||
str << bpCorrectedLineNumber;
|
||||
} else {
|
||||
str << '-';
|
||||
}
|
||||
str << "</td></tr>"
|
||||
<< "<tr><td>" << BreakHandler::tr("Condition:")
|
||||
<< "</td><td>" << condition << "</td><td>" << bpCondition << "</td></tr>"
|
||||
<< "<tr><td>" << BreakHandler::tr("Ignore Count:")
|
||||
<< "</td><td>" << ignoreCount << "</td><td>" << bpIgnoreCount << "</td></tr>"
|
||||
<< "<tr><td>" << BreakHandler::tr("Ignore Count:") << "</td><td>";
|
||||
if (ignoreCount)
|
||||
str << ignoreCount;
|
||||
str << "</td><td>";
|
||||
if (bpIgnoreCount)
|
||||
str << bpIgnoreCount;
|
||||
str << "</td></tr>"
|
||||
<< "<tr><td>" << BreakHandler::tr("Thread Specification:")
|
||||
<< "</td><td>" << threadSpec << "</td><td>" << bpThreadSpec << "</td></tr>"
|
||||
<< "</table></body></html>";
|
||||
return rc;
|
||||
}
|
||||
|
||||
QString BreakpointData::toString() const
|
||||
{
|
||||
QString rc;
|
||||
QTextStream str(&rc);
|
||||
str << BreakHandler::tr("Marker File:") << ' ' << m_markerFileName << '\n'
|
||||
<< BreakHandler::tr("Marker Line:") << ' ' << m_markerLineNumber << '\n'
|
||||
<< BreakHandler::tr("Breakpoint Number:") << ' ' << bpNumber << '\n'
|
||||
<< BreakHandler::tr("Breakpoint Type:") << ' '
|
||||
<< (type == BreakpointType ? BreakHandler::tr("Breakpoint")
|
||||
: type == WatchpointType ? BreakHandler::tr("Watchpoint")
|
||||
: BreakHandler::tr("Unknown breakpoint type")) << '\n'
|
||||
<< BreakHandler::tr("File Name:") << ' '
|
||||
<< fileName << " -- " << bpFileName << '\n'
|
||||
<< BreakHandler::tr("Function Name:") << ' '
|
||||
<< funcName << " -- " << bpFuncName << '\n'
|
||||
<< BreakHandler::tr("Line Number:") << ' '
|
||||
<< lineNumber << " -- " << bpLineNumber << '\n'
|
||||
<< BreakHandler::tr("Breakpoint Address:") << ' '
|
||||
<< address << " -- " << bpAddress << '\n'
|
||||
<< BreakHandler::tr("Condition:") << ' '
|
||||
<< condition << " -- " << bpCondition << '\n'
|
||||
<< BreakHandler::tr("Ignore Count:") << ' '
|
||||
<< ignoreCount << " -- " << bpIgnoreCount << '\n'
|
||||
<< BreakHandler::tr("Thread Specification:") << ' '
|
||||
<< threadSpec << " -- " << bpThreadSpec << '\n';
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool BreakpointData::isLocatedAt(const QString &fileName_, int lineNumber_,
|
||||
bool useMarkerPosition) const
|
||||
{
|
||||
int line = useMarkerPosition ? m_markerLineNumber : lineNumber.toInt();
|
||||
int line = useMarkerPosition ? m_markerLineNumber : lineNumber;
|
||||
return lineNumber_ == line && fileNameMatch(fileName_, m_markerFileName);
|
||||
}
|
||||
|
||||
@@ -331,6 +334,9 @@ bool BreakpointData::isSimilarTo(const BreakpointData *needle) const
|
||||
&& !needle->bpNumber.startsWith(bpNumber))
|
||||
return false;
|
||||
|
||||
if (address && needle->address && address == needle->address)
|
||||
return true;
|
||||
|
||||
// At least at a position we were looking for.
|
||||
// FIXME: breaks multiple breakpoints at the same location
|
||||
if (!fileName.isEmpty()
|
||||
|
||||
@@ -55,7 +55,6 @@ public:
|
||||
void removeMarker();
|
||||
void updateMarker();
|
||||
QString toToolTip() const;
|
||||
QString toString() const;
|
||||
BreakHandler *handler() { return m_handler; }
|
||||
|
||||
bool isLocatedAt(const QString &fileName, int lineNumber,
|
||||
@@ -86,9 +85,9 @@ public:
|
||||
// This "user requested information" will get stored in the session.
|
||||
QString fileName; // Short name of source file.
|
||||
QByteArray condition; // Condition associated with breakpoint.
|
||||
QByteArray ignoreCount; // Ignore count associated with breakpoint.
|
||||
QByteArray lineNumber; // Line in source file.
|
||||
QByteArray address; // Address for watchpoints.
|
||||
int ignoreCount; // Ignore count associated with breakpoint.
|
||||
int lineNumber; // Line in source file.
|
||||
quint64 address; // Address for watchpoints.
|
||||
QByteArray threadSpec; // Thread specification.
|
||||
QString funcName; // Name of containing function.
|
||||
bool useFullPath; // Should we use the full path when setting the bp?
|
||||
@@ -96,16 +95,17 @@ public:
|
||||
// This is what gdb produced in response.
|
||||
QByteArray bpNumber; // Breakpoint number assigned by the debugger engine.
|
||||
QByteArray bpCondition; // Condition acknowledged by the debugger engine.
|
||||
QByteArray bpIgnoreCount;// Ignore count acknowledged by the debugger engine.
|
||||
int bpIgnoreCount; // Ignore count acknowledged by the debugger engine.
|
||||
QString bpFileName; // File name acknowledged by the debugger engine.
|
||||
QString bpFullName; // Full file name acknowledged by the debugger engine.
|
||||
QByteArray bpLineNumber; // Line number acknowledged by the debugger engine.
|
||||
QByteArray bpCorrectedLineNumber; // Acknowledged by the debugger engine.
|
||||
int bpLineNumber; // Line number acknowledged by the debugger engine.
|
||||
int bpCorrectedLineNumber; // Acknowledged by the debugger engine.
|
||||
QByteArray bpThreadSpec; // Thread spec acknowledged by the debugger engine.
|
||||
QString bpFuncName; // Function name acknowledged by the debugger engine.
|
||||
QByteArray bpAddress; // Address acknowledged by the debugger engine.
|
||||
quint64 bpAddress; // Address acknowledged by the debugger engine.
|
||||
bool bpMultiple; // Happens in constructors/gdb.
|
||||
bool bpEnabled; // Enable/disable command sent.
|
||||
QByteArray bpState; // gdb: <PENDING>, <MULTIPLE>
|
||||
|
||||
void setMarkerFileName(const QString &fileName);
|
||||
QString markerFileName() const { return m_markerFileName; }
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <QtGui/QItemSelectionModel>
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QTreeView>
|
||||
#include <QtGui/QIntValidator>
|
||||
|
||||
|
||||
namespace Debugger {
|
||||
@@ -362,6 +363,7 @@ void BreakWindow::editBreakpoint(const QModelIndexList &list)
|
||||
QAbstractItemModel *m = model();
|
||||
ui.lineEditCondition->setText(
|
||||
m->data(idx, BreakpointConditionRole).toString());
|
||||
ui.lineEditIgnoreCount->setValidator(new QIntValidator(0, 2147483647, ui.lineEditIgnoreCount));
|
||||
ui.lineEditIgnoreCount->setText(
|
||||
m->data(idx, BreakpointIgnoreCountRole).toString());
|
||||
ui.lineEditThreadSpec->setText(
|
||||
|
||||
@@ -44,26 +44,18 @@ CdbCore::BreakPoint breakPointFromBreakPointData(const Debugger::Internal::Break
|
||||
rc.type = bpd.type == Debugger::Internal::BreakpointData::BreakpointType ?
|
||||
CdbCore::BreakPoint::Code : CdbCore::BreakPoint::Data;
|
||||
|
||||
if (rc.type == CdbCore::BreakPoint::Data) {
|
||||
QByteArray addressBA = bpd.address;
|
||||
if (addressBA.startsWith("0x"))
|
||||
addressBA.remove(0, 2);
|
||||
bool ok;
|
||||
rc.address = addressBA.toULongLong(&ok, 16);
|
||||
if (!ok)
|
||||
qWarning("Cdb: Cannot convert watchpoint address '%s'", bpd.address.constData());
|
||||
}
|
||||
rc.address = bpd.address;
|
||||
if (!bpd.threadSpec.isEmpty()) {
|
||||
bool ok;
|
||||
rc.threadId = bpd.threadSpec.toInt(&ok);
|
||||
if (!ok)
|
||||
qWarning("Cdb: Cannot convert breakpoint thread specification '%s'", bpd.address.constData());
|
||||
qWarning("Cdb: Cannot convert breakpoint thread specification '%s'", bpd.threadSpec.constData());
|
||||
}
|
||||
rc.fileName = QDir::toNativeSeparators(bpd.fileName);
|
||||
rc.condition = bpd.condition;
|
||||
rc.funcName = bpd.funcName;
|
||||
rc.ignoreCount = bpd.ignoreCount.isEmpty() ? 0 : bpd.ignoreCount.toInt();
|
||||
rc.lineNumber = bpd.lineNumber.isEmpty() ? -1 : bpd.lineNumber.toInt();
|
||||
rc.ignoreCount = bpd.ignoreCount;
|
||||
rc.lineNumber = bpd.lineNumber;
|
||||
rc.oneShot = false;
|
||||
rc.enabled = bpd.enabled;
|
||||
return rc;
|
||||
@@ -129,7 +121,7 @@ bool synchronizeBreakPoints(CIDebugControl* debugControl,
|
||||
updateMarkers = true;
|
||||
nbd->pending = false;
|
||||
nbd->bpNumber = QByteArray::number(uint(id));
|
||||
nbd->bpAddress = "0x" + QByteArray::number(address, 16);
|
||||
nbd->bpAddress = address;
|
||||
// Take over rest as is
|
||||
nbd->bpCondition = nbd->condition;
|
||||
nbd->bpIgnoreCount = nbd->ignoreCount;
|
||||
|
||||
@@ -394,5 +394,19 @@ QString DisassemblerViewAgent::address() const
|
||||
return d->frame.address;
|
||||
}
|
||||
|
||||
// Return address of an assembly line "0x0dfd bla"
|
||||
quint64 DisassemblerViewAgent::addressFromDisassemblyLine(const QString &line)
|
||||
{
|
||||
const int pos = line.indexOf(QLatin1Char(' '));
|
||||
if (pos < 0)
|
||||
return 0;
|
||||
QString addressS = line.left(pos);
|
||||
if (addressS.startsWith(QLatin1String("0x")))
|
||||
addressS.remove(0, 2);
|
||||
bool ok;
|
||||
const quint64 address = addressS.toULongLong(&ok, 16);
|
||||
return ok ? address : quint64(0);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
@@ -97,6 +97,9 @@ public:
|
||||
void cleanup();
|
||||
bool isMixed() const;
|
||||
|
||||
// Return address of an assembly line "0x0dfd bla"
|
||||
static quint64 addressFromDisassemblyLine(const QString &line);
|
||||
|
||||
private:
|
||||
DisassemblerViewAgentPrivate *d;
|
||||
};
|
||||
|
||||
@@ -325,10 +325,11 @@ void DebuggerEnginePrivate::breakpointSetRemoveMarginActionTriggered()
|
||||
QAction *act = qobject_cast<QAction *>(sender());
|
||||
QTC_ASSERT(act, return);
|
||||
QList<QVariant> list = act->data().toList();
|
||||
QTC_ASSERT(list.size() == 2, return);
|
||||
QTC_ASSERT(list.size() >= 3, return);
|
||||
const QString fileName = list.at(0).toString();
|
||||
const int lineNumber = list.at(1).toInt();
|
||||
m_breakHandler.toggleBreakpoint(fileName, lineNumber);
|
||||
const quint64 address = list.at(2).toULongLong();
|
||||
m_breakHandler.toggleBreakpoint(fileName, lineNumber, address);
|
||||
}
|
||||
|
||||
void DebuggerEnginePrivate::breakpointEnableDisableMarginActionTriggered()
|
||||
@@ -352,30 +353,30 @@ void DebuggerEnginePrivate::handleContextMenuRequest(const QVariant ¶meters)
|
||||
QMenu *menu = (QMenu *)(list.at(2).value<quint64>());
|
||||
|
||||
BreakpointData *data = 0;
|
||||
QString position;
|
||||
QString fileName;
|
||||
quint64 address = 0;
|
||||
if (editor->property("DisassemblerView").toBool()) {
|
||||
fileName = editor->file()->fileName();
|
||||
QString line = editor->contents()
|
||||
.section('\n', lineNumber - 1, lineNumber - 1);
|
||||
position = _("*") + fileName;
|
||||
BreakpointData needle;
|
||||
needle.bpAddress = line.left(line.indexOf(QLatin1Char(' '))).toLatin1();
|
||||
needle.bpLineNumber = "-1";
|
||||
address = needle.address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
|
||||
needle.bpLineNumber = -1;
|
||||
data = m_breakHandler.findSimilarBreakpoint(&needle);
|
||||
} else {
|
||||
fileName = editor->file()->fileName();
|
||||
position = fileName + QString(":%1").arg(lineNumber);
|
||||
data = m_breakHandler.findBreakpoint(fileName, lineNumber);
|
||||
}
|
||||
|
||||
QList<QVariant> args;
|
||||
args.append(fileName);
|
||||
args.append(lineNumber);
|
||||
args.append(address);
|
||||
|
||||
if (data) {
|
||||
// existing breakpoint
|
||||
QAction *act = new QAction(tr("Remove Breakpoint"), menu);
|
||||
const QString number = QString::fromAscii(data->bpNumber);
|
||||
QAction *act = new QAction(tr("Remove Breakpoint %1").arg(number), menu);
|
||||
act->setData(args);
|
||||
connect(act, SIGNAL(triggered()),
|
||||
this, SLOT(breakpointSetRemoveMarginActionTriggered()));
|
||||
@@ -383,16 +384,19 @@ void DebuggerEnginePrivate::handleContextMenuRequest(const QVariant ¶meters)
|
||||
|
||||
QAction *act2;
|
||||
if (data->enabled)
|
||||
act2 = new QAction(tr("Disable Breakpoint"), menu);
|
||||
act2 = new QAction(tr("Disable Breakpoint %1").arg(number), menu);
|
||||
else
|
||||
act2 = new QAction(tr("Enable Breakpoint"), menu);
|
||||
act2 = new QAction(tr("Enable Breakpoint %1").arg(number), menu);
|
||||
act2->setData(args);
|
||||
connect(act2, SIGNAL(triggered()),
|
||||
this, SLOT(breakpointEnableDisableMarginActionTriggered()));
|
||||
menu->addAction(act2);
|
||||
} else {
|
||||
// non-existing
|
||||
QAction *act = new QAction(tr("Set Breakpoint"), menu);
|
||||
const QString text = address ?
|
||||
tr("Set Breakpoint at 0x%1").arg(address, 0, 16) :
|
||||
tr("Set Breakpoint at line %1").arg(lineNumber);
|
||||
QAction *act = new QAction(text, menu);
|
||||
act->setData(args);
|
||||
connect(act, SIGNAL(triggered()),
|
||||
this, SLOT(breakpointSetRemoveMarginActionTriggered()));
|
||||
|
||||
@@ -2061,18 +2061,23 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointData *data, const GdbMi &b
|
||||
} else if (child.hasName("addr")) {
|
||||
// <MULTIPLE> happens in constructors. In this case there are
|
||||
// _two_ fields named "addr" in the response. On Linux that is...
|
||||
if (child.data() == "<MULTIPLE>")
|
||||
data->bpMultiple = true;
|
||||
else
|
||||
data->bpAddress = child.data();
|
||||
if (child.data().startsWith("0x")) {
|
||||
data->bpAddress = child.data().mid(2).toULongLong(0, 16);
|
||||
} else {
|
||||
data->bpState = child.data();
|
||||
if (child.data() == "<MULTIPLE>")
|
||||
data->bpMultiple = true;
|
||||
}
|
||||
} else if (child.hasName("file")) {
|
||||
file = child.data();
|
||||
} else if (child.hasName("fullname")) {
|
||||
fullName = child.data();
|
||||
} else if (child.hasName("line")) {
|
||||
data->bpLineNumber = child.data();
|
||||
if (child.data().toInt() && data->bpCorrectedLineNumber.isEmpty())
|
||||
data->setMarkerLineNumber(child.data().toInt());
|
||||
bool ok;
|
||||
const int lineNumber = child.data().toInt(&ok);
|
||||
data->bpLineNumber = lineNumber;
|
||||
if (ok && data->bpCorrectedLineNumber <= 0)
|
||||
data->setMarkerLineNumber(lineNumber);
|
||||
} else if (child.hasName("cond")) {
|
||||
data->bpCondition = child.data();
|
||||
// gdb 6.3 likes to "rewrite" conditions. Just accept that fact.
|
||||
@@ -2127,18 +2132,25 @@ QString GdbEngine::breakLocation(const QString &file) const
|
||||
return where;
|
||||
}
|
||||
|
||||
static inline QByteArray bpAddressSpec(quint64 address)
|
||||
{
|
||||
return "*0x" + QByteArray::number(address, 16);
|
||||
}
|
||||
|
||||
QByteArray GdbEngine::breakpointLocation(const BreakpointData *data)
|
||||
{
|
||||
if (!data->funcName.isEmpty())
|
||||
return data->funcName.toLatin1();
|
||||
if (data->address)
|
||||
return bpAddressSpec(data->address);
|
||||
// In this case, data->funcName is something like '*0xdeadbeef'
|
||||
if (data->lineNumber.toInt() == 0)
|
||||
if (data->lineNumber == 0)
|
||||
return data->funcName.toLatin1();
|
||||
QString loc = data->useFullPath ? data->fileName : breakLocation(data->fileName);
|
||||
// The argument is simply a C-quoted version of the argument to the
|
||||
// non-MI "break" command, including the "original" quoting it wants.
|
||||
return "\"\\\"" + GdbMi::escapeCString(loc).toLocal8Bit() + "\\\":"
|
||||
+ data->lineNumber + '"';
|
||||
+ QByteArray::number(data->lineNumber) + '"';
|
||||
}
|
||||
|
||||
void GdbEngine::sendInsertBreakpoint(int index)
|
||||
@@ -2147,7 +2159,7 @@ void GdbEngine::sendInsertBreakpoint(int index)
|
||||
// Set up fallback in case of pending breakpoints which aren't handled
|
||||
// by the MI interface.
|
||||
if (data->type == BreakpointData::WatchpointType) {
|
||||
postCommand("watch *" + data->address,
|
||||
postCommand("watch " + bpAddressSpec(data->address),
|
||||
NeedsStop | RebuildBreakpointModel,
|
||||
CB(handleWatchInsert), index);
|
||||
return;
|
||||
@@ -2367,9 +2379,9 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointData *
|
||||
re.setMinimal(true);
|
||||
|
||||
if (re.indexIn(output) != -1) {
|
||||
data->bpAddress = re.cap(1).toLatin1();
|
||||
data->bpAddress = re.cap(1).toULongLong(0, 16);
|
||||
data->bpFuncName = re.cap(2).trimmed();
|
||||
data->bpLineNumber = re.cap(4).toLatin1();
|
||||
data->bpLineNumber = re.cap(4).toInt();
|
||||
QString full = fullName(re.cap(3));
|
||||
if (full.isEmpty()) {
|
||||
// FIXME: This happens without UsePreciseBreakpoints regularly.
|
||||
@@ -2388,7 +2400,7 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointData *
|
||||
// the marker in more cases.
|
||||
if (data->fileName.endsWith(full))
|
||||
full = data->fileName;
|
||||
data->setMarkerLineNumber(data->bpLineNumber.toInt());
|
||||
data->setMarkerLineNumber(data->bpLineNumber);
|
||||
if (data->markerFileName().isEmpty()) {
|
||||
qDebug() << "111";
|
||||
data->setMarkerFileName(full);
|
||||
@@ -2428,9 +2440,9 @@ void GdbEngine::handleInfoLine(const GdbResponse &response)
|
||||
QByteArray ba = response.data.findChild("consolestreamoutput").data();
|
||||
const int pos = ba.indexOf(' ', 5);
|
||||
if (ba.startsWith("Line ") && pos != -1) {
|
||||
const QByteArray line = ba.mid(5, pos - 5);
|
||||
const int line = ba.mid(5, pos - 5).toInt();
|
||||
data->bpCorrectedLineNumber = line;
|
||||
data->setMarkerLineNumber(line.toInt());
|
||||
data->setMarkerLineNumber(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2542,7 +2554,7 @@ void GdbEngine::attemptBreakpointSynchronization()
|
||||
else // Because gdb won't do both changes at a time anyway.
|
||||
if (data->ignoreCount != data->bpIgnoreCount) {
|
||||
// Update ignorecount if needed.
|
||||
QByteArray ic = QByteArray::number(data->ignoreCount.toInt());
|
||||
QByteArray ic = QByteArray::number(data->ignoreCount);
|
||||
postCommand("ignore " + data->bpNumber + ' ' + ic,
|
||||
NeedsStop | RebuildBreakpointModel,
|
||||
CB(handleBreakIgnore), data->bpNumber.toInt());
|
||||
@@ -2564,11 +2576,10 @@ void GdbEngine::attemptBreakpointSynchronization()
|
||||
sendInsertBreakpoint(index);
|
||||
continue;
|
||||
}
|
||||
if (data->bpAddress.startsWith("0x")
|
||||
&& data->bpCorrectedLineNumber.isEmpty()) {
|
||||
if (data->bpAddress && data->bpCorrectedLineNumber == 0) {
|
||||
// Prevent endless loop.
|
||||
data->bpCorrectedLineNumber = " ";
|
||||
postCommand("info line *" + data->bpAddress,
|
||||
data->bpCorrectedLineNumber = -1;
|
||||
postCommand("info line *0x" + QByteArray::number(data->bpAddress, 16),
|
||||
NeedsStop | RebuildBreakpointModel,
|
||||
CB(handleInfoLine), data->bpNumber.toInt());
|
||||
}
|
||||
|
||||
@@ -332,14 +332,14 @@ static QByteArray breakpointLocation(const BreakpointData *data)
|
||||
if (!data->funcName.isEmpty())
|
||||
return data->funcName.toLatin1();
|
||||
// In this case, data->funcName is something like '*0xdeadbeef'
|
||||
if (data->lineNumber.toInt() == 0)
|
||||
if (data->lineNumber == 0)
|
||||
return data->funcName.toLatin1();
|
||||
//QString loc = data->useFullPath ? data->fileName : breakLocation(data->fileName);
|
||||
// The argument is simply a C-quoted version of the argument to the
|
||||
// non-MI "break" command, including the "original" quoting it wants.
|
||||
//return "\"\\\"" + GdbMi::escapeCString(data->fileName).toLocal8Bit() + "\\\":"
|
||||
// + data->lineNumber + '"';
|
||||
return data->fileName.toLocal8Bit() + ":" + data->lineNumber;
|
||||
return data->fileName.toLocal8Bit() + ':' + QByteArray::number(data->lineNumber);
|
||||
}
|
||||
|
||||
void PdbEngine::attemptBreakpointSynchronization()
|
||||
@@ -388,7 +388,7 @@ void PdbEngine::handleBreakInsert(const PdbResponse &response)
|
||||
QByteArray line = response.data.mid(pos2 + 1);
|
||||
data->bpNumber = bpnr;
|
||||
data->bpFileName = _(file);
|
||||
data->bpLineNumber = line;
|
||||
data->bpLineNumber = line.toInt();
|
||||
handler->updateMarkers();
|
||||
}
|
||||
|
||||
|
||||
@@ -439,7 +439,7 @@ void QmlEngine::attemptBreakpointSynchronization()
|
||||
QString processedFilename = data->fileName;
|
||||
if (isShadowBuildProject())
|
||||
processedFilename = toShadowBuildFilename(data->fileName);
|
||||
breakList << qMakePair(processedFilename, data->lineNumber.toInt());
|
||||
breakList << qMakePair(processedFilename, data->lineNumber);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -462,7 +462,7 @@ void ScriptEngine::attemptBreakpointSynchronization()
|
||||
}
|
||||
if (!data->fileName.isEmpty() && data->markerFileName().isEmpty()) {
|
||||
data->setMarkerFileName(data->fileName);
|
||||
data->setMarkerLineNumber(data->lineNumber.toInt());
|
||||
data->setMarkerLineNumber(data->lineNumber);
|
||||
updateNeeded = true;
|
||||
}
|
||||
}
|
||||
@@ -608,7 +608,7 @@ static BreakpointData *findBreakPointByFileName(BreakHandler *handler,
|
||||
const int count = handler->size();
|
||||
for (int b = 0; b < count; b++) {
|
||||
BreakpointData *data = handler->at(b);
|
||||
if (lineNumber == data->lineNumber.toInt() && fileName == data->fileName)
|
||||
if (lineNumber == data->lineNumber && fileName == data->fileName)
|
||||
return data;
|
||||
}
|
||||
return 0;
|
||||
@@ -649,7 +649,7 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction)
|
||||
|
||||
// We just run into a breakpoint.
|
||||
//SDEBUG("RESOLVING BREAKPOINT AT " << fileName << lineNumber);
|
||||
data->bpLineNumber = QByteArray::number(lineNumber);
|
||||
data->bpLineNumber = lineNumber;
|
||||
data->bpFileName = fileName;
|
||||
data->bpFuncName = functionName;
|
||||
data->setMarkerLineNumber(lineNumber);
|
||||
|
||||
@@ -769,13 +769,11 @@ bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int ro
|
||||
case RequestToggleWatchRole: {
|
||||
BreakHandler *handler = engine()->breakHandler();
|
||||
const quint64 address = value.toULongLong();
|
||||
const QByteArray addressBA =
|
||||
QByteArray("0x") + QByteArray::number(address, 16);
|
||||
const int index = handler->findWatchPointIndexByAddress(addressBA);
|
||||
const int index = handler->findWatchPointIndexByAddress(address);
|
||||
if (index == -1) {
|
||||
BreakpointData *data = new BreakpointData;
|
||||
data->type = BreakpointData::WatchpointType;
|
||||
data->address = addressBA;
|
||||
data->address = address;
|
||||
handler->appendBreakpoint(data);
|
||||
} else {
|
||||
handler->removeBreakpoint(index);
|
||||
|
||||
Reference in New Issue
Block a user