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