forked from qt-creator/qt-creator
CDB: Only use codemodel breakpoint correction for old cdbs.
Since version 6.2 cdb supports setting breakpoints on non codelines and automatically set it to the next available line. Change-Id: I27facf4f2463bad76a20ef0abb5a5412471c296f Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
@@ -136,3 +136,14 @@ std::string moduleNameByOffset(CIDebugSymbols *symbols, ULONG64 offset)
|
||||
return std::string();
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
std::string sourceFileNameByOffset(CIDebugSymbols *symbols, ULONG64 offset, PULONG lineNumber)
|
||||
{
|
||||
enum { BufSize = 512 };
|
||||
char buf[BufSize];
|
||||
buf[0] = '\0';
|
||||
HRESULT hr = symbols->GetLineByOffset(offset, lineNumber, buf, BufSize, NULL, NULL);
|
||||
if (FAILED(hr))
|
||||
return std::string();
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ ULONG currentThreadId(CIDebugClient *client);
|
||||
ULONG currentProcessId(IDebugSystemObjects *sysObjects);
|
||||
ULONG currentProcessId(CIDebugClient *client);
|
||||
std::string moduleNameByOffset(CIDebugSymbols *symbols, ULONG64 offset);
|
||||
std::string sourceFileNameByOffset(CIDebugSymbols *symbols, ULONG64 offset, PULONG lineNumber);
|
||||
|
||||
#ifdef QTC_TRACE
|
||||
# define QTC_TRACE_IN dprintf(">%s\n", __FUNCTION__);
|
||||
|
||||
@@ -742,6 +742,14 @@ static bool gdbmiFormatBreakpoint(std::ostream &str,
|
||||
const std::string module = moduleNameByOffset(symbols, memoryRange.first);
|
||||
if (!module.empty())
|
||||
str << ",module=\"" << module << '"';
|
||||
ULONG lineNumber = 0;
|
||||
std::string srcFile = sourceFileNameByOffset(symbols, memoryRange.first, &lineNumber);
|
||||
if (!srcFile.empty()) {
|
||||
// replace all backslashes with slashes
|
||||
replace(srcFile, '\\', '/');
|
||||
str << ",srcfile=\"" << srcFile << '"';
|
||||
str << ",srcline=\"" << lineNumber << '"';
|
||||
}
|
||||
} // symbols
|
||||
// Report the memory of watchpoints for comparing bitfields
|
||||
if (dataSpaces && memoryRange.second > 0) {
|
||||
@@ -755,7 +763,7 @@ static bool gdbmiFormatBreakpoint(std::ostream &str,
|
||||
// Expression
|
||||
if (verbose > 1) {
|
||||
char buf[BufSize];
|
||||
if (SUCCEEDED(bp->GetOffsetExpression(buf, BUFSIZ, 0)))
|
||||
if (SUCCEEDED(bp->GetOffsetExpression(buf, BufSize, 0)))
|
||||
str << ",expression=\"" << gdbmiStringFormat(buf) << '"';
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -102,6 +102,14 @@ void replace(std::wstring &s, wchar_t before, wchar_t after)
|
||||
s[i] = after;
|
||||
}
|
||||
|
||||
void replace(std::string &s, char before, char after)
|
||||
{
|
||||
const std::string::size_type size = s.size();
|
||||
for (std::string::size_type i = 0; i < size; ++i)
|
||||
if (s.at(i) == before)
|
||||
s[i] = after;
|
||||
}
|
||||
|
||||
bool endsWith(const std::string &haystack, const char *needle)
|
||||
{
|
||||
const size_t needleLen = strlen(needle);
|
||||
|
||||
@@ -134,6 +134,7 @@ bool integerFromWString(const std::wstring &s, Integer *v)
|
||||
}
|
||||
|
||||
void replace(std::wstring &s, wchar_t before, wchar_t after);
|
||||
void replace(std::string &s, char before, char after);
|
||||
|
||||
// Stream a string onto a char stream doing backslash & octal escaping
|
||||
// suitable for GDBMI usable as 'str << gdbmiStringFormat(wstring)'
|
||||
|
||||
@@ -375,6 +375,7 @@ void CdbEngine::init()
|
||||
m_sourceStepInto = false;
|
||||
m_watchPointX = m_watchPointY = 0;
|
||||
m_ignoreCdbOutput = false;
|
||||
m_autoBreakPointCorrection = false;
|
||||
m_watchInameToName.clear();
|
||||
m_wow64State = wow64Uninitialized;
|
||||
|
||||
@@ -733,6 +734,7 @@ bool CdbEngine::launchCDB(const DebuggerStartParameters &sp, QString *errorMessa
|
||||
showMessage(msg, LogMisc);
|
||||
|
||||
m_outputBuffer.clear();
|
||||
m_autoBreakPointCorrection = false;
|
||||
const QStringList environment = sp.environment.size() == 0 ?
|
||||
QProcessEnvironment::systemEnvironment().toStringList() :
|
||||
sp.environment.toStringList();
|
||||
@@ -2609,7 +2611,24 @@ void CdbEngine::parseOutputLine(QByteArray line)
|
||||
qDebug("### Gathering output for '%s' token %d", currentCommand->command.constData(), currentCommand->token);
|
||||
return;
|
||||
}
|
||||
|
||||
const char versionString[] = "Microsoft (R) Windows Debugger Version";
|
||||
if (line.startsWith(versionString)) {
|
||||
QRegExp versionRegEx(QLatin1String("(\\d+)\\.(\\d+)\\.\\d+\\.\\d+"));
|
||||
if (versionRegEx.indexIn(QLatin1String(line)) > -1) {
|
||||
bool ok = true;
|
||||
int major = versionRegEx.cap(1).toInt(&ok);
|
||||
int minor = versionRegEx.cap(2).toInt(&ok);
|
||||
if (ok) {
|
||||
// for some incomprehensible reasons Microsoft cdb version 6.2 is newer than 6.12
|
||||
m_autoBreakPointCorrection = major > 6 || (major == 6 && minor >= 2 && minor < 10);
|
||||
showMessage(QString::fromLocal8Bit(line), LogMisc);
|
||||
showMessage(QString::fromLatin1("Using ")
|
||||
+ m_autoBreakPointCorrection ? QLatin1String("CDB ")
|
||||
: QLatin1String("codemodel ")
|
||||
+ QString::fromLatin1("based breakpoint correction."), LogMisc);
|
||||
}
|
||||
}
|
||||
}
|
||||
showMessage(QString::fromLocal8Bit(line), LogMisc);
|
||||
}
|
||||
|
||||
@@ -2814,8 +2833,9 @@ void CdbEngine::attemptBreakpointSynchronization()
|
||||
}
|
||||
switch (handler->state(id)) {
|
||||
case BreakpointInsertRequested:
|
||||
if (parameters.type == BreakpointByFileAndLine
|
||||
&& debuggerCore()->boolSetting(CdbBreakPointCorrection)) {
|
||||
if (!m_autoBreakPointCorrection
|
||||
&& parameters.type == BreakpointByFileAndLine
|
||||
&& debuggerCore()->boolSetting(CdbBreakPointCorrection)) {
|
||||
if (lineCorrection.isNull())
|
||||
lineCorrection.reset(new BreakpointCorrectionContext(debuggerCore()->cppCodeModelSnapshot(),
|
||||
CppTools::CppModelManagerInterface::instance()->workingCopy()));
|
||||
@@ -3210,6 +3230,8 @@ void CdbEngine::handleBreakPoints(const GdbMi &value)
|
||||
currentResponse.module = reportedResponse.module;
|
||||
currentResponse.pending = reportedResponse.pending;
|
||||
currentResponse.enabled = reportedResponse.enabled;
|
||||
currentResponse.fileName = reportedResponse.fileName;
|
||||
currentResponse.lineNumber = reportedResponse.lineNumber;
|
||||
formatCdbBreakPointResponse(mid, currentResponse, str);
|
||||
if (debugBreakpoints)
|
||||
qDebug(" Setting for %d: %s\n", currentResponse.id.majorPart(),
|
||||
|
||||
@@ -286,6 +286,7 @@ private:
|
||||
int m_watchPointX;
|
||||
int m_watchPointY;
|
||||
PendingBreakPointMap m_pendingBreakpointMap;
|
||||
bool m_autoBreakPointCorrection;
|
||||
QHash<QString, QString> m_fileNameModuleHash;
|
||||
QMultiHash<QString, quint64> m_symbolAddressCache;
|
||||
QHash<QByteArray, QString> m_watchInameToName;
|
||||
|
||||
@@ -300,6 +300,13 @@ void parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r,
|
||||
const GdbMi moduleG = gdbmi["module"];
|
||||
if (moduleG.isValid())
|
||||
r->module = QString::fromLocal8Bit(moduleG.data());
|
||||
const GdbMi sourceFileName = gdbmi["srcfile"];
|
||||
if (sourceFileName.isValid()) {
|
||||
r->fileName = QString::fromLocal8Bit(sourceFileName.data());
|
||||
const GdbMi lineNumber = gdbmi["srcline"];
|
||||
if (lineNumber.isValid())
|
||||
r->lineNumber = lineNumber.data().toULongLong(0, 0);
|
||||
}
|
||||
if (expression) {
|
||||
const GdbMi expressionG = gdbmi["expression"];
|
||||
if (expressionG.isValid())
|
||||
|
||||
Reference in New Issue
Block a user