Debugger: New breakpoint types in CDB.

Emulate exec() by breaking on CreateProcessW().
This commit is contained in:
Friedemann Kleint
2011-03-07 11:02:07 +01:00
parent c9c10aa41f
commit fcdbdcaee0
4 changed files with 62 additions and 41 deletions

View File

@@ -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()

View File

@@ -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;
} }

View File

@@ -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

View File

@@ -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