forked from qt-creator/qt-creator
Debugger: New breakpoint types in CDB.
Emulate exec() by breaking on CreateProcessW().
This commit is contained in:
@@ -2264,7 +2264,26 @@ bool CdbEngine::stateAcceptsBreakpointChanges() const
|
||||
|
||||
bool CdbEngine::acceptsBreakpoint(BreakpointId id) const
|
||||
{
|
||||
return DebuggerEngine::isCppBreakpoint(breakHandler()->breakpointData(id));
|
||||
const BreakpointParameters &data = breakHandler()->breakpointData(id);
|
||||
if (!DebuggerEngine::isCppBreakpoint(data))
|
||||
return false;
|
||||
switch (data.type) {
|
||||
case UnknownType:
|
||||
case BreakpointAtFork:
|
||||
case BreakpointAtVFork:
|
||||
case BreakpointAtSysCall:
|
||||
return false;
|
||||
case Watchpoint:
|
||||
case BreakpointByFileAndLine:
|
||||
case BreakpointByFunction:
|
||||
case BreakpointByAddress:
|
||||
case BreakpointAtThrow:
|
||||
case BreakpointAtCatch:
|
||||
case BreakpointAtMain:
|
||||
case BreakpointAtExec:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CdbEngine::attemptBreakpointSynchronization()
|
||||
|
@@ -94,18 +94,49 @@ static inline QString cdbBreakPointFileName(const BreakpointParameters &bp,
|
||||
return cdbSourcePathMapping(QDir::toNativeSeparators(bp.fileName), sourcePathMapping, SourceToDebugger);
|
||||
}
|
||||
|
||||
// Convert breakpoint in CDB syntax. (applying source path mappings using native paths).
|
||||
static BreakpointParameters fixWinMSVCBreakpoint(const BreakpointParameters &p)
|
||||
{
|
||||
switch (p.type) {
|
||||
case UnknownType:
|
||||
case BreakpointByFileAndLine:
|
||||
case BreakpointByFunction:
|
||||
case BreakpointByAddress:
|
||||
case BreakpointAtFork:
|
||||
case BreakpointAtVFork:
|
||||
case BreakpointAtSysCall:
|
||||
case Watchpoint:
|
||||
break;
|
||||
case BreakpointAtExec: { // Emulate by breaking on CreateProcessW().
|
||||
BreakpointParameters rc(BreakpointByFunction);
|
||||
rc.module = QLatin1String("kernel32");
|
||||
rc.functionName = QLatin1String("CreateProcessW");
|
||||
return rc;
|
||||
}
|
||||
case BreakpointAtThrow: {
|
||||
BreakpointParameters rc(BreakpointByFunction);
|
||||
rc.functionName = QLatin1String("CxxThrowException"); // MSVC runtime. Potentially ambiguous.
|
||||
return rc;
|
||||
}
|
||||
case BreakpointAtCatch: {
|
||||
BreakpointParameters rc(BreakpointByFunction);
|
||||
rc.functionName = QLatin1String("__CxxCallCatchBlock"); // MSVC runtime. Potentially ambiguous.
|
||||
return rc;
|
||||
}
|
||||
case BreakpointAtMain: {
|
||||
BreakpointParameters rc(BreakpointByFunction);
|
||||
rc.functionName = QLatin1String("main");
|
||||
return rc;
|
||||
}
|
||||
} // switch
|
||||
return p;
|
||||
}
|
||||
|
||||
QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
|
||||
const QList<QPair<QString, QString> > &sourcePathMapping,
|
||||
BreakpointId id /* = BreakpointId(-1) */,
|
||||
bool oneshot)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
const BreakpointParameters bp = fixWinMSVCBreakpoint(bpIn);
|
||||
#else
|
||||
const BreakpointParameters bp = bpIn;
|
||||
#endif
|
||||
|
||||
QByteArray rc;
|
||||
ByteArrayInputStream str(rc);
|
||||
|
||||
@@ -121,6 +152,10 @@ QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
|
||||
if (oneshot)
|
||||
str << "/1 ";
|
||||
switch (bp.type) {
|
||||
case BreakpointAtFork:
|
||||
case BreakpointAtExec:
|
||||
case BreakpointAtVFork:
|
||||
case BreakpointAtSysCall:
|
||||
case UnknownType:
|
||||
case BreakpointAtCatch:
|
||||
case BreakpointAtThrow:
|
||||
@@ -141,7 +176,7 @@ QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
|
||||
str << bp.module << '!';
|
||||
str << cdbBreakPointFileName(bp, sourcePathMapping) << ':' << bp.lineNumber << '`';
|
||||
break;
|
||||
case Watchpoint:
|
||||
case Watchpoint: // Read/write 1 byte
|
||||
str << "rw 1 " << hex << hexPrefixOn << bp.address << hexPrefixOff << dec;
|
||||
break;
|
||||
}
|
||||
|
@@ -389,29 +389,5 @@ bool isFatalWinException(long code)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Special function names in MSVC runtime
|
||||
const char *winMSVCThrowFunction = "CxxThrowException";
|
||||
const char *winMSVCCatchFunction = "__CxxCallCatchBlock";
|
||||
|
||||
BreakpointParameters fixWinMSVCBreakpoint(const BreakpointParameters &p)
|
||||
{
|
||||
if (p.type == BreakpointAtThrow) {
|
||||
BreakpointParameters rc(BreakpointByFunction);
|
||||
rc.functionName = QLatin1String(winMSVCThrowFunction);
|
||||
return rc;
|
||||
}
|
||||
if (p.type == BreakpointAtCatch) {
|
||||
BreakpointParameters rc(BreakpointByFunction);
|
||||
rc.functionName = QLatin1String(winMSVCCatchFunction);
|
||||
return rc;
|
||||
}
|
||||
if (p.type == BreakpointAtMain) {
|
||||
BreakpointParameters rc(BreakpointByFunction);
|
||||
rc.functionName = QLatin1String("main");
|
||||
return rc;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
@@ -42,8 +42,6 @@ QT_FORWARD_DECLARE_CLASS(QTextStream)
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class BreakpointParameters;
|
||||
|
||||
struct ProcData; // debuggerdialogs, used by the process listing dialogs
|
||||
|
||||
QList<ProcData> winProcessList();
|
||||
@@ -92,13 +90,6 @@ bool isFatalWinException(long code);
|
||||
// Check for EXCEPTION_BREAKPOINT, EXCEPTION_SINGLE_STEP
|
||||
bool isDebuggerWinException(long code);
|
||||
|
||||
// fix up breakpoints (catch/throw, etc).
|
||||
BreakpointParameters fixWinMSVCBreakpoint(const BreakpointParameters &p);
|
||||
|
||||
// Special function names in MSVC runtime
|
||||
extern const char *winMSVCThrowFunction;
|
||||
extern const char *winMSVCCatchFunction;
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
|
Reference in New Issue
Block a user