Commit 84790f9a authored by David Schulz's avatar David Schulz
Browse files

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: default avatarFriedemann Kleint <Friedemann.Kleint@digia.com>
parent fe238305
......@@ -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())
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment