forked from qt-creator/qt-creator
Debugger: Minimize stalling at break-points insertion in UVSC engine
Sometime the UVSC_DBG_CREATE_BP function stalls within 10 seconds and then returns with the timeout error. But this problem can be avoided by creating and then removing the fake breakpoint before creating the original breakpoint. In this case, we need to remove the line number from the expression of this fake breakpoint. Of course, it does not help when the breakpoint cannot be created with the specified expression. In this case the UVSC_DBG_CREATE_BP function will stall anyway within 10 seconds. Change-Id: Ie8d39c545683d6bb3e29e5bb7c4ac0fd1e34222a Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -799,6 +799,10 @@ bool UvscClient::createBreakpoint(const QString &exp, quint32 &tickMark, quint64
|
||||
if (!checkConnection())
|
||||
return false;
|
||||
|
||||
// Magic workaround to prevent the stalling.
|
||||
if (!controlHiddenBreakpoint(exp))
|
||||
return false;
|
||||
|
||||
QByteArray bkparm = UvscUtils::encodeBreakPoint(BRKTYPE_EXEC, exp);
|
||||
QByteArray bkrsp(kMaximumBreakpointResponseSize, 0);
|
||||
qint32 bkrspLength = bkrsp.size();
|
||||
@@ -881,6 +885,54 @@ bool UvscClient::disableBreakpoint(quint32 tickMark)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UvscClient::controlHiddenBreakpoint(const QString &exp)
|
||||
{
|
||||
if (!checkConnection())
|
||||
return false;
|
||||
|
||||
// It is a magic workaround to prevent the UVSC bug when the break-point
|
||||
// creation may stall. A problem is that sometime the UVSC_DBG_CREATE_BP
|
||||
// function blocks and returns then with the timeout error when the original
|
||||
// break-point contains the full expression including the line number.
|
||||
//
|
||||
// It can be avoided with helps of creation and then deletion of the
|
||||
// 'fake hidden' break-point with the same expression excluding the line
|
||||
// number, before creation of an original break-point.
|
||||
|
||||
const int slashIndex = exp.lastIndexOf('\\');
|
||||
if (slashIndex == -1 || (slashIndex + 1) == exp.size())
|
||||
return true;
|
||||
|
||||
QByteArray bkrsp(kMaximumBreakpointResponseSize, 0);
|
||||
|
||||
const QString hiddenExp = exp.mid(0, slashIndex);
|
||||
QByteArray bkparm = UvscUtils::encodeBreakPoint(BRKTYPE_EXEC, hiddenExp);
|
||||
qint32 bkrspLength = bkrsp.size();
|
||||
UVSC_STATUS st = ::UVSC_DBG_CREATE_BP(m_descriptor,
|
||||
reinterpret_cast<BKPARM *>(bkparm.data()),
|
||||
bkparm.size(),
|
||||
reinterpret_cast<BKRSP *>(bkrsp.data()),
|
||||
&bkrspLength);
|
||||
if (st != UVSC_STATUS_SUCCESS) {
|
||||
setError(RuntimeError);
|
||||
return false;
|
||||
}
|
||||
|
||||
BKCHG bkchg = {};
|
||||
bkchg.type = CHG_KILLBP;
|
||||
bkchg.tickMark = reinterpret_cast<const BKRSP *>(bkrsp.constData())->tickMark;
|
||||
bkrspLength = bkrsp.size();
|
||||
st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg),
|
||||
reinterpret_cast<BKRSP *>(bkrsp.data()),
|
||||
&bkrspLength);
|
||||
if (st != UVSC_STATUS_SUCCESS) {
|
||||
setError(RuntimeError);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UvscClient::calculateExpression(const QString &exp, QByteArray &)
|
||||
{
|
||||
if (!checkConnection())
|
||||
|
@@ -141,6 +141,8 @@ private:
|
||||
void updateLocation(const QByteArray &bpreason);
|
||||
bool addressToFileLine(quint64 address, QString &fileName, QString &function, quint32 &line);
|
||||
|
||||
bool controlHiddenBreakpoint(const QString &exp);
|
||||
|
||||
qint32 m_descriptor = -1;
|
||||
quint64 m_exitAddress = 0;
|
||||
UvscError m_error = NoError;
|
||||
|
Reference in New Issue
Block a user