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
|
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()
|
void CdbEngine::attemptBreakpointSynchronization()
|
||||||
|
@@ -94,18 +94,49 @@ static inline QString cdbBreakPointFileName(const BreakpointParameters &bp,
|
|||||||
return cdbSourcePathMapping(QDir::toNativeSeparators(bp.fileName), sourcePathMapping, SourceToDebugger);
|
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,
|
QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
|
||||||
const QList<QPair<QString, QString> > &sourcePathMapping,
|
const QList<QPair<QString, QString> > &sourcePathMapping,
|
||||||
BreakpointId id /* = BreakpointId(-1) */,
|
BreakpointId id /* = BreakpointId(-1) */,
|
||||||
bool oneshot)
|
bool oneshot)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
const BreakpointParameters bp = fixWinMSVCBreakpoint(bpIn);
|
const BreakpointParameters bp = fixWinMSVCBreakpoint(bpIn);
|
||||||
#else
|
|
||||||
const BreakpointParameters bp = bpIn;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QByteArray rc;
|
QByteArray rc;
|
||||||
ByteArrayInputStream str(rc);
|
ByteArrayInputStream str(rc);
|
||||||
|
|
||||||
@@ -121,6 +152,10 @@ QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
|
|||||||
if (oneshot)
|
if (oneshot)
|
||||||
str << "/1 ";
|
str << "/1 ";
|
||||||
switch (bp.type) {
|
switch (bp.type) {
|
||||||
|
case BreakpointAtFork:
|
||||||
|
case BreakpointAtExec:
|
||||||
|
case BreakpointAtVFork:
|
||||||
|
case BreakpointAtSysCall:
|
||||||
case UnknownType:
|
case UnknownType:
|
||||||
case BreakpointAtCatch:
|
case BreakpointAtCatch:
|
||||||
case BreakpointAtThrow:
|
case BreakpointAtThrow:
|
||||||
@@ -141,7 +176,7 @@ QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
|
|||||||
str << bp.module << '!';
|
str << bp.module << '!';
|
||||||
str << cdbBreakPointFileName(bp, sourcePathMapping) << ':' << bp.lineNumber << '`';
|
str << cdbBreakPointFileName(bp, sourcePathMapping) << ':' << bp.lineNumber << '`';
|
||||||
break;
|
break;
|
||||||
case Watchpoint:
|
case Watchpoint: // Read/write 1 byte
|
||||||
str << "rw 1 " << hex << hexPrefixOn << bp.address << hexPrefixOff << dec;
|
str << "rw 1 " << hex << hexPrefixOn << bp.address << hexPrefixOff << dec;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -389,29 +389,5 @@ bool isFatalWinException(long code)
|
|||||||
return true;
|
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 Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
@@ -42,8 +42,6 @@ QT_FORWARD_DECLARE_CLASS(QTextStream)
|
|||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class BreakpointParameters;
|
|
||||||
|
|
||||||
struct ProcData; // debuggerdialogs, used by the process listing dialogs
|
struct ProcData; // debuggerdialogs, used by the process listing dialogs
|
||||||
|
|
||||||
QList<ProcData> winProcessList();
|
QList<ProcData> winProcessList();
|
||||||
@@ -92,13 +90,6 @@ bool isFatalWinException(long code);
|
|||||||
// Check for EXCEPTION_BREAKPOINT, EXCEPTION_SINGLE_STEP
|
// Check for EXCEPTION_BREAKPOINT, EXCEPTION_SINGLE_STEP
|
||||||
bool isDebuggerWinException(long code);
|
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 Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user